Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > go expvar

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

作者:虚拟之

Go语言的expvar标准库是专为暴露程序内部指标设计的轻量级监控工具,支持通过HTTP接口以JSON格式实时查看运行状态,本文就来详细的介绍一下go语言标准库expvar监控工具的实现,感兴趣的可以了解一下

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

一、基础功能说明

import "expvar"

二、基础类型使用示例

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内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文