OLD | NEW |
(Empty) | |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 """Classes representing the monitoring interface for tasks or devices. |
| 6 |
| 7 Usage: |
| 8 # symlink appengine/modules/gae_ts_mon into the top level directory |
| 9 # of your appengine app |
| 10 |
| 11 import gae_ts_mon |
| 12 from google.appengine.api import modules |
| 13 |
| 14 # Sets up default target |
| 15 instance_id = hash(modules.get_current_instance_id()) % 10 |
| 16 gae_ts_mon.initialize(job_name='job', instance=instance_id, |
| 17 service_name='service', endpoint='endpoint') |
| 18 |
| 19 # Will use the default Target set up with initialize |
| 20 count_metric = gae_ts_mon.CounterMetric('my/metric/name', fields={}) |
| 21 count_metric.set(0) |
| 22 for x in range(100): |
| 23 count_metric.increment() |
| 24 |
| 25 # Use a custom Target: |
| 26 t = ts_mon.TaskTarget('service', 'job', 'region', 'host') |
| 27 g_metric = ts_mon.GaugeMetric('/my/metric/name2', |
| 28 fields={'key': 'value'}, |
| 29 target=t) |
| 30 g_metric.set(5) |
| 31 |
| 32 # Flush (sends metrics to monarch, already done automatically every 5m) |
| 33 gae_ts_mon.flush() |
| 34 |
| 35 """ |
| 36 |
| 37 import logging |
| 38 import os |
| 39 import random |
| 40 import time |
| 41 |
| 42 from monacq.proto import metrics_pb2 |
| 43 |
| 44 from common import errors |
| 45 |
| 46 # The maximum number of MetricsData messages to include in each HTTP request. |
| 47 # MetricsCollections larger than this will be split into multiple requests. |
| 48 METRICS_DATA_LENGTH_LIMIT = 1000 |
| 49 |
| 50 |
| 51 class State(object): |
| 52 """Package-level state is stored here so that it is easily accessible. |
| 53 |
| 54 Configuration is kept in this one object at the global level so that all |
| 55 libraries in use by the same tool or service can all take advantage of the |
| 56 same configuration. |
| 57 """ |
| 58 |
| 59 def __init__(self): |
| 60 # The Monitor object that will be used to send all metrics. |
| 61 self.global_monitor = None |
| 62 # The Target object that will be paired with all metrics that don't supply |
| 63 # their own. |
| 64 self.default_target = None |
| 65 # The flush mode being used to control when metrics are pushed. |
| 66 self.flush_mode = None |
| 67 # All metrics created by this application. |
| 68 self.metrics = set() |
| 69 |
| 70 state = State() |
| 71 |
| 72 |
| 73 def send(metric): |
| 74 """Send a single metric to the monitoring api. |
| 75 |
| 76 This is called automatically by Metric.set - you don't need to call it |
| 77 manually. |
| 78 """ |
| 79 if state.flush_mode != 'all': |
| 80 return |
| 81 |
| 82 if not state.global_monitor: |
| 83 raise errors.MonitoringNoConfiguredMonitorError(metric._name) |
| 84 |
| 85 proto = metrics_pb2.MetricsCollection() |
| 86 metric.serialize_to(proto, default_target=state.default_target) |
| 87 state.global_monitor.send(proto) |
| 88 |
| 89 |
| 90 def flush(): |
| 91 """Send all metrics that are registered in the application.""" |
| 92 if not state.global_monitor: |
| 93 raise errors.MonitoringNoConfiguredMonitorError(None) |
| 94 |
| 95 proto = metrics_pb2.MetricsCollection() |
| 96 |
| 97 def loop_action(proto): |
| 98 if len(proto.data) >= METRICS_DATA_LENGTH_LIMIT: |
| 99 state.global_monitor.send(proto) |
| 100 del proto.data[:] |
| 101 |
| 102 for metric in state.metrics: |
| 103 metric.serialize_to(proto, default_target=state.default_target, |
| 104 loop_action=loop_action) |
| 105 |
| 106 state.global_monitor.send(proto) |
| 107 |
| 108 |
| 109 def register(metric): |
| 110 """Adds the metric to the list of metrics sent by flush(). |
| 111 |
| 112 This is called automatically by Metric's constructor. |
| 113 """ |
| 114 # If someone is registering the same metric object twice, that's okay, but |
| 115 # registering two different metric objects with the same metric name is not. |
| 116 for m in state.metrics: |
| 117 if metric == m: |
| 118 state.metrics.remove(m) |
| 119 state.metrics.add(metric) |
| 120 return |
| 121 if any([metric._name == m._name for m in state.metrics]): |
| 122 raise errors.MonitoringDuplicateRegistrationError(metric._name) |
| 123 |
| 124 state.metrics.add(metric) |
| 125 |
| 126 |
| 127 def unregister(metric): |
| 128 """Removes the metric from the list of metrics sent by flush().""" |
| 129 state.metrics.remove(metric) |
OLD | NEW |