| OLD | NEW |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """Classes representing the monitoring interface for tasks or devices.""" | 5 """Classes representing the monitoring interface for tasks or devices.""" |
| 6 | 6 |
| 7 | 7 |
| 8 import base64 | 8 import base64 |
| 9 import httplib2 | 9 import httplib2 |
| 10 import json | 10 import json |
| 11 import logging | 11 import logging |
| 12 import socket | 12 import socket |
| 13 import traceback | 13 import traceback |
| 14 | 14 |
| 15 from googleapiclient import discovery | 15 from googleapiclient import discovery |
| 16 from googleapiclient import errors | 16 from googleapiclient import errors |
| 17 from infra_libs import httplib2_utils | 17 from infra_libs import httplib2_utils |
| 18 from infra_libs.ts_mon.common import interface |
| 18 from infra_libs.ts_mon.common import http_metrics | 19 from infra_libs.ts_mon.common import http_metrics |
| 19 from infra_libs.ts_mon.common import pb_to_popo | 20 from infra_libs.ts_mon.common import pb_to_popo |
| 20 from infra_libs.ts_mon.protos import metrics_pb2 | 21 from infra_libs.ts_mon.protos.current import metrics_pb2 |
| 21 from oauth2client import gce | 22 try: # pragma: no cover |
| 23 from oauth2client import gce |
| 24 except ImportError: # pragma: no cover |
| 25 from oauth2client.contrib import gce |
| 22 from oauth2client.client import GoogleCredentials | 26 from oauth2client.client import GoogleCredentials |
| 23 from oauth2client.file import Storage | 27 from oauth2client.file import Storage |
| 24 | 28 |
| 25 # Special string that can be passed through as the credentials path to use the | 29 # Special string that can be passed through as the credentials path to use the |
| 26 # default Appengine or GCE service account. | 30 # default Appengine or GCE service account. |
| 27 APPENGINE_CREDENTIALS = ':appengine' | 31 APPENGINE_CREDENTIALS = ':appengine' |
| 28 GCE_CREDENTIALS = ':gce' | 32 GCE_CREDENTIALS = ':gce' |
| 29 | 33 |
| 30 | 34 |
| 31 class Monitor(object): | 35 class Monitor(object): |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 | 92 |
| 89 def __init__(self, endpoint, credentials_file_path, http=None): | 93 def __init__(self, endpoint, credentials_file_path, http=None): |
| 90 self._endpoint = endpoint | 94 self._endpoint = endpoint |
| 91 credentials = self._load_credentials(credentials_file_path) | 95 credentials = self._load_credentials(credentials_file_path) |
| 92 if http is None: | 96 if http is None: |
| 93 http = httplib2_utils.RetriableHttp( | 97 http = httplib2_utils.RetriableHttp( |
| 94 httplib2_utils.InstrumentedHttp('acq-mon-api')) | 98 httplib2_utils.InstrumentedHttp('acq-mon-api')) |
| 95 self._http = credentials.authorize(http) | 99 self._http = credentials.authorize(http) |
| 96 | 100 |
| 97 def encodeToJson(self, metric_pb): | 101 def encodeToJson(self, metric_pb): |
| 98 return json.dumps({ 'resource': pb_to_popo.convert(metric_pb) }) | 102 if interface.state.use_new_proto: |
| 103 return json.dumps({'payload': pb_to_popo.convert(metric_pb)}) |
| 104 else: |
| 105 return json.dumps({'resource': pb_to_popo.convert(metric_pb)}) |
| 99 | 106 |
| 100 def send(self, metric_pb): | 107 def send(self, metric_pb): |
| 101 body = self.encodeToJson(self._wrap_proto(metric_pb)) | 108 if interface.state.use_new_proto: |
| 109 body = self.encodeToJson(metric_pb) |
| 110 else: |
| 111 body = self.encodeToJson(self._wrap_proto(metric_pb)) |
| 102 | 112 |
| 103 try: | 113 try: |
| 104 resp, content = self._http.request(self._endpoint, method='POST', | 114 resp, content = self._http.request(self._endpoint, method='POST', |
| 105 body=body) | 115 body=body) |
| 106 if resp.status != 200: | 116 if resp.status != 200: |
| 107 logging.warning('HttpsMonitor.send received status %d: %s', resp.status, | 117 logging.warning('HttpsMonitor.send received status %d: %s', resp.status, |
| 108 content) | 118 content) |
| 109 except (ValueError, errors.Error, | 119 except (ValueError, errors.Error, |
| 110 socket.timeout, socket.error, socket.herror, socket.gaierror, | 120 socket.timeout, socket.error, socket.herror, socket.gaierror, |
| 111 httplib2.HttpLib2Error): | 121 httplib2.HttpLib2Error): |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 # Log a warning, not error, to avoid false alarms in AppEngine apps. | 156 # Log a warning, not error, to avoid false alarms in AppEngine apps. |
| 147 logging.warning('PubSubMonitor._initialize failed:\n%s', | 157 logging.warning('PubSubMonitor._initialize failed:\n%s', |
| 148 traceback.format_exc()) | 158 traceback.format_exc()) |
| 149 self._api = None | 159 self._api = None |
| 150 self._update_init_metrics(http_metrics.STATUS_ERROR) | 160 self._update_init_metrics(http_metrics.STATUS_ERROR) |
| 151 return False | 161 return False |
| 152 | 162 |
| 153 self._update_init_metrics(http_metrics.STATUS_OK) | 163 self._update_init_metrics(http_metrics.STATUS_OK) |
| 154 return True | 164 return True |
| 155 | 165 |
| 156 def __init__(self, credsfile, project, topic, use_instrumented_http=True): | 166 def __init__(self, credsfile, project, topic, use_instrumented_http=True, |
| 167 ca_certs=None): |
| 157 """Process monitoring related command line flags and initialize api. | 168 """Process monitoring related command line flags and initialize api. |
| 158 | 169 |
| 159 Args: | 170 Args: |
| 160 credsfile (str): path to the credentials json file | 171 credsfile (str): path to the credentials json file |
| 161 project (str): the name of the Pub/Sub project to publish to. | 172 project (str): the name of the Pub/Sub project to publish to. |
| 162 topic (str): the name of the Pub/Sub topic to publish to. | 173 topic (str): the name of the Pub/Sub topic to publish to. |
| 163 use_instrumented_http (bool): whether to record monitoring metrics for | 174 use_instrumented_http (bool): whether to record monitoring metrics for |
| 164 HTTP requests made to the pubsub API. | 175 HTTP requests made to the pubsub API. |
| 176 ca_certs (str): path to file containing root CA certificates for SSL |
| 177 server certificate validation. If not set, a CA cert |
| 178 file bundled with httplib2 is used. |
| 165 """ | 179 """ |
| 166 # Do not call self._check_initialize() in the constructor. This | 180 # Do not call self._check_initialize() in the constructor. This |
| 167 # class is constructed during app initialization on AppEngine, and | 181 # class is constructed during app initialization on AppEngine, and |
| 168 # network calls are especially flaky during that time. | 182 # network calls are especially flaky during that time. |
| 169 self._api = None | 183 self._api = None |
| 170 self._use_instrumented_http = use_instrumented_http | 184 self._use_instrumented_http = use_instrumented_http |
| 171 if use_instrumented_http: | 185 if use_instrumented_http: |
| 172 self._http = httplib2_utils.InstrumentedHttp( | 186 self._http = httplib2_utils.InstrumentedHttp( |
| 173 'acq-mon-api-pubsub', timeout=self.TIMEOUT) | 187 'acq-mon-api-pubsub', timeout=self.TIMEOUT, ca_certs=ca_certs) |
| 174 else: | 188 else: |
| 175 self._http = httplib2.Http(timeout=self.TIMEOUT) | 189 self._http = httplib2.Http(timeout=self.TIMEOUT, ca_certs=ca_certs) |
| 176 self._credsfile = credsfile | 190 self._credsfile = credsfile |
| 177 self._topic = 'projects/%s/topics/%s' % (project, topic) | 191 self._topic = 'projects/%s/topics/%s' % (project, topic) |
| 178 | 192 |
| 179 def send(self, metric_pb): | 193 def send(self, metric_pb): |
| 180 """Send a metric proto to the monitoring api. | 194 """Send a metric proto to the monitoring api. |
| 181 | 195 |
| 182 Args: | 196 Args: |
| 183 metric_pb (MetricsData or MetricsCollection): the metric protobuf to send | 197 metric_pb (MetricsData or MetricsCollection): the metric protobuf to send |
| 184 """ | 198 """ |
| 185 if not self._check_initialize(): | 199 if not self._check_initialize(): |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 logging.info('Flushing monitoring metrics:\n%s', text) | 234 logging.info('Flushing monitoring metrics:\n%s', text) |
| 221 if self._fh is not None: | 235 if self._fh is not None: |
| 222 self._fh.write(text + '\n\n') | 236 self._fh.write(text + '\n\n') |
| 223 self._fh.flush() | 237 self._fh.flush() |
| 224 | 238 |
| 225 | 239 |
| 226 class NullMonitor(Monitor): | 240 class NullMonitor(Monitor): |
| 227 """Class that doesn't send metrics anywhere.""" | 241 """Class that doesn't send metrics anywhere.""" |
| 228 def send(self, metric_pb): | 242 def send(self, metric_pb): |
| 229 pass | 243 pass |
| OLD | NEW |