1# 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 17 18def _threshold_for_count_below(buckets, boundaries, count_below): 19 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 39 40def percentile(buckets, pctl, boundaries): 41 return _threshold_for_count_below(buckets, boundaries, 42 sum(buckets) * pctl / 100.0) 43 44 45def counter(core_stats, name): 46 for stat in core_stats['metrics']: 47 if stat['name'] == name: 48 return int(stat.get('count', 0)) 49 50 51Histogram = collections.namedtuple('Histogram', 'buckets boundaries') 52 53 54def histogram(core_stats, name): 55 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) 63