| 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 individual metrics that can be sent.""" | 5 """Classes representing individual metrics that can be sent.""" |
| 6 | 6 |
| 7 import copy | 7 import copy |
| 8 | 8 |
| 9 from infra_libs.ts_mon.protos import metrics_pb2 | 9 from infra_libs.ts_mon.protos.current import metrics_pb2 |
| 10 from infra_libs.ts_mon.protos.new import metrics_pb2 as new_metrics_pb2 |
| 10 | 11 |
| 11 from infra_libs.ts_mon.common import distribution | 12 from infra_libs.ts_mon.common import distribution |
| 12 from infra_libs.ts_mon.common import errors | 13 from infra_libs.ts_mon.common import errors |
| 13 from infra_libs.ts_mon.common import interface | 14 from infra_libs.ts_mon.common import interface |
| 14 | 15 |
| 15 | 16 |
| 16 MICROSECONDS_PER_SECOND = 1000000 | 17 MICROSECONDS_PER_SECOND = 1000000 |
| 17 | 18 |
| 18 | 19 |
| 19 class Metric(object): | 20 class Metric(object): |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 raise NotImplementedError() | 87 raise NotImplementedError() |
| 87 | 88 |
| 88 def __eq__(self, other): | 89 def __eq__(self, other): |
| 89 return (self.name == other.name and | 90 return (self.name == other.name and |
| 90 self._fields == other._fields and | 91 self._fields == other._fields and |
| 91 type(self) == type(other)) | 92 type(self) == type(other)) |
| 92 | 93 |
| 93 def unregister(self): | 94 def unregister(self): |
| 94 interface.unregister(self) | 95 interface.unregister(self) |
| 95 | 96 |
| 97 @staticmethod |
| 98 def _map_units_to_string(units): |
| 99 """Map MetricsDataUnits to the corresponding string according to: |
| 100 http://unitsofmeasure.org/ucum.html because that's what the new proto |
| 101 requires.""" |
| 102 if units in _UNITS_TO_STRING: |
| 103 return _UNITS_TO_STRING[units] |
| 104 else: |
| 105 return '{unknown}' |
| 106 |
| 107 def _populate_data_set(self, data_set, fields): |
| 108 """Populate MetricsDataSet.""" |
| 109 data_set.metric_name = '%s%s' % (interface.state.metric_name_prefix, |
| 110 self._name) |
| 111 data_set.description = self._description or '' |
| 112 data_set.annotations.unit = self._map_units_to_string(self._units) |
| 113 |
| 114 if self.is_cumulative(): |
| 115 data_set.stream_kind = new_metrics_pb2.CUMULATIVE |
| 116 else: |
| 117 data_set.stream_kind = new_metrics_pb2.GAUGE |
| 118 |
| 119 self._populate_value_type(data_set) |
| 120 self._populate_field_descriptors(data_set, fields) |
| 121 |
| 122 def _populate_data(self, data_set, start_time, end_time, fields, value): |
| 123 """Add a new metrics_pb2.MetricsData to data_set |
| 124 |
| 125 Args: |
| 126 data_set (new_metrics_pb2.MetricsDataSet): protocol buffer into |
| 127 which to add the current metric values. |
| 128 start_time (int): timestamp in microseconds since UNIX epoch. |
| 129 """ |
| 130 data = data_set.data.add() |
| 131 data.start_timestamp.seconds = int(start_time) |
| 132 data.end_timestamp.seconds = int(end_time) |
| 133 |
| 134 self._populate_fields_new(data, fields) |
| 135 self._populate_value_new(data, value) |
| 136 |
| 96 def serialize_to(self, collection_pb, start_time, fields, value, target): | 137 def serialize_to(self, collection_pb, start_time, fields, value, target): |
| 97 """Generate metrics_pb2.MetricsData messages for this metric. | 138 """Generate metrics_pb2.MetricsData messages for this metric. |
| 98 | 139 |
| 99 Args: | 140 Args: |
| 100 collection_pb (metrics_pb2.MetricsCollection): protocol buffer into which | 141 collection_pb (metrics_pb2.MetricsCollection): protocol buffer into which |
| 101 to add the current metric values. | 142 to add the current metric values. |
| 102 start_time (int): timestamp in microseconds since UNIX epoch. | 143 start_time (int): timestamp in microseconds since UNIX epoch. |
| 103 target (Target): a Target to use. | 144 target (Target): a Target to use. |
| 104 """ | 145 """ |
| 105 | 146 |
| 106 metric_pb = collection_pb.data.add() | 147 metric_pb = collection_pb.data.add() |
| 107 metric_pb.metric_name_prefix = interface.state.metric_name_prefix | 148 metric_pb.metric_name_prefix = interface.state.metric_name_prefix |
| 108 metric_pb.name = self._name | 149 metric_pb.name = self._name |
| 109 if self._description is not None: | 150 if self._description is not None: |
| 110 metric_pb.description = self._description | 151 metric_pb.description = self._description |
| 111 if self._units is not None: | 152 if self._units is not None: |
| 112 metric_pb.units = self._units | 153 metric_pb.units = self._units |
| 113 | 154 |
| 114 self._populate_value(metric_pb, value, start_time) | 155 self._populate_value(metric_pb, value, start_time) |
| 115 self._populate_fields(metric_pb, fields) | 156 self._populate_fields(metric_pb, fields) |
| 116 | 157 |
| 117 target._populate_target_pb(metric_pb) | 158 target._populate_target_pb(metric_pb) |
| 118 | 159 |
| 160 def _populate_field_descriptors(self, data_set, fields): |
| 161 """Populate `field_descriptor` in MetricsDataSet. |
| 162 |
| 163 Args: |
| 164 data_set (new_metrics_pb2.MetricsDataSet): a data set protobuf to |
| 165 populate |
| 166 fields (list of (key, value) tuples): normalized metric fields |
| 167 |
| 168 Raises: |
| 169 MonitoringInvalidFieldTypeError: if a field has a value of unknown type |
| 170 """ |
| 171 field_type = new_metrics_pb2.MetricsDataSet.MetricFieldDescriptor |
| 172 for key, value in fields: |
| 173 descriptor = data_set.field_descriptor.add() |
| 174 descriptor.name = key |
| 175 if isinstance(value, basestring): |
| 176 descriptor.field_type = field_type.STRING |
| 177 elif isinstance(value, bool): |
| 178 descriptor.field_type = field_type.BOOL |
| 179 elif isinstance(value, int): |
| 180 descriptor.field_type = field_type.INT64 |
| 181 else: |
| 182 raise errors.MonitoringInvalidFieldTypeError(self._name, key, value) |
| 183 |
| 184 def _populate_fields_new(self, data, fields): |
| 185 """Fill in the fields attribute of a metric protocol buffer. |
| 186 |
| 187 Args: |
| 188 metric (metrics_pb2.MetricsData): a metrics protobuf to populate |
| 189 fields (list of (key, value) tuples): normalized metric fields |
| 190 |
| 191 Raises: |
| 192 MonitoringInvalidFieldTypeError: if a field has a value of unknown type |
| 193 """ |
| 194 for key, value in fields: |
| 195 field = data.field.add() |
| 196 field.name = key |
| 197 if isinstance(value, basestring): |
| 198 field.string_value = value |
| 199 elif isinstance(value, bool): |
| 200 field.bool_value = value |
| 201 elif isinstance(value, int): |
| 202 field.int64_value = value |
| 203 else: |
| 204 raise errors.MonitoringInvalidFieldTypeError(self._name, key, value) |
| 205 |
| 119 def _populate_fields(self, metric, fields): | 206 def _populate_fields(self, metric, fields): |
| 120 """Fill in the fields attribute of a metric protocol buffer. | 207 """Fill in the fields attribute of a metric protocol buffer. |
| 121 | 208 |
| 122 Args: | 209 Args: |
| 123 metric (metrics_pb2.MetricsData): a metrics protobuf to populate | 210 metric (metrics_pb2.MetricsData): a metrics protobuf to populate |
| 124 fields (list of (key, value) tuples): normalized metric fields | 211 fields (list of (key, value) tuples): normalized metric fields |
| 125 | 212 |
| 126 Raises: | 213 Raises: |
| 127 MonitoringInvalidFieldTypeError: if a field has a value of unknown type | 214 MonitoringInvalidFieldTypeError: if a field has a value of unknown type |
| 128 """ | 215 """ |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 def _populate_value(self, metric, value, start_time): | 255 def _populate_value(self, metric, value, start_time): |
| 169 """Fill in the the data values of a metric protocol buffer. | 256 """Fill in the the data values of a metric protocol buffer. |
| 170 | 257 |
| 171 Args: | 258 Args: |
| 172 metric (metrics_pb2.MetricsData): a metrics protobuf to populate | 259 metric (metrics_pb2.MetricsData): a metrics protobuf to populate |
| 173 value (see concrete class): the value of the metric to be set | 260 value (see concrete class): the value of the metric to be set |
| 174 start_time (int): timestamp in microseconds since UNIX epoch. | 261 start_time (int): timestamp in microseconds since UNIX epoch. |
| 175 """ | 262 """ |
| 176 raise NotImplementedError() | 263 raise NotImplementedError() |
| 177 | 264 |
| 265 def _populate_value_new(self, data, value): |
| 266 """Fill in the the data values of a metric protocol buffer. |
| 267 |
| 268 Args: |
| 269 data (metrics_pb2.MetricsData): a metrics protobuf to populate |
| 270 value (see concrete class): the value of the metric to be set |
| 271 """ |
| 272 raise NotImplementedError() |
| 273 |
| 274 def _populate_value_type(self, data_set): |
| 275 """Fill in the the data values of a metric protocol buffer. |
| 276 |
| 277 Args: |
| 278 data_set (metrics_pb2.MetricsDataSet): a MetricsDataSet protobuf to |
| 279 populate |
| 280 """ |
| 281 raise NotImplementedError() |
| 282 |
| 178 def set(self, value, fields=None, target_fields=None): | 283 def set(self, value, fields=None, target_fields=None): |
| 179 """Set a new value for this metric. Results in sending a new value. | 284 """Set a new value for this metric. Results in sending a new value. |
| 180 | 285 |
| 181 The subclass should do appropriate type checking on value and then call | 286 The subclass should do appropriate type checking on value and then call |
| 182 self._set_and_send_value. | 287 self._set_and_send_value. |
| 183 | 288 |
| 184 Args: | 289 Args: |
| 185 value (see concrete class): the value of the metric to be set | 290 value (see concrete class): the value of the metric to be set |
| 186 fields (dict): additional metric fields to complement those on self | 291 fields (dict): additional metric fields to complement those on self |
| 187 target_fields (dict): overwrite some of the default target fields | 292 target_fields (dict): overwrite some of the default target fields |
| (...skipping 29 matching lines...) Expand all Loading... |
| 217 interface.state.store.incr(self.name, self._normalize_fields(fields), | 322 interface.state.store.incr(self.name, self._normalize_fields(fields), |
| 218 target_fields, delta, modify_fn=modify_fn) | 323 target_fields, delta, modify_fn=modify_fn) |
| 219 | 324 |
| 220 | 325 |
| 221 class StringMetric(Metric): | 326 class StringMetric(Metric): |
| 222 """A metric whose value type is a string.""" | 327 """A metric whose value type is a string.""" |
| 223 | 328 |
| 224 def _populate_value(self, metric, value, start_time): | 329 def _populate_value(self, metric, value, start_time): |
| 225 metric.string_value = value | 330 metric.string_value = value |
| 226 | 331 |
| 332 def _populate_value_new(self, data, value): |
| 333 data.string_value = value |
| 334 |
| 335 def _populate_value_type(self, data_set): |
| 336 data_set.value_type = new_metrics_pb2.STRING |
| 337 |
| 227 def set(self, value, fields=None, target_fields=None): | 338 def set(self, value, fields=None, target_fields=None): |
| 228 if not isinstance(value, basestring): | 339 if not isinstance(value, basestring): |
| 229 raise errors.MonitoringInvalidValueTypeError(self._name, value) | 340 raise errors.MonitoringInvalidValueTypeError(self._name, value) |
| 230 self._set(fields, target_fields, value) | 341 self._set(fields, target_fields, value) |
| 231 | 342 |
| 232 def is_cumulative(self): | 343 def is_cumulative(self): |
| 233 return False | 344 return False |
| 234 | 345 |
| 235 | 346 |
| 236 class BooleanMetric(Metric): | 347 class BooleanMetric(Metric): |
| 237 """A metric whose value type is a boolean.""" | 348 """A metric whose value type is a boolean.""" |
| 238 | 349 |
| 239 def _populate_value(self, metric, value, start_time): | 350 def _populate_value(self, metric, value, start_time): |
| 240 metric.boolean_value = value | 351 metric.boolean_value = value |
| 241 | 352 |
| 353 def _populate_value_new(self, data, value): |
| 354 data.bool_value = value |
| 355 |
| 356 def _populate_value_type(self, data_set): |
| 357 data_set.value_type = new_metrics_pb2.BOOL |
| 358 |
| 242 def set(self, value, fields=None, target_fields=None): | 359 def set(self, value, fields=None, target_fields=None): |
| 243 if not isinstance(value, bool): | 360 if not isinstance(value, bool): |
| 244 raise errors.MonitoringInvalidValueTypeError(self._name, value) | 361 raise errors.MonitoringInvalidValueTypeError(self._name, value) |
| 245 self._set(fields, target_fields, value) | 362 self._set(fields, target_fields, value) |
| 246 | 363 |
| 247 def is_cumulative(self): | 364 def is_cumulative(self): |
| 248 return False | 365 return False |
| 249 | 366 |
| 250 | 367 |
| 251 class NumericMetric(Metric): # pylint: disable=abstract-method | 368 class NumericMetric(Metric): # pylint: disable=abstract-method |
| (...skipping 13 matching lines...) Expand all Loading... |
| 265 def __init__(self, name, fields=None, start_time=None, description=None, | 382 def __init__(self, name, fields=None, start_time=None, description=None, |
| 266 units=None): | 383 units=None): |
| 267 super(CounterMetric, self).__init__( | 384 super(CounterMetric, self).__init__( |
| 268 name, fields=fields, description=description, units=units) | 385 name, fields=fields, description=description, units=units) |
| 269 self._start_time = start_time | 386 self._start_time = start_time |
| 270 | 387 |
| 271 def _populate_value(self, metric, value, start_time): | 388 def _populate_value(self, metric, value, start_time): |
| 272 metric.counter = value | 389 metric.counter = value |
| 273 metric.start_timestamp_us = int(start_time * MICROSECONDS_PER_SECOND) | 390 metric.start_timestamp_us = int(start_time * MICROSECONDS_PER_SECOND) |
| 274 | 391 |
| 392 def _populate_value_new(self, data, value): |
| 393 data.int64_value = value |
| 394 |
| 395 def _populate_value_type(self, data_set): |
| 396 data_set.value_type = new_metrics_pb2.INT64 |
| 397 |
| 275 def set(self, value, fields=None, target_fields=None): | 398 def set(self, value, fields=None, target_fields=None): |
| 276 if not isinstance(value, (int, long)): | 399 if not isinstance(value, (int, long)): |
| 277 raise errors.MonitoringInvalidValueTypeError(self._name, value) | 400 raise errors.MonitoringInvalidValueTypeError(self._name, value) |
| 278 self._set(fields, target_fields, value, enforce_ge=True) | 401 self._set(fields, target_fields, value, enforce_ge=True) |
| 279 | 402 |
| 280 def increment_by(self, step, fields=None, target_fields=None): | 403 def increment_by(self, step, fields=None, target_fields=None): |
| 281 if not isinstance(step, (int, long)): | 404 if not isinstance(step, (int, long)): |
| 282 raise errors.MonitoringInvalidValueTypeError(self._name, step) | 405 raise errors.MonitoringInvalidValueTypeError(self._name, step) |
| 283 self._incr(fields, target_fields, step) | 406 self._incr(fields, target_fields, step) |
| 284 | 407 |
| 285 def is_cumulative(self): | 408 def is_cumulative(self): |
| 286 return True | 409 return True |
| 287 | 410 |
| 288 | 411 |
| 289 class GaugeMetric(NumericMetric): | 412 class GaugeMetric(NumericMetric): |
| 290 """A metric whose value type is an integer.""" | 413 """A metric whose value type is an integer.""" |
| 291 | 414 |
| 292 def _populate_value(self, metric, value, start_time): | 415 def _populate_value(self, metric, value, start_time): |
| 293 metric.gauge = value | 416 metric.gauge = value |
| 294 | 417 |
| 418 def _populate_value_new(self, data, value): |
| 419 data.int64_value = value |
| 420 |
| 421 def _populate_value_type(self, data_set): |
| 422 data_set.value_type = new_metrics_pb2.INT64 |
| 423 |
| 295 def set(self, value, fields=None, target_fields=None): | 424 def set(self, value, fields=None, target_fields=None): |
| 296 if not isinstance(value, (int, long)): | 425 if not isinstance(value, (int, long)): |
| 297 raise errors.MonitoringInvalidValueTypeError(self._name, value) | 426 raise errors.MonitoringInvalidValueTypeError(self._name, value) |
| 298 self._set(fields, target_fields, value) | 427 self._set(fields, target_fields, value) |
| 299 | 428 |
| 300 def is_cumulative(self): | 429 def is_cumulative(self): |
| 301 return False | 430 return False |
| 302 | 431 |
| 303 | 432 |
| 304 class CumulativeMetric(NumericMetric): | 433 class CumulativeMetric(NumericMetric): |
| 305 """A metric whose value type is a monotonically increasing float.""" | 434 """A metric whose value type is a monotonically increasing float.""" |
| 306 | 435 |
| 307 def __init__(self, name, fields=None, start_time=None, description=None, | 436 def __init__(self, name, fields=None, start_time=None, description=None, |
| 308 units=None): | 437 units=None): |
| 309 super(CumulativeMetric, self).__init__( | 438 super(CumulativeMetric, self).__init__( |
| 310 name, fields=fields, description=description, units=units) | 439 name, fields=fields, description=description, units=units) |
| 311 self._start_time = start_time | 440 self._start_time = start_time |
| 312 | 441 |
| 313 def _populate_value(self, metric, value, start_time): | 442 def _populate_value(self, metric, value, start_time): |
| 314 metric.cumulative_double_value = value | 443 metric.cumulative_double_value = value |
| 315 metric.start_timestamp_us = int(start_time * MICROSECONDS_PER_SECOND) | 444 metric.start_timestamp_us = int(start_time * MICROSECONDS_PER_SECOND) |
| 316 | 445 |
| 446 def _populate_value_new(self, data, value): |
| 447 data.double_value = value |
| 448 |
| 449 def _populate_value_type(self, data_set): |
| 450 data_set.value_type = new_metrics_pb2.DOUBLE |
| 451 |
| 317 def set(self, value, fields=None, target_fields=None): | 452 def set(self, value, fields=None, target_fields=None): |
| 318 if not isinstance(value, (float, int)): | 453 if not isinstance(value, (float, int)): |
| 319 raise errors.MonitoringInvalidValueTypeError(self._name, value) | 454 raise errors.MonitoringInvalidValueTypeError(self._name, value) |
| 320 self._set(fields, target_fields, float(value), enforce_ge=True) | 455 self._set(fields, target_fields, float(value), enforce_ge=True) |
| 321 | 456 |
| 322 def is_cumulative(self): | 457 def is_cumulative(self): |
| 323 return True | 458 return True |
| 324 | 459 |
| 325 | 460 |
| 326 class FloatMetric(NumericMetric): | 461 class FloatMetric(NumericMetric): |
| 327 """A metric whose value type is a float.""" | 462 """A metric whose value type is a float.""" |
| 328 | 463 |
| 329 def _populate_value(self, metric, value, start_time): | 464 def _populate_value(self, metric, value, start_time): |
| 330 metric.noncumulative_double_value = value | 465 metric.noncumulative_double_value = value |
| 331 | 466 |
| 467 def _populate_value_new(self, metric, value): |
| 468 metric.double_value = value |
| 469 |
| 470 def _populate_value_type(self, data_set_pb): |
| 471 data_set_pb.value_type = new_metrics_pb2.DOUBLE |
| 472 |
| 332 def set(self, value, fields=None, target_fields=None): | 473 def set(self, value, fields=None, target_fields=None): |
| 333 if not isinstance(value, (float, int)): | 474 if not isinstance(value, (float, int)): |
| 334 raise errors.MonitoringInvalidValueTypeError(self._name, value) | 475 raise errors.MonitoringInvalidValueTypeError(self._name, value) |
| 335 self._set(fields, target_fields, float(value)) | 476 self._set(fields, target_fields, float(value)) |
| 336 | 477 |
| 337 def is_cumulative(self): | 478 def is_cumulative(self): |
| 338 return False | 479 return False |
| 339 | 480 |
| 340 | 481 |
| 341 class DistributionMetric(Metric): | 482 class DistributionMetric(Metric): |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 | 530 |
| 390 # Add the overflow buckets if present. | 531 # Add the overflow buckets if present. |
| 391 if value.bucketer.underflow_bucket in value.buckets: | 532 if value.bucketer.underflow_bucket in value.buckets: |
| 392 pb.underflow = value.buckets[value.bucketer.underflow_bucket] | 533 pb.underflow = value.buckets[value.bucketer.underflow_bucket] |
| 393 if value.bucketer.overflow_bucket in value.buckets: | 534 if value.bucketer.overflow_bucket in value.buckets: |
| 394 pb.overflow = value.buckets[value.bucketer.overflow_bucket] | 535 pb.overflow = value.buckets[value.bucketer.overflow_bucket] |
| 395 | 536 |
| 396 if value.count != 0: | 537 if value.count != 0: |
| 397 pb.mean = float(value.sum) / value.count | 538 pb.mean = float(value.sum) / value.count |
| 398 | 539 |
| 540 def _populate_value_new(self, metric, value): |
| 541 pb = metric.distribution_value |
| 542 |
| 543 # Copy the bucketer params. |
| 544 if value.bucketer.width == 0: |
| 545 pb.exponential_buckets.growth_factor = value.bucketer.growth_factor |
| 546 pb.exponential_buckets.scale = 1.0 |
| 547 pb.exponential_buckets.num_finite_buckets = ( |
| 548 value.bucketer.num_finite_buckets) |
| 549 else: |
| 550 pb.linear_buckets.width = value.bucketer.width |
| 551 pb.linear_buckets.offset = 0.0 |
| 552 pb.linear_buckets.num_finite_buckets = value.bucketer.num_finite_buckets |
| 553 |
| 554 # Copy the distribution bucket values. Only include the finite buckets, not |
| 555 # the overflow buckets on each end. |
| 556 pb.bucket_count.extend( |
| 557 value.buckets.get(i, 0) for i in |
| 558 xrange(0, value.bucketer.total_buckets)) |
| 559 |
| 560 pb.count = value.count |
| 561 pb.mean = float(value.sum) / max(value.count, 1) |
| 562 |
| 563 def _populate_value_type(self, data_set_pb): |
| 564 data_set_pb.value_type = new_metrics_pb2.DISTRIBUTION |
| 565 |
| 399 @staticmethod | 566 @staticmethod |
| 400 def _running_zero_generator(iterable): | 567 def _running_zero_generator(iterable): |
| 401 """Compresses sequences of zeroes in the iterable into negative zero counts. | 568 """Compresses sequences of zeroes in the iterable into negative zero counts. |
| 402 | 569 |
| 403 For example an input of [1, 0, 0, 0, 2] is converted to [1, -3, 2]. | 570 For example an input of [1, 0, 0, 0, 2] is converted to [1, -3, 2]. |
| 404 """ | 571 """ |
| 405 | 572 |
| 406 count = 0 | 573 count = 0 |
| 407 | 574 |
| 408 for value in iterable: | 575 for value in iterable: |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 484 def __new__(mcs, name, bases, attrs): | 651 def __new__(mcs, name, bases, attrs): |
| 485 attrs.update(metrics_pb2.MetricsData.Units.items()) | 652 attrs.update(metrics_pb2.MetricsData.Units.items()) |
| 486 return super(MetaMetricsDataUnits, mcs).__new__(mcs, name, bases, attrs) | 653 return super(MetaMetricsDataUnits, mcs).__new__(mcs, name, bases, attrs) |
| 487 | 654 |
| 488 | 655 |
| 489 class MetricsDataUnits(object): | 656 class MetricsDataUnits(object): |
| 490 """An enumeration class for units of measurement for Metrics data. | 657 """An enumeration class for units of measurement for Metrics data. |
| 491 See infra_libs/ts_mon/protos/metrics.proto for a full list of supported units. | 658 See infra_libs/ts_mon/protos/metrics.proto for a full list of supported units. |
| 492 """ | 659 """ |
| 493 __metaclass__ = MetaMetricsDataUnits | 660 __metaclass__ = MetaMetricsDataUnits |
| 661 |
| 662 _UNITS_TO_STRING = { |
| 663 MetricsDataUnits.UNKNOWN_UNITS: '{unknown}', |
| 664 MetricsDataUnits.SECONDS: 's', |
| 665 MetricsDataUnits.MILLISECONDS: 'ms', |
| 666 MetricsDataUnits.MICROSECONDS: 'us', |
| 667 MetricsDataUnits.NANOSECONDS: 'ns', |
| 668 MetricsDataUnits.BITS: 'B', |
| 669 MetricsDataUnits.BYTES: 'By', |
| 670 MetricsDataUnits.KILOBYTES: 'kBy', |
| 671 MetricsDataUnits.MEGABYTES: 'MBy', |
| 672 MetricsDataUnits.GIGABYTES: 'GBy', |
| 673 MetricsDataUnits.KIBIBYTES: 'kiBy', |
| 674 MetricsDataUnits.MEBIBYTES: 'MiBy', |
| 675 MetricsDataUnits.GIBIBYTES: 'GiBy', |
| 676 MetricsDataUnits.AMPS: 'A', |
| 677 MetricsDataUnits.MILLIAMPS : 'mA', |
| 678 MetricsDataUnits.DEGREES_CELSIUS: 'Cel' |
| 679 } |
| OLD | NEW |