go语言标准库expvar监控工具的实现

 更新时间:2026年04月22日 15:00:29   作者:虚拟之  
Go语言的expvar标准库是专为暴露程序内部指标设计的轻量级监控工具,支持通过HTTP接口以JSON格式实时查看运行状态,本文就来详细的介绍一下go语言标准库expvar监控工具的实现,感兴趣的可以了解一下

Go语言的expvar标准库是专为暴露程序内部指标设计的轻量级监控工具,支持通过HTTP接口以JSON格式实时查看运行状态。

一、基础功能说明

import "expvar"
  • 核心机制:内置/debug/vars端点,自动导出注册变量
  • 变量类型:支持Int/Float/String/Map/自定义类型
  • 线程安全:内置原子操作保证并发安全
  • 扩展能力:支持注册函数型变量

二、基础类型使用示例

1. 基础计数器

var counter = expvar.NewInt("requests")
func handler(w http.ResponseWriter, r *http.Request) {
    counter.Add(1)
    fmt.Fprintf(w, "Hello World")
}
func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

测试命令:

curl http://localhost:8080/debug/vars | jq .requests

输出示例:

{ "requests": 158 }

2. 温度监控浮点数

temp := expvar.NewFloat("temperature")
temp.Set(26.5)
// 更新温度
temp.Add(0.5)

输出结果:

{ "temperature": 27.0 }

3. 版本信息字符串

version := expvar.NewString("version")
version.Set("v1.2.3")

输出展示:

{ "version": "v1.2.3" }

三、复合数据结构

4. Map结构统计

stats := expvar.NewMap("http")
stats.Set("requests", expvar.NewInt("total"))
stats.Set("errors", expvar.NewInt("count"))

stats.Get("requests").(*expvar.Int).Add(1)

输出结构:

{
  "http": {
    "requests": 42,
    "errors": 3
  }
}

5. 嵌套Map结构

dbStats := expvar.NewMap("database")
connStats := expvar.NewMap("connections")
dbStats.Set("mysql", connStats)
connStats.Set("open", expvar.NewInt("count"))
connStats.Set("max", expvar.NewInt("limit"))

输出结果:

{
  "database": {
    "mysql": {
      "open": 10,
      "max": 100
    }
  }
}

四、高级功能示例

6. 自定义结构体导出

type ServerStatus struct {
    Connections int
    mu          sync.Mutex
}
func (s *ServerStatus) String() string {
    s.mu.Lock()
    defer s.mu.Unlock()
    return fmt.Sprintf(`{"connections": %d}`, s.Connections)
}
status := &ServerStatus{}
expvar.Publish("server", status)
// 修改状态
status.mu.Lock()
status.Connections = 25
status.mu.Unlock()

输出结果:

{ "server": { "connections": 25 } }

7. 函数型变量

expvar.Publish("uptime", expvar.Func(func() interface{} {
    return time.Since(startTime).Seconds()
}))

动态输出:

{ "uptime": 3600.25 }

8. 原子计数器

var memStats expvar.Int
memStats.Set(1024)
go func() {
    for {
        atomic.AddInt64(&memStats.Value, 100)
        time.Sleep(time.Second)
    }
}()

持续增长的输出:

{ "memStats": 2024 }

五、系统级监控

9. 内存统计

expvar.Publish("memstats", expvar.Func(func() interface{} {
    var m runtime.MemStats
    runtime.ReadMemStats(&m)
    return m
}))

输出样例:

{
  "memstats": {
    "Alloc": 1024000,
    "TotalAlloc": 2048000,
    ...
  }
}

10. Goroutine计数

expvar.NewInt("goroutines").Set(int64(runtime.NumGoroutine()))

六、生产级应用

11. 动态配置中心

var config = expvar.NewMap("config")
config.Set("timeout", expvar.NewInt("seconds"))
config.Get("timeout").(*expvar.Int).Set(30)
// 动态修改配置
config.Get("timeout").(*expvar.Int).Set(60)

12. 实时QPS计算

var (
    totalRequests expvar.Int
    lastCheck     = time.Now()
)
expvar.Publish("qps", expvar.Func(func() interface{} {
    now := time.Now()
    interval := now.Sub(lastCheck).Seconds()
    qps := float64(totalRequests.Value()) / interval
    lastCheck = now
    totalRequests.Set(0)
    return qps
}))

13. 数据库连接池监控

dbConn := expvar.NewMap("db_connections")
dbConn.Set("open", expvar.NewInt("current"))
dbConn.Set("wait", expvar.NewInt("queued"))

// 连接获取时
dbConn.Get("open").(*expvar.Int).Add(1)
// 连接释放时
dbConn.Get("open").(*expvar.Int).Add(-1)

七、最佳实践建议

  1. 命名规范:使用service_metric的层级命名方式
  2. 性能考量:高频更新指标建议使用原子操作
  3. 安全防护:生产环境建议添加访问鉴权
  4. 数据聚合:结合Prometheus等工具进行可视化

八、完整示例程序

package main

import (
    "expvar"
    "fmt"
    "net/http"
    "runtime"
    "sync/atomic"
    "time"
)

func main() {
    // 基本计数器
    reqCounter := expvar.NewInt("http_requests")
  
    // 复合指标
    serviceStats := expvar.NewMap("service")
    serviceStats.Set("start_time", expvar.NewString(time.Now().Format(time.RFC3339)))
    serviceStats.Set("uptime", expvar.Func(func() interface{} {
        return time.Since(startTime).Seconds()
    }))

    // 自定义结构体
    type HealthStatus struct {
        Healthy bool `json:"healthy"`
    }
    expvar.Publish("health", expvar.Func(func() interface{} {
        return &HealthStatus{Healthy: true}
    }))

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        reqCounter.Add(1)
        w.Write([]byte("OK"))
    })

    go func() {
        for {
            atomic.AddInt64(&reqCounter.Value, 1)
            time.Sleep(time.Second)
        }
    }()

    fmt.Println("Server running at :8080")
    http.ListenAndServe(":8080", nil)
}

该示例整合了多种expvar用法,通过以下命令查看完整指标:

curl http://localhost:8080/debug/vars | jq .

输出将包含:

{
  "http_requests": 42,
  "service": {
    "start_time": "2023-09-15T12:34:56Z",
    "uptime": 3600.25
  },
  "health": {
    "healthy": true
  }
}

到此这篇关于go语言标准库expvar监控工具的实现的文章就介绍到这了,更多相关go expvar内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 深入了解Go语言编译链接的过程

    深入了解Go语言编译链接的过程

    Go在编译时会将interface和channel关键字转换成runtime中的结构和函数调用,所以小编觉得很有必要就Go的编译过程理一理做个进行总结,下面就来和小编一起了解一下Go语言编译链接的过程吧
    2023-08-08
  • 深入探讨Golang中如何进行并发发送HTTP请求

    深入探讨Golang中如何进行并发发送HTTP请求

    在 Golang 领域,并发发送 HTTP 请求是优化 Web 应用程序的一项重要技能,本文探讨了实现此目的的各种方法,文中的示例代码讲解详细,希望对大家有所帮助
    2024-01-01
  • 详解golang 定时任务time.Sleep和time.Tick实现结果比较

    详解golang 定时任务time.Sleep和time.Tick实现结果比较

    本文主要介绍了golang 定时任务time.Sleep和time.Tick实现结果比较,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • Go使用chan或context退出协程示例详解

    Go使用chan或context退出协程示例详解

    这篇文章主要为大家介绍了Go使用chan或context退出协程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • 详解如何在Golang中实现CORS(跨域)

    详解如何在Golang中实现CORS(跨域)

    很多时候,需要允许Web应用程序在不同域之间(跨域)实现共享资源,本文将简介跨域、CORS的概念,以及如何在Golang中如何实现CORS,文中有详细的示例代码,需要的朋友可以参考下
    2023-10-10
  • 10个现代网站开发必备的Go软件包工具盘点

    10个现代网站开发必备的Go软件包工具盘点

    这篇文章主要为大家介绍了10个现代网站开发必备的Go软件包,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • golang 并发安全Map以及分段锁的实现方法

    golang 并发安全Map以及分段锁的实现方法

    这篇文章主要介绍了golang 并发安全Map以及分段锁的实现方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-03-03
  • Go语言实现JSON解析的神器详解

    Go语言实现JSON解析的神器详解

    php转go是大趋势,越来越多公司的php服务都在用go进行重构,重构过程中,会发现php的json解析操作是真的香。本文和大家分享了一个Go语言实现JSON解析的神器,希望对大家有所帮助
    2023-01-01
  • golang log4go的日志输出优化详解

    golang log4go的日志输出优化详解

    log4go源于google的一项log工程,但官方已经停止维护更新,下面这篇文章主要给大家介绍了关于golang log4go的日志输出优化的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-12-12
  • 深入理解golang中io.Writer接口的使用

    深入理解golang中io.Writer接口的使用

    io 是一个 Golang 标准库包,它为围绕输入和输出的许多操作和用例定义了灵活的接口,这篇文章主要为大家介绍了Go中Writer接口的使用,需要的可以参考下
    2023-10-10

最新评论