Go 标准库增加metrics指标探讨分析

 更新时间:2023年10月11日 14:19:54   作者:煎鱼  
go中有一个神奇的标准库 runtime/metrics,提供了一系列预定义好的 Go 自身的相关指标,如果没有编写过基础监控库或者关注的比较少的朋友可能会没接触到这类指标,本文展开现有metrics 指标,并结合现有的社区讨论一起看看还有没有必要增加更多的标准库指标

快速了解 runtime/metrics

以下是一个快速 Demo。代码如下:

func main() {
    descs := metrics.All()
    samples := make([]metrics.Sample, len(descs))
    for i := range samples {
        samples[i].Name = descs[i].Name
    }
    metrics.Read(samples)
    for _, sample := range samples {
        name, value := sample.Name, sample.Value
        switch value.Kind() {
        case metrics.KindUint64:
            fmt.Printf("%s: %d\n", name, value.Uint64())
        case metrics.KindFloat64:
            fmt.Printf("%s: %f\n", name, value.Float64())
        case metrics.KindFloat64Histogram:
            fmt.Printf("%s: %f\n", name, medianBucket(value.Float64Histogram()))
         ...
        }
    }
}
func medianBucket(h *metrics.Float64Histogram) float64 {
    total := uint64(0)
    for _, count := range h.Counts {
        total += count
    }
    thresh := total / 2
    total = 0
    for i, count := range h.Counts {
        total += count
        if total >= thresh {
            return h.Buckets[i]
        }
    }
    panic("should not happen")
}

输出结果:

/cgo/go-to-c-calls:calls: 0
/cpu/classes/gc/mark/assist:cpu-seconds: 0.000000
/cpu/classes/gc/mark/dedicated:cpu-seconds: 0.000000
...
/gc/cycles/automatic:gc-cycles: 0
/gc/cycles/forced:gc-cycles: 0
/gc/cycles/total:gc-cycles: 0
/gc/gogc:percent: 100
/gc/gomemlimit:bytes: 9223372036854775807
/gc/heap/allocs-by-size:bytes: 8193.000000
/gc/heap/allocs:bytes: 56832
/gc/heap/allocs:objects: 6
/gc/heap/frees-by-size:bytes: 1.000000
/gc/heap/frees:bytes: 0
/gc/heap/frees:objects: 0
/gc/heap/goal:bytes: 4194304
...

里面包含了相当多的 Go 系统指标。完整的代码运行和输出可以查看 https://go.dev/play/p/CKASbysqX9x

我梳理了一张对照清单。其中 10 个指标如下:

序号指标含义
1/cgo/go-to-c-calls:calls当前进程从 Go 调用到 C 的次数
2/cpu/classes/gc/mark/assist:cpu-seconds预计执行 GC 程序所花费的 CPU 总时长,以协助 GC 并防止其落后于应用程序
3/cpu/classes/gc/mark/dedicated:cpu-seconds在专门用于执行 GC 任务的 CPU 处理器(根据 GOMAXPROCS 的定义)上执行 GC 任务预计需要花费的 CPU 总时长
4/cpu/classes/gc/mark/idle:cpu-seconds在空闲 CPU 资源上执行 GC 任务所花费的 CPU 总时间
5/cpu/classes/gc/pause:cpu-secondsGC 暂停应用程序预计所花费的 CPU 总时长
6/gc/cycles/automatic:gc-cyclesGo Runtime 程序已完成的 GC 循环次数。
7/gc/gogc:percent用户配置的堆大小目标百分比
8/gc/heap/allocs:objects应用程序触发的堆分配累计计数
9/memory/classes/heap/free:bytesGo Runtime 对物理内存的可用空间大小的预估(完全空闲并可返回底层系统但尚未返回的内存)
10/sched/gomaxprocs:threads当前 runtime.GOMAXPROCS 的值,或是可以同时执行用户级 Go 代码的操作系统线程数。

对于完整指标有兴趣的可以查看:

https://pkg.go.dev/runtime/metrics#hdr-Supported_metrics

更多的 metrics 指标

最近在 Go 社区中有同学发起了一项讨论《metrics for the standard library》,希望探讨和在其他标准库中添加更多的 metrics 指标,提供更多的可观察性。

比较多同学期望的是网络、延迟类的指标,针对性能、错误等。如下几种场景:

net/http 服务端:

  • 处理延迟。
  • 请求/响应体大小。
  • 恐慌(panic)、恢复(recover)。
  • 错误/警告(触发 net/http.Server.ErrorLog 的所有内容)
  • 被拒绝的无效请求。

net/http 客户端:

  • 调用延迟。
  • 请求/响应体大小
  • 连接池相关。

database/sql 客户端:

  • 查询延迟。
  • 响应大小。
  • 连接池相关。

net 网络包相关:

  • 例如 TCP、UDP 等,对应的打开连接的数量、连接状态(空闲、激活、关闭)、连接错误等。
  • 例如 TLS,在握手阶段相关的指标,握手持续时间、握手失败计数等。

总结

整体上会发现大家对于 Go 标准库的指标诉求,更多的趋向于底层包。因为无论你用的是什么开源仓库,其绝大部分都是基于上述提到的包。

在现阶段,如果自己的 Go 业务应用程序去记录这些指标,就需要再封装一层,每一个包,例如:ORM 就需要去实现一遍插件等。

而第三方库实现不会把 metrics 这类非核心功能直接加入初始化实现中。因此官方标准库对 metrics 的支持是非常有必要的。

至少这样就不用每个团队都搞一遍 net/http、database/sql 等的延迟调用指标的配置和设置了。

以上就是Go 标准库增加metrics指标探讨分析的详细内容,更多关于Go 标准库metrics指标的资料请关注脚本之家其它相关文章!

相关文章

  • Golang中如何实现枚举详析

    Golang中如何实现枚举详析

    举就是将数据值一一列出来,枚举可以用来表示一些固定的值,枚举是常量组成的,下面这篇文章主要给大家介绍了关于Golang中如何实现枚举的相关资料,需要的朋友可以参考下
    2022-07-07
  • 探索Go语言中的switch高级用法

    探索Go语言中的switch高级用法

    在Go语言中,switch语句除了常见的用法外,还有一种不常用但有趣的写法,这种写法中,switch后面不跟任何表达式,而每个case后面跟的是返回bool类型的函数调用表达式,这实际上是一个等价于switch true的用法,通过从上到下逐一比较case后的表达式是否为true来决定执行哪个分支
    2024-10-10
  • GO使用Mutex确保并发程序正确性详解

    GO使用Mutex确保并发程序正确性详解

    这篇文章主要为大家介绍了GO使用Mutex确保并发程序正确性详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • Go语言连接MySQL数据库执行基本的增删改查

    Go语言连接MySQL数据库执行基本的增删改查

    在后端开发中,MySQL 是最常用的关系型数据库之一,本文主要为大家详细介绍了如何使用 Go 连接 MySQL 数据库并执行基本的增删改查吧
    2025-08-08
  • 使用Golang快速构建出命令行应用程序

    使用Golang快速构建出命令行应用程序

    在日常开发中,大家对命令行工具(CLI)想必特别熟悉了,如果说你不知道命令工具,那你可能是个假开发。每天都会使用大量的命令行工具,例如最常用的Git、Go、Docker等,这篇文章主要介绍了使用Golang快速构建出命令行应用程序,需要的朋友可以参考下
    2023-02-02
  • 使用Go语言实现HTTP客户端请求并解析响应的完整流程

    使用Go语言实现HTTP客户端请求并解析响应的完整流程

    在日常开发中,无论是调用 RESTful API、采集网页数据,还是进行微服务之间的通信,HTTP 客户端几乎无处不在,本文聚焦于如何使用 Go 实现一个 HTTP 客户端,完成请求发送、响应解析、错误处理、Header与Body提取等完整流程,需要的朋友可以参考下
    2025-08-08
  • go语言语法基础的全面梳理(适合入门)

    go语言语法基础的全面梳理(适合入门)

    这篇文章主要介绍了go语言语法基础的相关资料,从基础语法到并发编程,涵盖变量声明、数据类型、流程控制、函数、接口、错误处理及并发编程,全面覆盖Go语言核心特性,需要的朋友可以参考下
    2026-06-06
  • Go语言非main包编译为静态库并使用的示例代码

    Go语言非main包编译为静态库并使用的示例代码

    本文以Windows为例,介绍一下如何将Go的非main包编译为静态库,用户又将如何使用。通过实际项目创建常规工程,通过示例代码给大家介绍的非常详细,需要的朋友参考下吧
    2021-07-07
  • Golang实现单元测试中的逻辑层

    Golang实现单元测试中的逻辑层

    前面我们完成了最麻烦的数据层的单元测试,今天我们来看看单元测试中最容易做的一层,数据逻辑层,也就是我们通常说的 service 或者 biz 等
    2023-03-03
  • Go语言中实现多线程定时任务的示例代码

    Go语言中实现多线程定时任务的示例代码

    本文主要介绍了Go语言中实现多线程定时任务的示例代码,使用goroutine和channel实现轻量级线程及通信,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-09-09

最新评论