massage_qps_stats_helpers.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  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. import collections
  15. def _threshold_for_count_below(buckets, boundaries, count_below):
  16. count_so_far = 0
  17. for lower_idx in range(0, len(buckets)):
  18. count_so_far += buckets[lower_idx]
  19. if count_so_far >= count_below:
  20. break
  21. if count_so_far == count_below:
  22. # this bucket hits the threshold exactly... we should be midway through
  23. # any run of zero values following the bucket
  24. for upper_idx in range(lower_idx + 1, len(buckets)):
  25. if buckets[upper_idx] != 0:
  26. break
  27. return (boundaries[lower_idx] + boundaries[upper_idx]) / 2.0
  28. else:
  29. # treat values as uniform throughout the bucket, and find where this value
  30. # should lie
  31. lower_bound = boundaries[lower_idx]
  32. upper_bound = boundaries[lower_idx + 1]
  33. return (upper_bound - (upper_bound - lower_bound) *
  34. (count_so_far - count_below) / float(buckets[lower_idx]))
  35. def percentile(buckets, pctl, boundaries):
  36. return _threshold_for_count_below(buckets, boundaries,
  37. sum(buckets) * pctl / 100.0)
  38. def counter(core_stats, name):
  39. for stat in core_stats['metrics']:
  40. if stat['name'] == name:
  41. return int(stat.get('count', 0))
  42. Histogram = collections.namedtuple('Histogram', 'buckets boundaries')
  43. def histogram(core_stats, name):
  44. for stat in core_stats['metrics']:
  45. if stat['name'] == name:
  46. buckets = []
  47. boundaries = []
  48. for b in stat['histogram']['buckets']:
  49. buckets.append(int(b.get('count', 0)))
  50. boundaries.append(int(b.get('start', 0)))
  51. return Histogram(buckets=buckets, boundaries=boundaries)