blob: 108451cd5522e637db3ea69938c5c7e01e0ef6c1 [file] [log] [blame]
Craig Tillerf11a40d2017-09-12 10:54:20 -07001# Copyright 2017 gRPC authors.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import collections
16
ncteiseneb128152017-12-11 17:48:24 -080017
Craig Tiller5d615602017-09-12 13:15:58 -070018def _threshold_for_count_below(buckets, boundaries, count_below):
ncteiseneb128152017-12-11 17:48:24 -080019 count_so_far = 0
20 for lower_idx in range(0, len(buckets)):
21 count_so_far += buckets[lower_idx]
22 if count_so_far >= count_below:
23 break
24 if count_so_far == count_below:
25 # this bucket hits the threshold exactly... we should be midway through
26 # any run of zero values following the bucket
27 for upper_idx in range(lower_idx + 1, len(buckets)):
28 if buckets[upper_idx] != 0:
29 break
30 return (boundaries[lower_idx] + boundaries[upper_idx]) / 2.0
31 else:
32 # treat values as uniform throughout the bucket, and find where this value
33 # should lie
34 lower_bound = boundaries[lower_idx]
35 upper_bound = boundaries[lower_idx + 1]
36 return (upper_bound - (upper_bound - lower_bound) *
37 (count_so_far - count_below) / float(buckets[lower_idx]))
38
Craig Tillerf11a40d2017-09-12 10:54:20 -070039
40def percentile(buckets, pctl, boundaries):
ncteiseneb128152017-12-11 17:48:24 -080041 return _threshold_for_count_below(buckets, boundaries,
42 sum(buckets) * pctl / 100.0)
43
Craig Tillerf11a40d2017-09-12 10:54:20 -070044
45def counter(core_stats, name):
ncteiseneb128152017-12-11 17:48:24 -080046 for stat in core_stats['metrics']:
47 if stat['name'] == name:
48 return int(stat.get('count', 0))
49
Craig Tillerf11a40d2017-09-12 10:54:20 -070050
51Histogram = collections.namedtuple('Histogram', 'buckets boundaries')
ncteiseneb128152017-12-11 17:48:24 -080052
53
Craig Tillerf11a40d2017-09-12 10:54:20 -070054def histogram(core_stats, name):
ncteiseneb128152017-12-11 17:48:24 -080055 for stat in core_stats['metrics']:
56 if stat['name'] == name:
57 buckets = []
58 boundaries = []
59 for b in stat['histogram']['buckets']:
60 buckets.append(int(b.get('count', 0)))
61 boundaries.append(int(b.get('start', 0)))
62 return Histogram(buckets=buckets, boundaries=boundaries)