go-metrics源码分析

本文详细分析了go-metrics库,包括MetricsSink接口及其实现如StatsiteSink、StatsdSink、PrometheusSink和InmemSink。重点讨论了StatsiteSink的TCP连接与数据推送,InmemSink的数据结构与操作,以及如何在接收到信号时打印InmemSink信息。此外,还介绍了go-metrics在实际应用中的配置和使用,包括启用RuntimeMetrics进行运行时性能监控。

本文公众号文章链接:https://mp.weixin.qq.com/s/d-HTKCldEn4CSdQU0uqd6w

本文csdn博客文章链接:https://blog.youkuaiyun.com/screscent/article/details/79759481

 

 

go-metrics是一个go语言的metrics库。其README中说的为:This library provides a metrics package which can be used to instrument code, expose application metrics, and profile runtime performance in a flexible manner.

 

如果不了解说明是metrics的,可以自行去网上搜索看下。

源码目录为

 

 

README中的说明:

通过MetricsSink接口提供了如下库。

  • StatsiteSink : Sinks to a statsite instance (TCP)

  • StatsdSink: Sinks to a StatsD / statsite instance (UDP)

  • PrometheusSink: Sinks to a Prometheus metrics endpoint (exposed via HTTP for scrapes)

  • InmemSink : Provides in-memory aggregation, can be used to export stats

  • FanoutSink : Sinks to multiple sinks. Enables writing to multiple statsite instances for example.

  • BlackholeSink : Sinks to nowhere

那下面进行源码分析:

一、MetricsSink

github.com/armon/go-metrics/sink.go

 

 

 

上面有四种类型的数据Gauge、Emitkey、IncrCounter、AddSample。

 

提供了一个黑洞操作的MetricSink。其实就是空的处理

 

FanoutSink是封装了一个[]MetricSink,接口函数,都是遍历各个MetricSink操作。

 

以上为网络上的提供了三个MetricSink的封装。

 

二、StatsiteSink

github.com/armon/go-metrics/statsite.go

StatsiteSink的结构体很简

在 `hashicorp/go-metrics` 包中,计数器(Counter)通常用于跟踪单调递增的值,例如请求总数或错误次数。默认情况下,该包并没有直接提供“重置”特定计数器的 API,因为计数器的设计初衷是持续累积,而不是周期性清零。 然而,可以通过以下方式实现对特定计数器的重置: 1. **使用 `metrics.Get` 方法获取现有计数器的引用**: 通过 `metrics.Get` 获取当前计数器的实例,然后进行操作。这要求在计数器定义时使用了相同的名称和标签组合。 2. **手动设置计数器的值为零**: 如果使用的是基于 `Prometheus` 的适配器或自定义的指标注册表,可以利用 `Set` 方法将计数器的值显式设置为 0。需要注意的是,标准的 Prometheus 客户端库并不支持直接设置计数器的值,因此可能需要使用 Gauge 来模拟计数器行为。 示例代码如下,假设使用的是支持 `Set` 操作的 Gauge 模拟计数器: ```go import ( "github.com/armon/go-metrics" "github.com/armon/go-metrics/prometheus" ) var ( myCounter = metrics.NewGauge([]string{"my", "counter"}, nil) ) func resetMyCounter() { // 重置特定计数器的值为 0 myCounter.Set(0) } func init() { // 注册 Prometheus 格式的指标 prometheusOpts := prometheus.PrometheusOpts{ EnableExpensiveMetrics: true, } metrics.NewGlobal(&prometheusOpts, nil) } ``` 3. **使用标签区分计数周期**: 另一种常见的做法是通过引入额外的标签(如 `reset_id` 或 `interval`)来区分不同的计数周期,而不是直接重置计数器。这样可以在逻辑上实现“重置”的效果,同时避免对其他计数器造成影响。 例如: ```go metrics.IncrCounterWithLabels([]string{"http", "requests"}, 1, []metrics.Label{ {Name: "reset_id", Value: "2023-10-01"}, }) ``` 4. **使用自定义指标注册表**: 如果需要更细粒度的控制,可以考虑实现自定义的指标注册表,并在其中添加对“重置”操作的支持。这种方式需要对 `metrics` 包的底层接口有较深入的理解,并可能涉及对源码的修改或扩展。 ### 注意事项 - 在使用 `Set` 方法时,应确保目标指标类型支持该操作(如 Gauge),而不是仅适用于计数器(Counter)。 - 重置计数器可能会影响监控系统的告警逻辑或数据聚合逻辑,因此应在设计阶段充分评估其影响。 - 如果使用 Prometheus 作为后端,建议使用 `histogram` 或 `summary` 类型来替代直接的计数器重置操作,以更好地支持长尾问题的分析和处理 [^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值