hashicorp/go-metrics
GitHub: hashicorp/go-metrics
Go 语言运行时性能指标采集库,支持将埋点数据灵活导出至 StatsD、Prometheus 等外部监控系统。
Stars: 1578 | Forks: 189
# go-metrics
该库提供了一个 `metrics` 包,可用于检测代码、
暴露应用指标,并以灵活的方式分析 runtime 性能。
当前 API:[](https://godoc.org/github.com/hashicorp/go-metrics)
## Sinks
* StatsiteSink:输出至 [statsite](https://github.com/statsite/statsite/) 实例 (TCP)
* StatsdSink:输出至 [StatsD](https://github.com/statsd/statsd/) / statsite 实例 (UDP)
* PrometheusSink:输出至 [Prometheus](http://prometheus.io/) 指标 endpoint(通过 HTTP 暴露以供抓取)
* InmemSink:提供内存内聚合,可用于导出统计信息
* FanoutSink:输出至多个 sink。例如,允许写入多个 statsite 实例。
* BlackholeSink:不输出到任何地方
除了 sink 之外,还可以使用 `InmemSignal` 来捕获信号,
并输出近期指标的格式化结果。例如,当进程接收到
SIGUSR1 时,它可以将近期的性能指标输出到 stderr 以供调试。
## Labels
大多数指标都有一个以 `WithLabels` 结尾的等效方法,此类方法
允许推送带有标签的指标,并使用底层 Sink 的某些功能
(例如:转换为 Prometheus 标签)。
由于某些标签可能会增加指标的基数,该
库允许使用一个对所有指标全局生效的允许/阻止列表过滤系统来过滤标签。
* 如果 `Config.AllowedLabels` 不为 nil,则只有该值中指定的标签会被发送到底层 Sink,否则,默认发送所有标签。
* 如果 `Config.BlockedLabels` 不为 nil,则该值中指定的任何标签都不会被发送到底层 Sink。
默认情况下,`Config.AllowedLabels` 和 `Config.BlockedLabels` 均为 nil,这意味着
完全不过滤任何标签,但允许用户在应用层面上全局阻止某些
具有高基数的标签。
## 向后兼容性
该库的 v0.5.0 版本将 Go 模块从 `github.com/armon/go-metrics` 重命名为 `github.com/hashicorp/go-metrics`。
虽然这没有对 API 引入任何破坏性变更,但该变更确实在微妙地破坏了向后兼容性。
本质上,Go 将重命名的模块视为完全不同的独立模块,并且会乐意将这两个模块编译进同一个二进制文件中。
由于 go-metrics 库的大多数用法都涉及通过全局指标处理器发送指标,因此拥有两个全局
指标处理器可能会导致一部分指标直接丢失。举个例子,如果你的应用配置
通过 `armon` 命名空间导出 go-metrics,那么任何通过 `hashicorp` 命名空间模块发送给 go-metrics 的指标
都不会被导出。
最终,所有 `armon/go-metrics` 的用法都应该被替换为 `hashicorp/go-metrics`。然而,在应用可能依赖的所有库中
进行单一时间点的协调更新并不总是可行的。为了方便迁移,
我们引入了一个 `github.com/hashicorp/go-metrics/compat` 包。这个包及其子包与
`armon/go-metrics` 保持 API 兼容。各个库应更新为使用此包来通过全局处理器发送指标。在内部,
该包会将指标路由到 `armon/go-metrics` 或 `hashicorp/go-metrics`。这是在应用的全局层面
通过使用 Go build tag 实现的。
**Build Tag**
* `armonmetrics` - 使用此 tag 会将指标路由到 `armon/go-metrics`
* `hashicorpmetrics` - 使用此 tag 会将所有指标路由到 `hashicorp/go-metrics`
如果未指定 build tag,默认行为是使用 `armon/go-metrics`。整体的迁移路径如下:
1. 升级使用 `armon/go-metrics` 的库,使其改为使用 `hashicorp/go-metrics/compat`。
2. 更新使用 `armon/go-metrics` 的应用所依赖的库。
* 这不需要作为一个庞大的原子更新一次性完成,由于默认行为保持不变,此过程可以相对缓慢地进行。
* 此时,所有指标仍将被发送至 `armon/go-metrics`
3. 更新应用以使用 `hashicorp/go-metrics`
* 将应用中所有 `github.com/armon/go-metrics` 的 import 替换为 `github.com/hashicorp/go-metrics`
* 在此阶段,库不作任何改动。
* 配置你的构建系统以使用 `hashicorpmetrics` tag 进行构建。
你的迁移实际上已经完成,你的应用现在已专门使用 `hashicorp/go-metrics`。该库的未来版本
将更改默认行为,以使用 `hashicorp/go-metrics` 替代 `armon/go-metrics`。届时,任何
在执行迁移前需要更多时间的应用,都必须配置其构建系统以包含 `armonmetrics` tag。此后的
后续版本最终将彻底移除兼容层。大致的时间表为:2025 年中期更改默认
行为,然后在 2025 年底移除兼容层。
## 示例
以下是使用该包的一个示例:
```
func SlowMethod() {
// Profiling the runtime of a method
defer metrics.MeasureSince([]string{"SlowMethod"}, time.Now())
}
// Configure a statsite sink as the global metrics sink
sink, _ := metrics.NewStatsiteSink("statsite:8125")
metrics.NewGlobal(metrics.DefaultConfig("service-name"), sink)
// Emit a Key/Value pair
metrics.EmitKey([]string{"questions", "meaning of life"}, 42)
```
以下是设置信号处理器的示例:
```
// Setup the inmem sink and signal handler
inm := metrics.NewInmemSink(10*time.Second, time.Minute)
sig := metrics.DefaultInmemSignal(inm)
metrics.NewGlobal(metrics.DefaultConfig("service-name"), inm)
// Run some code
inm.SetGauge([]string{"foo"}, 42)
inm.EmitKey([]string{"bar"}, 30)
inm.IncrCounter([]string{"baz"}, 42)
inm.IncrCounter([]string{"baz"}, 1)
inm.IncrCounter([]string{"baz"}, 80)
inm.AddSample([]string{"method", "wow"}, 42)
inm.AddSample([]string{"method", "wow"}, 100)
inm.AddSample([]string{"method", "wow"}, 22)
....
```
当接收到信号时,类似以下的内容将被输出到 stderr:
```
[2014-01-28 14:57:33.04 -0800 PST][G] 'foo': 42.000
[2014-01-28 14:57:33.04 -0800 PST][P] 'bar': 30.000
[2014-01-28 14:57:33.04 -0800 PST][C] 'baz': Count: 3 Min: 1.000 Mean: 41.000 Max: 80.000 Stddev: 39.509
[2014-01-28 14:57:33.04 -0800 PST][S] 'method.wow': Count: 3 Min: 22.000 Mean: 54.667 Max: 100.000 Stddev: 40.513
```
标签:EVTX分析, Go, Ruby工具, StatsD, 开发库, 性能监控, 指标采集, 日志审计, 自定义请求头, 运维监控