| 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 json | 9 import json |
| 10 import logging | 10 import logging |
| 11 import socket |
| 11 import traceback | 12 import traceback |
| 12 | 13 |
| 13 from googleapiclient import discovery | 14 from googleapiclient import discovery |
| 14 from googleapiclient import errors | 15 from googleapiclient import errors |
| 15 from oauth2client import gce | 16 from oauth2client import gce |
| 16 from oauth2client.client import GoogleCredentials | 17 from oauth2client.client import GoogleCredentials |
| 17 from oauth2client.file import Storage | 18 from oauth2client.file import Storage |
| 18 import httplib2 | 19 import httplib2 |
| 19 | 20 |
| 20 from infra_libs import httplib2_utils | 21 from infra_libs import httplib2_utils |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 ], | 156 ], |
| 156 } | 157 } |
| 157 # Occasionally, client fails to receive a proper internal JSON | 158 # Occasionally, client fails to receive a proper internal JSON |
| 158 # from the server and raises ValueError trying to parse it. Other | 159 # from the server and raises ValueError trying to parse it. Other |
| 159 # times we may fail with a network error. This is not fatal, we'll | 160 # times we may fail with a network error. This is not fatal, we'll |
| 160 # resend metrics next time. | 161 # resend metrics next time. |
| 161 try: | 162 try: |
| 162 self._api.projects().topics().publish( | 163 self._api.projects().topics().publish( |
| 163 topic=self._topic, | 164 topic=self._topic, |
| 164 body=body).execute(num_retries=5) | 165 body=body).execute(num_retries=5) |
| 165 except (ValueError, errors.Error): | 166 except (ValueError, errors.Error, |
| 167 socket.timeout, socket.error, socket.herror, socket.gaierror, |
| 168 httplib2.HttpLib2Error): |
| 166 # Log a warning, not error, to avoid false alarms in AppEngine apps. | 169 # Log a warning, not error, to avoid false alarms in AppEngine apps. |
| 167 logging.warning('PubSubMonitor.send failed:\n%s', | 170 logging.warning('PubSubMonitor.send failed:\n%s', |
| 168 traceback.format_exc()) | 171 traceback.format_exc()) |
| 169 | 172 |
| 170 | 173 |
| 171 class DebugMonitor(Monitor): | 174 class DebugMonitor(Monitor): |
| 172 """Class which writes metrics to logs or a local file for debugging.""" | 175 """Class which writes metrics to logs or a local file for debugging.""" |
| 173 def __init__(self, filepath=None): | 176 def __init__(self, filepath=None): |
| 174 if filepath is None: | 177 if filepath is None: |
| 175 self._fh = None | 178 self._fh = None |
| 176 else: | 179 else: |
| 177 self._fh = open(filepath, 'a') | 180 self._fh = open(filepath, 'a') |
| 178 | 181 |
| 179 def send(self, metric_pb): | 182 def send(self, metric_pb): |
| 180 text = str(self._wrap_proto(metric_pb)) | 183 text = str(self._wrap_proto(metric_pb)) |
| 181 logging.info('Flushing monitoring metrics:\n%s', text) | 184 logging.info('Flushing monitoring metrics:\n%s', text) |
| 182 if self._fh is not None: | 185 if self._fh is not None: |
| 183 self._fh.write(text + '\n\n') | 186 self._fh.write(text + '\n\n') |
| 184 self._fh.flush() | 187 self._fh.flush() |
| 185 | 188 |
| 186 | 189 |
| 187 class NullMonitor(Monitor): | 190 class NullMonitor(Monitor): |
| 188 """Class that doesn't send metrics anywhere.""" | 191 """Class that doesn't send metrics anywhere.""" |
| 189 def send(self, metric_pb): | 192 def send(self, metric_pb): |
| 190 pass | 193 pass |
| OLD | NEW |