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

Side by Side Diff: infra_libs/ts_mon/common/metric_store.py

Issue 1531573003: Handle multiple modifications to distribution metrics correctly. (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Created 5 years 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 unified diff | Download patch
OLDNEW
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 import collections 5 import collections
6 import logging 6 import logging
7 import operator 7 import operator
8 import threading 8 import threading
9 import time 9 import time
10 10
11 from infra_libs.ts_mon.common import errors 11 from infra_libs.ts_mon.common import errors
12 12
13 13
14 """A light-weight representation of a set or an incr. 14 """A light-weight representation of a set or an incr.
15 15
16 Args: 16 Args:
17 name: The metric name. 17 name: The metric name.
18 fields: The normalized field tuple. 18 fields: The normalized field tuple.
19 mod_type: Either 'set' or 'incr'. Other values will raise 19 mod_type: Either 'set' or 'incr'. Other values will raise
20 UnknownModificationTypeError when it's used. 20 UnknownModificationTypeError when it's used.
21 args: (value, enforce_ge) for 'set' or (delta, modify_fn) for 'incr'. 21 args: (value, enforce_ge) for 'set' or (delta, modify_fn) for 'incr'.
22 """ # pylint: disable=pointless-string-statement 22 """ # pylint: disable=pointless-string-statement
23 Modification = collections.namedtuple( 23 Modification = collections.namedtuple(
24 'Modification', ['name', 'fields', 'mod_type', 'args']) 24 'Modification', ['name', 'fields', 'mod_type', 'args'])
25 25
26 26
27 def combine_modifications(old, new):
28 """Combines two modifications into one.
29
30 The returned modification will be the result as if the second modification had
31 been applied after the first.
32 """
33
34 if old is None or new.mod_type == 'set':
35 # A 'set' will override any previous value.
36 return new
37 elif new.mod_type == 'incr':
38 # For two 'incr's sum their delta args, for an 'incr' on top of a 'set' add
39 # the delta to the set value.
40 return Modification(
41 old.name, old.fields, old.mod_type,
42 (old.args[0] + new.args[0], old.args[1]))
43 else:
44 raise errors.UnknownModificationTypeError(new.mod_type)
45
46
47 class MetricStore(object): 27 class MetricStore(object):
48 """A place to store values for each metric. 28 """A place to store values for each metric.
49 29
50 Several methods take "a normalized field tuple". This is a tuple of 30 Several methods take "a normalized field tuple". This is a tuple of
51 (key, value) tuples sorted by key. (The reason this is given as a tuple 31 (key, value) tuples sorted by key. (The reason this is given as a tuple
52 instead of a dict is because tuples are hashable and can be used as dict keys, 32 instead of a dict is because tuples are hashable and can be used as dict keys,
53 dicts can not). 33 dicts can not).
54 34
55 The MetricStore is also responsible for keeping the start_time of each metric. 35 The MetricStore is also responsible for keeping the start_time of each metric.
56 This is what goes into the start_timestamp_us field in the MetricsData proto 36 This is what goes into the start_timestamp_us field in the MetricsData proto
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 184
205 def reset_for_unittest(self, name=None): 185 def reset_for_unittest(self, name=None):
206 if name is not None: 186 if name is not None:
207 self._reset(name) 187 self._reset(name)
208 else: 188 else:
209 for name in self._values.keys(): 189 for name in self._values.keys():
210 self._reset(name) 190 self._reset(name)
211 191
212 def _reset(self, name): 192 def _reset(self, name):
213 self._values[name] = (self._start_time(name), {}) 193 self._values[name] = (self._start_time(name), {})
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698