前言:
最近公司在折腾应用级别的性能监控,现在已经有C、Java的版本了。 貌似还缺少我们组专用的Python版本。 现在做Metrics的公司有OneApm,就在我们的楼上。 oneapm的各种计算统计的api和dashboard面板虽然很好用,毕竟还是需要付费的。 今天就说下,我们是如何在python下获取metrics性能指标的. 这里透露下metric性能监控的架构,client其实是各个语言的metrics模块,数据的存取是Elasticsearch,前端的显示暂时是Kibana,当然kibana优缺点很鲜明,他不能很好的定制化页面,包括权限管理. 对于client –> elasticsearch集群的过程,可以增加本地一个本地转发节点完成,像scribe、logstash那样.
那么metries是什么? 是用来统计计算应用的性能指标, 频率, 耗时 ,大小长短…
举个例子,一个用python开发的爬虫服务:
一共处理了多少页面?
每秒钟的请求数是多少(TPS)?
平均每个请求处理的时间?
请求处理的最长耗时?
等待处理的请求队列长度?
每个函数在1分 5分 15分,分别的平均值在多少?
上面的这些需求就很适合用metrices来实现.
metrics原本是java的包,现在各个语言也都有基于metrices统计开发的模块。比如python的appmetrics,这名字就知道是应用监控 . 以前用python自己实现过一个简单的metrics,当然代码写得太low,不得见人… 这次结合appmetrics来说说五中metrics类型的区别,及应用场景。
文章写得不太严谨, 请砖家拍砖,另外标注下原文地址,http://xiaorui.cc/?p=2447
一共有五种 Metrics 类型
Gauges:
Gauges,最简单的度量指标,只有一个简单的返回值,例如,我们想衡量一个待处理队列中任务的个数
gauge可以是字符串,也可以是数字.
gauge = metrics.new_gauge("gauge_test") gauge.notify("version 1.0") gauge.get() {'kind': 'gauge', 'value': 'version 1.0'}
Counter:
Counter,就是计数器,inc增加,dec减少. 在appmetrics里面只暴露了notify
counter = metrics.new_counter("test") counter.notify(10) #xiaorui.cc counter.notify(-5) counter.get() {'kind': 'counter', 'value': 5} counter.notify("wrong") Traceback (most recent call last): File "<stdin>", line 1, in <module> File "appmetrics/simple_metrics.py", line 40, in notify value = int(value) ValueError: invalid literal for int() with base 10: 'wrong'
Meters:
Meters,度量一系列事件发生的速率(rate),例如TPS。Meters会统计最近1分钟,5分钟,15分钟,还有全部时间的速率。
meter = metrics.new_meter(“meter_test”)
meter.notify(1)
meter.notify(1)
meter.notify(3)
meter.get()
返回结果:
{'count': 5, 'kind': 'meter', 'five': 0.0066114184713530035, 'mean': 0.27743058841197027, 'fifteen': 0.0022160607980413085, 'day': 2.3147478365093123e-05, 'one': 0.031982234148270686}
count: 总数
mean: 平均值
one: 1分钟
five: 5分钟
fifteen: 15分钟
day: 一天的平均值
kind: “meter”
我们可以对比下java metrices运行结果:
count = 134
mean rate = 2.13 events/second
1-minute rate = 2.52 events/second
5-minute rate = 3.16 events/second
15-minute rate = 3.32 events/second
注:非常像 Unix 系统中 uptime 和 top 中的 load.
Histograms
Histogram统计数据的分布情况。比如最小值,最大值,中间值,还有中位数,75百分位, 90百分位, 95百分位, 98百分位, 99百分位, 和 99.9百分位的值(percentiles)。
import time, random @metrics.with_histogram("test") def my_worker(): time.sleep(random.random()) my_worker() #xiaorui.cc metrics.get("test")
返回结果:
{ 'arithmetic_mean': 0.41326093673706055, 'kind': 'histogram', 'skewness': 0.2739718270714368, 'harmonic_mean': 0.14326954591313346, 'min': 0.0613858699798584, 'standard_deviation': 0.4319169569113129, 'median': 0.2831099033355713, 'histogram': [(1.0613858699798584, 3), (2.0613858699798584, 0)], 'percentile': [(50, 0.2831099033355713), (75, 0.2831099033355713), (90, 0.895287036895752), (95, 0.895287036895752), (99, 0.895287036895752), (99.9, 0.895287036895752)], 'n': 3, 'max': 0.895287036895752, 'variance': 0.18655225766752892, 'geometric_mean': 0.24964828731906127, 'kurtosis': -2.3333333333333335 }
运行之后结果大致如下:
count = 56
min = 1122
max = 99650
mean = 48735.12
stddev = 28609.02
median = 49493.00
75% <= 72323.00
95% <= 90773.00
98% <= 94011.00
99% <= 99650.00
99.9% <= 99650.00
Timers
Timer其实是 Histogram 和 Meter 的结合, 在appmetrices里面没有直接的Timers的实现,但是可以通过Tagging实现.
metrics.new_histogram("test1") metrics.new_gauge("test2") metrics.new_meter("test3") metrics.tag("test1", "group1") metrics.tag("test3", "group1") metrics.tags() metrics.metrics_by_tag("group1")
返回的结果
{ 'test1': { 'arithmetic_mean': 0.0, 'skewness': 0.0, 'harmonic_mean': 0.0, 'min': 0, 'standard_deviation': 0.0, 'median': 0.0, 'histogram': [(0, 0)], 'percentile': [(50, 0.0), (75, 0.0), (90, 0.0), (95, 0.0), (99, 0.0), (99.9, 0.0)], 'n': 0, 'max': 0, 'variance': 0.0, 'geometric_mean': 0.0, 'kurtosis': 0.0 }, 'test3': { 'count': 0, 'five': 0.0, 'mean': 0.0, 'fifteen': 0.0, 'day': 0.0, 'one': 0.0 } }
如果用java metrics运行之后结果如下.
count = 38
mean rate = 1.90 calls/second
1-minute rate = 1.66 calls/second
5-minute rate = 1.61 calls/second
15-minute rate = 1.60 calls/second
min = 13.90 milliseconds
max = 988.71 milliseconds
mean = 519.21 milliseconds
stddev = 286.23 milliseconds
median = 553.84 milliseconds
75% <= 763.64 milliseconds
95% <= 943.27 milliseconds
98% <= 988.71 milliseconds
99% <= 988.71 milliseconds
99.9% <= 988.71 milliseconds
使用经验总结,
一般情况下,当我们需要统计某个函数或者action被调用的频率,会使用Meters。当我们需要统计某个函数的执行耗时,会使用Histograms。当我们既要统计频率又要统计耗时的时候,我们会使用Timers。所以说,Timers的数据最全。