# Copyright 2017 gRPC authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import collections def _threshold_for_count_below(buckets, boundaries, count_below): count_so_far = 0 for lower_idx in range(0, len(buckets)): count_so_far += buckets[lower_idx] if count_so_far >= count_below: break if count_so_far == count_below: # this bucket hits the threshold exactly... we should be midway through # any run of zero values following the bucket for upper_idx in range(lower_idx + 1, len(buckets)): if buckets[upper_idx] != 0: break return (boundaries[lower_idx] + boundaries[upper_idx]) / 2.0 else: # treat values as uniform throughout the bucket, and find where this value # should lie lower_bound = boundaries[lower_idx] upper_bound = boundaries[lower_idx + 1] return (upper_bound - (upper_bound - lower_bound) * (count_so_far - count_below) / float(buckets[lower_idx])) def percentile(buckets, pctl, boundaries): return _threshold_for_count_below(buckets, boundaries, sum(buckets) * pctl / 100.0) def counter(core_stats, name): for stat in core_stats['metrics']: if stat['name'] == name: return int(stat.get('count', 0)) Histogram = collections.namedtuple('Histogram', 'buckets boundaries') def histogram(core_stats, name): for stat in core_stats['metrics']: if stat['name'] == name: buckets = [] boundaries = [] for b in stat['histogram']['buckets']: buckets.append(int(b.get('count', 0))) boundaries.append(int(b.get('start', 0))) return Histogram(buckets=buckets, boundaries=boundaries)