prometheus中的指标timestamp有两个:
- prometheus拉取时刻的timestamp,即服务端的工夫:time.Now();
- exporter的/metrics接口,除了返回metric,value,还返回timestamp;
# HELP container_cpu_user_seconds_total Cumulative user cpu time consumed in seconds.# TYPE container_cpu_user_seconds_total countercontainer_cpu_user_seconds_total{container="",id="/",image="",name="",namespace="",pod=""} 788250.59 1692241058502container_cpu_user_seconds_total{container="",id="/kubepods.slice",image="",name="",namespace="",pod=""} 378238.54 1692241058529
一. prometheus的配置
对下面的两个timestamp,prometheus通过上面的配置决定抉择哪一个。
1. 配置
# honor_timestamps controls whether Prometheus respects the timestamps present# in scraped data.## If honor_timestamps is set to "true", the timestamps of the metrics exposed# by the target will be used.## If honor_timestamps is set to "false", the timestamps of the metrics exposed# by the target will be ignored.[ honor_timestamps: <boolean> | default = true ]
应用honor_timestamps配置拉取指标的工夫:
- 默认honor_timestamps=true;
honor_timestamps=true时:
- 应用拉取/metrics时exporter返回的timestamps;
- 若exporter未返回timestamps,则应用prometheus拉取时刻的timestamps(即服务端的工夫);
honor_timestamps=false时:
- 间接应用prometheus拉取时刻的timestamps(即服务端的工夫);
2. 源码
// scrape/scape.gofunc (sl *scrapeLoop) append(app storage.Appender, b []byte, contentType string, ts time.Time) (total, added, seriesAdded int, err error) { var ( p = textparse.New(b, contentType) defTime = timestamp.FromTime(ts) // 这里的ts=time.Now(),即拉取时的工夫 ) ... for { var ( et textparse.Entry sampleAdded bool ) if et, err = p.Next(); err != nil { if err == io.EOF { err = nil } break } ... t := defTime // defTime=time.Now() met, tp, v := p.Series() // 解析出拉取的:met=metrics, tp=timestamp, v=value if !sl.honorTimestamps { // 若honor_timestamps=false,tp=nil, 即应用服务端的工夫:time.Now() tp = nil } if tp != nil { // 若解析出之间,则t=解析的工夫,否则应用time.Now() t = *tp } ... err = app.AddFast(ce.ref, t, v) // 将t/v/series写入tsdb ... } ...}
二. exporter中的timestamp
1. 不带timestamp
# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.# TYPE go_gc_duration_seconds summarygo_gc_duration_seconds{quantile="0"} 0.000112409go_gc_duration_seconds{quantile="0.25"} 0.000435099go_gc_duration_seconds{quantile="0.5"} 0.000530901go_gc_duration_seconds{quantile="0.75"} 0.000681327go_gc_duration_seconds{quantile="1"} 0.00163155go_gc_duration_seconds_sum 11.546457813go_gc_duration_seconds_count 2331
在开发exporter时,也能够应用client_go的SetToCurrentTime()设置为以后工夫,这样/metrics就会返回timestamp。
2. 带timestamp(eg.cadvisor)
cavisor的/metrics返回了timestamp,紧跟在value前面:
# HELP container_cpu_user_seconds_total Cumulative user cpu time consumed in seconds.# TYPE container_cpu_user_seconds_total countercontainer_cpu_user_seconds_total{container="",id="/",image="",name="",namespace="",pod=""} 788250.59 1692241058502container_cpu_user_seconds_total{container="",id="/kubepods.slice",image="",name="",namespace="",pod=""} 378238.54 1692241058529container_cpu_user_seconds_total{container="",id="/kubepods.slice/kubepods-besteffort.slice",image="",name="",namespace="",pod=""} 17053.5 1692241041865container_cpu_user_seconds_total{container="",id="/kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-pod6cc5ddd5_aa45_4889_9106_20fcae0951e8.slice",image="",name="",namespace="kube-system",pod="kube-proxy-f6pjd"} 9980.23 1692241057892container_cpu_user_seconds_total{container="",id="/kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-poddabdd3fc_2893_4a90_99b8_464462a5ab6a.slice",image="",name="",namespace="kube-system",pod="calico-kube-controllers-75ddb95444-gv7j7"} 7073.3 1692241058973
cadvisor中结构prometheus指标中工夫的办法:
// cadvisor/metrics/prometheus.go{ name: "container_cpu_user_seconds_total", help: "Cumulative user cpu time consumed in seconds.", valueType: prometheus.CounterValue, getValues: func(s *info.ContainerStats) metricValues { return metricValues{ { value: float64(s.Cpu.Usage.User) / float64(time.Second), timestamp: s.Timestamp, }, } },}
能够看到,在采集的时候,记录了采集的timestamp,同时也把这个timestamp传给了prometheus:
for _, metricValue := range cm.getValues(stats) { ch <- prometheus.NewMetricWithTimestamp( metricValue.timestamp, prometheus.MustNewConstMetric(desc, cm.valueType, float64(metricValue.value), append(values, metricValue.labels...)...), )}
参考:
1.https://prometheus.io/docs/prometheus/latest/configuration/co...
2.https://mp.weixin.qq.com/s/kxHgNN_d83nT2LTNQyj6tg