Golang 监控全局变量

前言

你是否曾经遇到过这样的情况,在开发环境排查问题,因为一些数据保存在了一些全局变量中,这些变量往往是一个 map 或者是一个数组,想看看在运行过程中,这里面究竟存放了什么数据,有时不得不在运行的时候将它输出到日志中,那么如果我想实时看到这些数据的情况又怎么办呢?

其实 golang 中已经存在这样的库,就是来做这个事情的 expvar

使用案例

废话不多数,直接上案例

package main

import (
    "expvar"
    "net/http"
)

var (
    s    map[string]string
    user User
)

type User struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

func showMap() interface{} {
    return s
}

func showUser() interface{} {
    return user
}

func main() {
    user.Name = "tom"
    user.Age = 18
    s = make(map[string]string, 10)
    s["1"] = "111"
    s["2"] = "222"
    expvar.Publish("a_map", expvar.Func(showMap))
    expvar.Publish("b_user", expvar.Func(showUser))
    http.HandleFunc("/test", func(writer http.ResponseWriter, request *http.Request) {
        s["3"] = "333"
    })
    http.ListenAndServe(":8080", nil)
}

监控变量

直接访问 http://127.0.0.1:8080/debug/vars 你就能看到一个 json 格式的返回数据,数据如下所示:

{
  "a_map": {
    "1": "111",
    "2": "222"
  },
  "b_user": {
    "name": "tom",
    "age": 18
  },
  "cmdline": [
    "/private/var/folders/37/qpz6_ndd1w72bhrg2sgg042r0000gn/T/___go_build_go_demo_vars"
  ],
  "memstats": {
    "Alloc": 188992,
    "TotalAlloc": 188992,
    "Sys": 70453248,
    "Lookups": 0,
    "Mallocs": 818,
    "Frees": 21,
    "HeapAlloc": 188992,
    "HeapSys": 66650112,
    "HeapIdle": 65716224,
    "HeapInuse": 933888,
    "HeapReleased": 65683456,
    "HeapObjects": 797,
    "StackInuse": 458752,
    "StackSys": 458752,
    "MSpanInuse": 15776,
    "MSpanSys": 16384,
    "MCacheInuse": 6944,
    "MCacheSys": 16384,
    "BuckHashSys": 2638,
    "GCSys": 2240512,
    "OtherSys": 1068466,
    "NextGC": 4473924,
    "LastGC": 0,
    "PauseTotalNs": 0,
    ......
  }
}

这里面一方面将你的在代码中全局变量显示了出来还有个 cmdlinememstats 这个我们后面再说

这是你可以访问一次 http://127.0.0.1:8080/test 然后再回来看看,就会发现变量的值以及改变,说明这个变量显示的是实时的

监控原理

其实原理非常简单,你自己都能写,下面就是源码中的一部分

// Handler returns the expvar HTTP Handler.
//
// This is only needed to install the handler in a non-standard location.
func Handler() http.Handler {
    return http.HandlerFunc(expvarHandler)
}

func cmdline() interface{} {
    return os.Args
}

func memstats() interface{} {
    stats := new(runtime.MemStats)
    runtime.ReadMemStats(stats)
    return *stats
}

func init() {
    http.HandleFunc("/debug/vars", expvarHandler)
    Publish("cmdline", Func(cmdline))
    Publish("memstats", Func(memstats))
}

其实就是在 init 的时候注册了对应的路由,还注册了 cmdline 和 memstats 两个值,这两个值很有用:

  • cmdline 展示了当前启动时通过命令行传递的参数是什么
  • memstats 展示了当前运行时内存的使用情况,还有 gc 的部分信息等等

其他方法

https://golang.org/pkg/expvar/

当然这个包不止有 Publish 方法,还有 Add、Set 等等,个人最常用的还是 Publish

监控内存并展示

既然 expvar 暴露了内存的使用情况,那我们当然能利用这个信息来作图了,所以就推荐一个很好用的库

https://github.com/rs/jplot

安装之后,就可以用命令通过之前的接口来监控内存等使用情况咯

jplot --url http://127.0.0.1:8080/debug/vars \
    memstats.HeapSys+memstats.HeapAlloc+memstats.HeapIdle+marker,counter:memstats.NumGC \
    counter:memstats.TotalAlloc \
    memstats.HeapObjects \
    memstats.StackSys+memstats.StackInuse

我觉得这样的使用方式在本地和开发环境的时候测试更加轻量,不用部署一些监控软件,即开即测;当然线上环境肯定会有 prometheus + grafana 这样的监控神器,这里也只是抛个砖头。

总结

如果线上需要监控一些全局变量的使用情况可以考虑使用 expvar 进行监控和查看,或者用它来监控你的配置文件或者一些任务数量等等也是一个不错的选择。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269