[autotest] Add logging of state 'locked' for model_logic

This will help us to determine whether abnormalities in statuses such as
repair failed are actual problems. If a host is locked, we typically
don't care about its status when doing analysis. I looked at rpc_interface.py,
seems like there are two calls modify_hosts and modify_host that call
update_object(host) only after checking for invalid modifications. So I
decided to log the data in rpc_interface.py

BUG=chromium:394451
TEST=On local afe added a host and via frontend locked and unlocked host.
     Verified results in es db.

Change-Id: I0362f64d0c8270dc9373a421944e024ef0175ecd
Reviewed-on: https://chromium-review.googlesource.com/209268
Tested-by: Michael Liang <michaelliang@chromium.org>
Reviewed-by: Dan Shi <dshi@chromium.org>
Commit-Queue: Michael Liang <michaelliang@chromium.org>
diff --git a/frontend/afe/model_logic.py b/frontend/afe/model_logic.py
index 95e4fc8..6453128 100644
--- a/frontend/afe/model_logic.py
+++ b/frontend/afe/model_logic.py
@@ -3,11 +3,13 @@
 """
 
 import re
+import time
 import django.core.exceptions
 from django.db import models as dbmodels, backend, connection
 from django.db.models.sql import query
 import django.db.models.sql.where
 from django.utils import datastructures
+from autotest_lib.client.common_lib.cros.graphite import es_utils
 from autotest_lib.frontend.afe import rdb_model_extensions
 from autotest_lib.frontend.afe import readonly_connection
 
@@ -702,6 +704,21 @@
         obj.save()
         return obj
 
+    def record_state(self, type_str, state, value):
+        """Record metadata in elasticsearch.
+
+        @param type_str: sets the _type field in elasticsearch db.
+        @param state: string representing what state we are recording,
+                      e.g. 'locked'
+        @param value: value of the state, e.g. True
+        """
+        metadata = {
+            'time_recorded': time.time(),
+             state: value,
+            'hostname': self.hostname,
+        }
+        es_utils.ESMetadata().post(type_str=type_str, metadata=metadata)
+
 
     def update_object(self, data={}, **kwargs):
         """\
@@ -713,9 +730,14 @@
         data.update(kwargs)
         data = self.prepare_data_args(data)
         self.convert_human_readable_values(data)
-
         for field_name, value in data.iteritems():
             setattr(self, field_name, value)
+            # Other fields such as label (when updated) are not sent over
+            # the es because it doesn't contribute to putting together host
+            # host history. Locks are important in host history because if
+            # a device is locked then we don't really care what state it is in.
+            if field_name == 'locked':
+                self.record_state('lock_history', 'locked', value)
         self.do_validate()
         self.save()