首页 >> 车型 >> 「潮流」通过Prometheus的Exporter搜集你想要的一切

「潮流」通过Prometheus的Exporter搜集你想要的一切

2025-11-26 12:16:44

的明确指出接收者。

HELP

#TYPE 的素材XML如下表,必需填入当前地名和当前各种类型(如果没有一致的当前各种类型,必需赶回 untyped)。

TYPE

跟踪采样部分必需满足如下XML标准。

metric_name [ "{" label_name "=" " label_value " { "," label_name "=" " label_value " } [ "," ] "}" ] value [ timestamp ]

其里,metric_name 和 label_name 能够遵循 PromQL 的XML标准。value 是一个 f loat XML的数据集,timestamp 的各种类型为 int64(从 1970-01-01 00:00:00 开始至今的总毫秒数),可另设其可选为当前时间。

具有并不相同 metric_name 的采样能够按照一个组的型式左至右,并且每正要能够是唯一的当前地名和附加偏移使用量对组合。Prometheus 为了方便使用 client library 的类似于提供者了四种数据集各种类型:

Counter:Counter 是一个累加的数据集各种类型。一个 Counter 各种类型的当前只亦会随着时间逐渐递减(当系统亦会重启的时候,Counter 当前亦会被重置为 0)。据信系统亦会顺利同步进行的总任务生产厂使用量、系统亦会从近期一次启动到目前为止频发的总错误数等场景都简便类似于 Counter 各种类型的当前。Gauge:Gauge 当前主要运用于据信一个瞬时倍数,这个当前可以增加也可此表降,比如 CPU 的类似于情况、内存类似于使用量以及ROM当前的内部空间容使用量等。Histogram:Histogram 表示柱状图,主要运用于人口统计一些数据集分布的情况,可以计算在一定范围内的数据集分布情况,同时还提供者了当前倍数的总和。在大多数情况下,应用程序亦会类似于某些当前的最少倍数作为概述,例如,类似于系统亦会的最少作出反应时间来衡使用量系统亦会的作出反应并能。这种手段有个显着的疑问——如果大多数恳求的作出反应时间都维持在 100ms 内,而个别恳求的作出反应时间必需 1s 甚至更久,那么作出反应时间的最少倍数体现不成作出反应时间里的尖刺,这就是所谓的“吉氏疑问”。为了更加真实地反映系统亦会作出反应并能,类似于的手段是按照恳求提前的范围同步进行分组,例如在上述下例里,可以分别人口统计作出反应时间在[0,100ms]、[100,1s]和[1s,∞]这 3 个该线的恳求数,通过拍照这 3 个分区里恳求使用量的分布,就可以尤其客观地研究成系统亦会的作出反应并能。Summary:Summary 与 Histogram 相近,也亦会人口统计当前的总数(以_count 作为后缀)以及 sum 倍数(以_sum 作为后缀)。两者的主要区别在于,Histogram 当前这样一来据信了在不同该线内采样的取倍数,而 Summary 各种类型则由客户端计算对应的分小数点。例如下例展示了一个 Summary 各种类型的当前,其里 quantile=”0.5”表示里小数点,quantile=”0.9”表示九分小数点。

广义上讲,所有可以向 Prometheus 提供者跟踪采样数据集的程序在都可以被特指一个 Exporter,Exporter 的一个下例被特指 target,Prometheus 亦会通过轮询的型式定时从这些 target 里赚取采样数据集。

自己动手编订一个 Exporter

一般来说,绝大多数 Exporter 都是基于 Go 语法编订的,一小部分是基于 Python 语法编订的,还有很小一部分是类似于 Java 语法编订的。比如其网站提供者的 Consul Metrics 图标热带植物器 Exporter,如果是在 Go 语法的运行环境下,必需按照如下表下例运行这个 Exporter。

package main import ( "log" "net/http" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp") var ( cpuTemp = prometheus.NewGauge(prometheus.GaugeOpts{ NameSpace: "our_idc", Subsystem: "k8s" Name: "cpu_temperature_celsius", Help: "Current temperature of the CPU.", }) hdFailures = prometheus.NewCounterVec( prometheus.CounterOpts{ NameSpace: "our_idc", Subsystem: "k8s" Name: "hd_errors_total", Help: "Number of hard-disk errors.", }, []string{"device"}, )) func init() { // Metrics have to be registered to be exposed: prometheus.MustRegister(cpuTemp) prometheus.MustRegister(hdFailures)} func main() { cpuTemp.Set(65.3) hdFailures.With(prometheus.Labels{"device":"/dev/sda"}).Inc() // The Handler function provides a default handler to expose metrics // via an HTTP server. "/metrics" is the usual endpoint for that. http.Handle("/metrics", promhttp.Handler()) log.Fatal(http.ListenAndServe(":8888", nil))

其里创设了一个 gauge 和 CounterVec 取向,并分别以外了 metric name 和 help 接收者,其里 CounterVec 是用来经营管理并不相同 metric 下不同 label 的除此以外 Counter,同理存在 GaugeVec,可以想到下面下例里通告了一个 lable 的 key 为“device”,类似于的时候也必需以外一个 lable: hdFailures.With(prometheus.Labels{"device":"/dev/sda"}).Inc()。

变使用量概念后同步进行注册,最后便重启一个 http 增倍数的 8888 接口就顺利同步进行了整个程序在,Prometheus 热带植物数据集是通过定时恳求该增倍数 http 接口来付诸的。

启动程序在之后可以在 web 搜索引擎里输成 就可以得不到 client 渗入的数据集,其里有片段推断为:

# HELP our_idc_k8s_cpu_temperature_celsius Current temperature of the CPU.# TYPE our_idc_k8s_cpu_temperature_celsius gaugeour_idc_k8s_cpu_temperature_celsius 65.3# HELP our_idc_k8s_hd_errors_total Number of hard-disk errors.# TYPE our_idc_k8s_hd_errors_total counterour_idc_k8s_hd_errors_total{device="/dev/sda"} 1

上图就是下例程序在所渗入成来的数据集,并且可以想到 counterVec 是有 label 的,而比如说的 gauage 取向却要用 lable 标识,这就是基本数据集各种类型和对应 Vec 旧版本的差别。此时便拍照 就亦会辨认出增倍数状态已经转化成 UP 了。

下面的例证只是一个简便的 demo,因为在 prometheus.yml 装配文件里我们以外热带植物路由器接收者的时间间隔为 60s,每隔 60s Prometheus 亦会通过 http 恳求一次自己渗入的数据集,而在下例里我们只另设了一次 gauge 变使用量 cupTemp 的倍数,如果在 60s 的采样间隔里将该倍数另设多次,前面的倍数就亦会被其余部分,只有 Prometheus 热带植物数据集那一刻的倍数能被想到,并且如果便改变这个倍数,Prometheus 就始终能想到这个恒定的变使用量,除非应用程序显式通过 Delete 变量移除这个变使用量。

类似于 Counter,Gauage 等这些本体一般来说,但是如果便类似于这些变使用量必需我们手动删,我们可以指示行 resetfunction 来清除之前的 metrics。

图标 Collector

这样一来类似于 Collector,go client Colletor 只亦会在每次作出反应 Prometheus 恳求的时候才搜罗数据集。

必需每次显式传递信息变使用量的倍数,否则就不亦会便维持该变使用量,在 Prometheus 也将看不到这个变使用量。Collector 是一个API,所有搜罗 metrics 数据集的取向都必需付诸这个API,Counter 和 Gauage 等不例外。它之下提供者了两个变量,Collector 运用于搜罗应用程序数据集,将搜罗好的数据集传递信息给传入倍数 Channel 就可;Descirbe 变量运用于描述这个 Collector。

当搜罗系统亦会搜罗的数据集太多时时,就可以图标 Collector 搜罗的手段,优化处理过程,并且在某些情况下如果已经有了一个成熟的 metrics,就不必需类似于 Counter,Gauage 等这些数据集本体,这样一来在 Collector 之下付诸一个代理的基本功能即可。

之外所有的 export 都是通过图标 Collector 付诸。一个简便的 Collector 的付诸 export 的下例如下:

package main import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" "net/http" "sync") type ClusterManager struct { sync.Mutex Zone string metricMapCounters map[string]string metricMapGauges map[string]string} //Simulate prepare the datafunc (c *ClusterManager) ReallyExpensiveAssessmentOfTheSystemState() ( metrics map[string]float64,) { metrics = map[string]float64{ "oom_crashes_total": 42.00, "ram_usage": 6.023e23, } return}//通过 NewClusterManager 理论创设本体体及对应的当前接收者,下例如下表。// NewClusterManager creates the two Descs OOMCountDesc and RAMUsageDesc. Note// that the zone is set as a ConstLabel. (It's different in each instance of the// ClusterManager, but constant over the lifetime of an instance.) Then there is// a variable label "host", since we want to partition the collected metrics by// host. Since all Descs created in this way are consistent across instances,// with a guaranteed distinction by the "zone" label, we can register different// ClusterManager instances with the same registry.func NewClusterManager(zone string) *ClusterManager { return WildClusterManager{ Zone: zone, metricMapGauges: map[string]string{ "ram_usage": "ram_usage_bytes", }, metricMapCounters: map[string]string{ "oom_crashes": "oom_crashes_total", }, }}//首先,热带植物器能够付诸 prometheus.Collector API,也能够付诸 Describe 和 Collect 理论。付诸API的下例如下表。// Describe simply sends the two Descs in the struct to the channel.// Prometheus 的注册器指示行 Collect 来能用倍数 // 将搜罗的数据集传递信息到 Channel 里并赶回 // 搜罗的当前接收者来自 Describe,可以并发地执行能用临时工,但是能够要保证线程的安全 func (c *ClusterManager) Describe(ch chan<- *prometheus.Desc) { // prometheus.NewDesc(prometheus.BuildFQName(namespace, "", metricName), docString, labels, nil) for _, v := range c.metricMapGauges { ch <- prometheus.NewDesc(prometheus.BuildFQName(c.Zone, "", v), v, nil, nil) } for _, v := range c.metricMapCounters { ch <- prometheus.NewDesc(prometheus.BuildFQName(c.Zone, "", v), v, nil, nil) }} //Collect 理论是核心,它亦会能用你必需的所有数据集,根据供给对其同步进行研究,然后将当前发送给回客户端库。// 运用于传递信息所有可能当前的概念描述符 // 可以在程序在运行期间添加另行的描述,搜罗另行的当前接收者 // 重复的描述符将被忽略。两个不同的 Collector 不要另设并不相同的描述符 func (c *ClusterManager) Collect(ch chan<- prometheus.Metric) { c.Lock() defer c.Unlock() m := c.ReallyExpensiveAssessmentOfTheSystemState() for k, v := range m { t := prometheus.GaugeValue if c.metricMapCounters[k] != "" { t = prometheus.CounterValue } c.registerConstMetric(ch, k, v, t) }}// 运用于传递信息所有可能当前的概念描述符给当前func (c *ClusterManager) registerConstMetric(ch chan<- prometheus.Metric, metric string, val float64, valType prometheus.ValueType, labelValues ...string) { descr := prometheus.NewDesc(prometheus.BuildFQName(c.Zone, "", metric), metric, nil, nil) if m, err := prometheus.NewConstMetric(descr, valType, val, labelValues...); err == nil { ch <- m }} func main() { workerCA := NewClusterManager("xiaodian") reg := prometheus.NewPedanticRegistry() reg.MustRegister(workerCA) //当 promhttp.Handler()被执行时,所有 metric 被序列化输成。题外话,其实输成的XML既可以是 plain text,也可以是 protocol Buffers。 http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{})) http.ListenAndServe(":8888", nil)}

此时就可以去 想到传递信息现在的数据集了。

高质使用量 Exporter 的编订原则与理论主要理论

概述链接:_exporters/。

在访问 Exporter 的主页(即 这样的根逆时针)时,它亦会赶回一个简便的页面,这就是 Exporter 的放页(Landing Page)。放页里可以捡HTML和努力接收者,包括跟踪当前项的明确指出。放页上还包括近期执行的健康检查本表、本表的状态以及调试接收者,这对过热清理极其有努力。一台路由器或者容器上可能亦会有许多 Exporter 和 Prometheus 组件,它们都有自己的接口号。因此,在写就 Exporter 和发布 Exporter 之前,必需健康检查另行添加的接口是否已经被类似于[1],敦促类似于可选接口分配范围之外的接口。我们应该根据企业各种类型其设计好当前的#HELP#TYPE 的XML。这些当前往往是可装配的,包括可选重启的当前和可选停止使用的当前。这是因为大多当前并不亦会真正被用到,其设计过多的当前不仅亦会可用故意的资源,还亦会因素整体的可靠性。其他理论

对于如何写就高质使用量 Exporter,除了有效分配接口号、其设计放页、一目了然当前这 3 个之外外,还有一些其他的原则。

据信 Exporter 本身的运行状态当前。可装配化同步进行基本功能的启用和停止使用。推荐类似于 YAML 作为装配XML。遵循微分标准重另行命名的最佳系统化[2],除此以外是_count、_sum、_total、_bucket 和 info 等疑问。为微分提供者正确的该单位。附加的唯一性、可读性及必要的延时接收者其设计。通过 Docker 等手段一键装配 Exporter。尽使用量类似于 Collectors 手段搜罗当前,如 Go 语法里的 MustNewConstMetric。提供者 scrapes 刮擦不甘心的错误其设计,这有助于可靠性调试。尽使用量不要重复提供者较早的当前,如 Node Exporter 已经提供者的 CPU、磁盘等接收者。向 Prometheus 引起争议原始的微分数据集,不敦促自行计算,Exporter 的核心是热带植物原始当前。Redis Exporter 源代码解析

在本章里,读者可以辨认出开捡源代码领域展现成不计其数的 Exporter,阿里巴巴开捡源代码的 Exporter 就有 RocketMQ Exporter、Sentinel Exporter、Sentry Exporter、Alibaba Cloud Exporter 等多种。

编订 Exporter 和编订 Spring Boot Starter 一样,可以多概述其他优秀的开捡源代码操作系统的下例。

本节就来简便研究一下运维临时工里用到的 Redis Exporter 源代码。

在类似于 Redis Exporter 时,可以通过 redis_exporter--help 指示拍照完整的倍数本表。可选情况下,它在接口 9192 上运行,并在逆时针/metrics 上渗入当前。可以通过--web.listen-addres 和--web.telemetry-path 指示来另设接口和逆时针,下例如下表。

redis_exporter -web.listen-address=":8888" -web.telemetry-path="/node_metrics"

上述下例将简化 redis Exporter 绑定到接口 8888 并在逆时针/node_metrics 上渗入当前。

这个逻辑是在源代码 redis_exporter.go 里付诸的.Redis Exporter[3]主要通过 Redis 原生的指示赚取 Redis 所有的接收者,它赞同 2.x、3.x、4.x、5.x 和 6.x 旧版本。

在源代码里,可以想到多处类似于了 doRedisCmd 理论发送给指示以赚取可靠性当前,下例如下表。主要是通过原生的 INFO 指示赚取所有可靠性接收者。该指示的赶回结果详情概述[4]。

infoAll, err := redis.String(doRedisCmd(c, "INFO", "ALL"))

转换成的 infoAll 接收者通过 func (e *Exporter) extractInfoMetrics(ch chanfunc (e *Exporter) extractInfoMetrics(ch chan<- prometheus.Metric, info string, dbCount int) { keyValues := map[string]string{} handledDBs := map[string]bool{} fieldClass := "" //以换行符同步进行分割 lines := strings.Split(info, "") masterHost := "" masterPort := "" //遍历查询到的结果,根据当前转换成一个 hash 倍数 for _, line := range lines { line = strings.TrimSpace(line) log.Debugf("info: %s", line) //去除带#的注释文件 if len(line)> 0 WildWild strings.HasPrefix(line, "# ") { fieldClass = line[2:] log.Debugf("set fieldClass: %s", fieldClass) continue } //去除不带:的或者字符低于 2 的 if (len(line) < 2) || (!strings.Contains(line, ":")) { continue } //以冒号同步进行分割 split := strings.SplitN(line, ":", 2) fieldKey := split[0] fieldValue := split[1] //将当前地名与倍数存到 hash 里 keyValues[fieldKey] = fieldValue if fieldKey == "master_host" { masterHost = fieldValue } if fieldKey == "master_port" { masterPort = fieldValue } //按照集群和副本和哨兵模式同步进行处理 switch fieldClass { case "Replication": if ok := e.handleMetricsReplication(ch, masterHost, masterPort, fieldKey, fieldValue); ok { continue } case "Server": e.handleMetricsServer(ch, fieldKey, fieldValue) case "Commandstats": e.handleMetricsCommandStats(ch, fieldKey, fieldValue) continue case "Keyspace": if keysTotal, keysEx, avgTTL, ok := parseDBKeyspaceString(fieldKey, fieldValue); ok { dbName := fieldKey e.registerConstMetricGauge(ch, "db_keys", keysTotal, dbName) e.registerConstMetricGauge(ch, "db_keys_expiring", keysEx, dbName) if avgTTL> -1 { e.registerConstMetricGauge(ch, "db_avg_ttl_seconds", avgTTL, dbName) } handledDBs[dbName] = true continue } case "Sentinel": e.handleMetricsSentinel(ch, fieldKey, fieldValue) } if !e.includeMetric(fieldKey) { continue } //将搜罗到接收者同步进行按照一定法则同步进行处理 e.parseAndRegisterConstMetric(ch, fieldKey, fieldValue) } for dbIndex := 0; dbIndex < dbCount; dbIndex++ { dbName := "db" + strconv.Itoa(dbIndex) if _, exists := handledDBs[dbName]; !exists { e.registerConstMetricGauge(ch, "db_keys", 0, dbName) e.registerConstMetricGauge(ch, "db_keys_expiring", 0, dbName) } } e.registerConstMetricGauge(ch, "instance_info", 1, keyValues["role"], keyValues["redis_version"], keyValues["redis_build_id"], keyValues["redis_mode"], keyValues["os"], keyValues["maxmemory_policy"], keyValues["tcp_port"], keyValues["run_id"], keyValues["process_id"], ) if keyValues["role"] == "slave" { e.registerConstMetricGauge(ch, "slave_info", 1, keyValues["master_host"], keyValues["master_port"], keyValues["slave_read_only"]) }}

然后通过 e.parseAndRegisterConstMetric(ch, fieldKey, fieldValue)理论,将搜罗到 hash 里的接收者,按照一定的法则转换成 prometheus.Metric。核心下例如下:

func (e *Exporter) parseAndRegisterConstMetric(ch chan<- prometheus.Metric, fieldKey, fieldValue string) { orgMetricName := sanitizeMetricName(fieldKey) metricName := orgMetricName if newName, ok := e.metricMapGauges[metricName]; ok { metricName = newName } else { if newName, ok := e.metricMapCounters[metricName]; ok { metricName = newName } } var err error var val float64 switch fieldValue { case "ok", "true": val = 1 case "err", "fail", "false": val = 0 default: val, err = strconv.ParseFloat(fieldValue, 64) } if err != nil { log.Debugf("couldn't parse %s, err: %s", fieldValue, err) } //根据 key 判断 prometheus.ValueType t := prometheus.GaugeValue if e.metricMapCounters[orgMetricName] != "" { t = prometheus.CounterValue } switch metricName { case "latest_fork_usec": metricName = "latest_fork_seconds" val = val / 1e6 } //根据 prometheus.ValueType 转换成转换成 prometheus.Metric,将其捡到一个 chanal 里 e.registerConstMetric(ch, metricName, val, t)}e.parseAndRegisterConstMetric(ch, fieldKey, fieldValue)

然后通过 func (e *Exporter) registerConstMetric(ch chanfunc (e *Exporter) registerConstMetric(ch chan<- prometheus.Metric, metric string, val float64, valType prometheus.ValueType, labelValues ...string) { descr := e.metricDescriptions[metric] if descr == nil { descr = newMetricDescr(e.options.Namespace, metric, metric+" metric", labelValues) } if m, err := prometheus.NewConstMetric(descr, valType, val, labelValues...); err == nil { ch <- m }}

最后*Exporter.Collect 的理论指示行 registerConstMetric 理论,就顺利同步进行了 redis 的 info 当前的搜罗。其他当前的搜罗这样一来也是并不相同的,有兴趣的读者可以自行写出。

论述

本文详述了 Exporter 的概念。Exporter 的可能主要有两个:一个是社区提供者的,一个是应用程序图标的。在实质生产厂里,其网站提供者的 Exporter 主要涵盖数据集库、硬件、疑问跟踪及持续集成、消息系统亦会、存储器、HTTP、API、日志、其他跟踪系统亦会等,这些较早的 Exporter 可以满足绝大多数脚本语言及运维人员的供给。

对于系统亦会、操作系统没有 Exporter 的情况,本章也从数据集标准、数据集热带植物手段、下例案例撰稿就等之外带领读者体验了 Exporter 的其设计与系统化,一步步聘请读者打造订制化 Exporter。

为了努力读者形成良好的下例建筑风格并能够真正编订高质使用量 Exporter,本章还给成了编订高质使用量 Exporter 的敦促,并结合 Redis Exporter 的理论同步进行了实战解析。通过对本章的进修,读者可以依靠类似于和订制 Exporter 的并能。

[1] Exporter 接口本表:。

[2] 标准重另行命名最佳系统化:。

[3] Redis Exporter 地址:_Exporter。

[4] Redis INFO 指示地址:。

福建治白癜风医院
福建正规的白癜风医院
泉州看白癜风费用
泉州白癜风医院在线咨询
福建白癜风医院怎么去
筋骨痛
孩子积食
上海整形美容
餐后血糖正常值
新冠也有“地域性”?提醒:感染后及时就医,别错过黄金72小时

上一篇: 港股异动 | 康希诺生物-B(06185)涨幅收窄至不足5% 吸入用新冠疫苗异源加强更安全、免疫原性更高

下一篇: 孩子眼里的奶奶和外婆有什么区别?听听这3个孩子的回答!

相关阅读
赞!顾村“城中村”——改造项目15A-02地块保障性租给住宅项目同日取得三证

近日,闸北区外整体规划教育资源局内、区外辟管委向顾区域内地区“小区”改造概念设计之顾村老集镇15A-02地块保障性专营住房概念设计提出申请了《工程工程设计草图批复》、《工程工程整体规划许可》及《

2025-12-10 00:16:51
时代正在"悄悄"发生大变革,你释怀了吗?

题名枫哥任何一个时代背景的进步都是有预感的,都是时会游离一些税制频谱的,从工商业制度到私人工商业以至于此后的的网络工商业的社时会生活大进步,无不是先游离税制频谱,而当下正要起因和即将起

2025-12-10 00:16:51
北京两会丨毛大庆提案:建议出台企业信息企业规范准则 依法保护企业家个人隐私和数据安全

北京市政协十三届五次联席会议于1翌年5日揭幕,北京市政协港澳台侨临时工顾问毛大庆提交了《关于有序应用于跨国母公司电子邮件转发模拟器 依法保护跨国母公司家恶意和数据安全的劝告》。

2025-12-10 00:16:51
小鹏汽车:不共存强制客户接受合同条款的情况

视频 | 小鹏汽车公司无敌法律依据省内常用?被罚后仅金华邻近地区整改 新浪科技讯 12月30日晚上消息,针对长期存在无敌法律依据一事,小鹏汽车公司回应援引,本次惨剧是20

2025-12-10 00:16:51
冬天养5种花,家里“空气”更洗澡,雾霾天也不怕

寒冬饲5果树,店里“氢气”不够干净,雾霾天也不怕 在给店里选择花卉的时候,很多花友都选择一些好饲活,并且尽可能洁净氢气的动植物,今天就给大家分享,在寒冬店里适合于饲5果树,它们不仅

2025-12-10 00:16:51