Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1680)

Unified Diff: appengine_module/gae_ts_mon/interface.py

Issue 1260293009: make version of ts_mon compatible with appengine (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: take out deleted utils methods Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: appengine_module/gae_ts_mon/interface.py
diff --git a/appengine_module/gae_ts_mon/interface.py b/appengine_module/gae_ts_mon/interface.py
new file mode 100644
index 0000000000000000000000000000000000000000..e9590b7f05ff2ef16ea191f843a8461472852fa8
--- /dev/null
+++ b/appengine_module/gae_ts_mon/interface.py
@@ -0,0 +1,124 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Classes representing the monitoring interface for tasks or devices.
+
+Usage:
+ # symlink appengine/modules/gae_ts_mon into the top level directory
+ # of your appengine app
+
+ import gae_ts_mon
+
+ # Sets up default target
+ gae_ts_mon.initialize(job_name='job', instance='12d2e1',
Sergey Berezin 2015/08/18 00:40:38 nit: is the instance value supposed to be a consta
jshu 2015/08/18 01:15:55 should be a real instance id, which is an int. fix
Sergey Berezin 2015/08/18 17:31:38 Two comments then: 1. In README, let's use <insta
jshu 2015/08/20 00:23:34 fixed
+ service_name='service', endpoint='endpoint')
+
+ # Will use the default Target set up with initialize
+ count_metric = gae_ts_mon.CounterMetric('my/metric/name', fields={})
+ count_metric.set(0)
+ for x in range(100):
+ count_metric.increment()
+
+ # Use a custom Target:
+ t = ts_mon.TaskTarget('service', 'job', 'region', 'host')
+ g_metric = ts_mon.GaugeMetric('/my/metric/name2', fields={'asdf': 'qwer'},
+ target=t)
Sergey Berezin 2015/08/18 00:40:37 nit: indentation.
+ g_metric.set(5)
+
+ # Flush (send metrics to monarch)
+ gae_ts_mon.flush()
Sergey Berezin 2015/08/18 00:40:38 nit: I believe this should be called automatically
jshu 2015/08/18 01:15:55 called from a cron job. leaving that in to give th
Sergey Berezin 2015/08/18 17:31:38 I'd still mention what you said in the comment; ot
+
+"""
+
+import logging
+import os
+import random
+import threading
+import time
+
+from proto import metrics_pb2
+
+from common import errors
+
+# The maximum number of MetricsData messages to include in each HTTP request.
+# MetricsCollections larger than this will be split into multiple requests.
+METRICS_DATA_LENGTH_LIMIT = 5000
Sergey Berezin 2015/08/18 00:40:38 nit: we are reducing this to 1000 - see https://co
+
+
+class State(object):
+ """Package-level state is stored here so that it is easily accessible.
+
+ Configuration is kept in this one object at the global level so that all
+ libraries in use by the same tool or service can all take advantage of the
+ same configuration.
+ """
+
+ def __init__(self):
+ # The Monitor object that will be used to send all metrics.
+ self.global_monitor = None
+ # The Target object that will be paired with all metrics that don't supply
+ # their own.
+ self.default_target = None
+ # The flush mode being used to control when metrics are pushed.
+ self.flush_mode = None
+ # All metrics created by this application.
+ self.metrics = set()
+
+state = State()
+
+
+def send(metric):
+ """Send a single metric to the monitoring api.
+
+ This is called automatically by Metric.set - you don't need to call it
+ manually.
+ """
+ if state.flush_mode != 'all':
+ return
+
+ if not state.global_monitor:
+ raise errors.MonitoringNoConfiguredMonitorError(metric._name)
+
+ proto = metrics_pb2.MetricsCollection()
+ metric.serialize_to(proto, default_target=state.default_target)
+ state.global_monitor.send(proto)
+
+
+def flush():
+ """Send all metrics that are registered in the application."""
+ if not state.global_monitor:
+ raise errors.MonitoringNoConfiguredMonitorError(None)
+
+ proto = metrics_pb2.MetricsCollection()
+
+ def loop_action(proto):
+ if len(proto.data) >= METRICS_DATA_LENGTH_LIMIT:
+ state.global_monitor.send(proto)
+ del proto.data[:]
+
+ for metric in state.metrics:
+ metric.serialize_to(proto, default_target=state.default_target,
+ loop_action=loop_action)
+
+ state.global_monitor.send(proto)
+
+
+def register(metric):
+ """Adds the metric to the list of metrics sent by flush().
+
+ This is called automatically by Metric's constructor.
+ """
+ # If someone is registering the same metric object twice, that's okay, but
+ # registering two different metric objects with the same metric name is not.
+ if metric in state.metrics:
+ return
+ if any([metric._name == m._name for m in state.metrics]):
+ raise errors.MonitoringDuplicateRegistrationError(metric._name)
+
+ state.metrics.add(metric)
+
+
+def unregister(metric):
+ """Removes the metric from the list of metrics sent by flush()."""
+ state.metrics.remove(metric)

Powered by Google App Engine
This is Rietveld 408576698