gops —— Go 程序诊断分析工具

简介: GitHub: https://github.com/google/gops 一个用于列出和诊断分析系统中正在运行的 Go 程序的命令行工具 安装 1 go get -u github.

GitHub: https://github.com/google/gops

一个用于列出和诊断分析系统中正在运行的 Go 程序的命令行工具

安装

go get -u github.com/google/gops

命令帮助

执行 gops help 查看帮助文档:

gops is a tool to list and diagnose Go processes.


	gops <cmd> <pid|addr> ...


	gops <pid> # displays process info


Commands:


stack       	Prints the stack trace.


gc          	Runs the garbage collector and blocks until successful.


setgc	        Sets the garbage collection target percentage.


memstats    	Prints the allocation and garbage collection stats.


version     	Prints the Go version used to build the program.


stats       	Prints the vital runtime stats.


help        	Prints this help text.


Profiling commands:


trace       	Runs the runtime tracer for 5 secs and launches "go tool trace".


pprof-heap  	Reads the heap profile and launches "go tool pprof".


pprof-cpu   	Reads the CPU profile and launches "go tool pprof".


All commands require the agent running on the Go process.


Symbol "*" indicates the process runs the agent.

使用详解

为了能更好的分析程序,需要在我们的项目中加一行 agent 诊断分析代码,用于统计分析程序问题。

package main


import (


	"log"


	"time"


	"github.com/google/gops/agent"


)


func main() {


	if err := agent.Listen(agent.Options{}); err != nil {


		log.Fatal(err)


	}


	time.Sleep(time.Hour)


}

其中,agent. 支持更多的参数:

// Code reference: github.com/google/gops/agent/agent.go:42


// Options allows configuring the started agent.


type Options struct {


	// Addr is the host:port the agent will be listening at.


	// Optional.


	Addr string


	// ConfigDir is the directory to store the configuration file,


	// PID of the gops process, filename, port as well as content.


	// Optional.


	ConfigDir string


	// ShutdownCleanup automatically cleans up resources if the


	// running process receives an interrupt. Otherwise, users


	// can call Close before shutting down.


	// Optional.


	ShutdownCleanup bool


}

●  Addr

可选。为远程分析服务提供监听地址,例如: :9119。配置了该项,那我们可以在本机查看分析远程服务器上的 Go 程序,非常有帮助。

 ●  ConfigDir

可选。用于存放统计数据和配置的目录,默认为当前用户的主目录。也可以通过环境变量GOPS_CONFIG_DIR设置。具体参考代码:

const gopsConfigDirEnvKey = "GOPS_CONFIG_DIR"


func ConfigDir() (string, error) {


	if configDir := os.Getenv(gopsConfigDirEnvKey); configDir != "" {


		return configDir, nil


	}


	if runtime.GOOS == "windows" {


		return filepath.Join(os.Getenv("APPDATA"), "gops"), nil


	}


	homeDir := guessUnixHomeDir()


	if homeDir == "" {


		return "", errors.New("unable to get current user home directory: os/user lookup failed; $HOME is empty")


	}


	return filepath.Join(homeDir, ".config", "gops"), nil


}


func guessUnixHomeDir() string {


	usr, err := user.Current()


	if err == nil {


		return usr.HomeDir


	}


	return os.Getenv("HOME")


}

 ●  ShutdownCleanup

可选。设置为 true,则在程序关闭时会自动清理数据。

NOTE: 如果不加 agent 代码,那我们无法更深入的诊断程序,也就是说无法执行gops memstatsgops pprof-heap等所有类似于 gops <cmd> <pid|addr> ... 的子命令。

gops

直接执行 gops 命令会列出本机所有正在运行的 Go 程序。

$ gops


99288 47636 go    go1.10.1 /usr/local/Cellar/go/1.10.1/libexec/bin/go


99300 99288 main* go1.10.1 /private/var/folders/cs/mfl4k8t54_g1thdzvzkdxbbr0000gn/T/go-build375822490/b001/exe/main


99570 2899  gops  go1.10.1 /Users/shocker/gowork/bin/gops


99154 14655 hugo  go1.11.1 /usr/local/Cellar/hugo/0.49.1/bin/hugo

该命令会显示以下内容:

 ●  PID
 ●  PPID
 ●  程序名称
 ●  构建该程序的 Go 版本号
 ●  程序所在绝对路径

注意,列表中有个程序名称后面带了个 *,表示该程序加入了 gops 的诊断分析代码。

gops <pid>

用法: gops <pid> 查看本机指定 PID Go 程序的基本信息

$ gops 99300


parent PID:	99288


threads:	11


memory usage:	0.157%


cpu usage:	0.013%


username:	shocker


cmd+args:	/var/folders/cs/mfl4k8t54_g1thdzvzkdxbbr0000gn/T/go-build375822490/b001/exe/main


local/remote:	*:9105 <-> :0 (LISTEN)


local/remote:	127.0.0.1:57109 <-> 127.0.0.1:3306 (ESTABLISHED)


local/remote:	*:8000 <-> :0 (LISTEN)

local/remote 表示本机建立的监听(LISTEN),或者与远程服务器建立的链接(ESTABLISHED)

local/remote: *:9105 <-> :0 (LISTEN) 中的 *:9105 是 gops/agent 提供的服务,

gops tree

用法: gops tree 以目录树的形式展示所有 Go 程序。

$ gops tree


...


├── 2899


│   └── 99996 (gops) {go1.10.1}


├── 47636


│   └── 99288 (go) {go1.10.1}


│       └── [*]  99300 (main) {go1.10.1}


└── 14655


└── 99154 (hugo) {go1.11.1}

gops stack (<pid>|<addr>)

用法: gops stack (<pid>|<addr>) 用于显示程序所有堆栈信息,包括每个 goroutine 的堆栈信息、运行状态、运行时长等。

$ gops stack 99300


goroutine 7 [running]:


runtime/pprof.writeGoroutineStacks(0x1882720, 0xc4202b8010, 0xd0, 0xd0)


	/usr/local/Cellar/go/1.10.1/libexec/src/runtime/pprof/pprof.go:650 +0xa7


runtime/pprof.writeGoroutine(0x1882720, 0xc4202b8010, 0x2, 0x30, 0xc420068248)


	/usr/local/Cellar/go/1.10.1/libexec/src/runtime/pprof/pprof.go:639 +0x44


goroutine 1 [IO wait, 9 minutes]:


internal/poll.runtime_pollWait(0x1db4da0, 0x72, 0x0)


	/usr/local/Cellar/go/1.10.1/libexec/src/runtime/netpoll.go:173 +0x57


internal/poll.(*pollDesc).wait(0xc4201e7318, 0x72, 0x0, 0x0, 0x0)


# more ...

gops memstats (<pid>|<addr>)

用法: gops memstats (<pid>|<addr>) 查看程序的内存统计信息

$ gops memstats 127.0.0.1:9105


alloc: 1.36MB (1428632 bytes)


total-alloc: 10.21MB (10709376 bytes)


sys: 9.07MB (9509112 bytes)


lookups: 91


mallocs: 102818


frees: 91896


heap-alloc: 1.36MB (1428632 bytes)


heap-sys: 5.22MB (5472256 bytes)


heap-idle: 2.34MB (2457600 bytes)


heap-in-use: 2.88MB (3014656 bytes)


heap-released: 0 bytes


heap-objects: 10922


stack-in-use: 704.00KB (720896 bytes)


stack-sys: 704.00KB (720896 bytes)


stack-mspan-inuse: 47.95KB (49096 bytes)


stack-mspan-sys: 80.00KB (81920 bytes)


stack-mcache-inuse: 6.78KB (6944 bytes)


stack-mcache-sys: 16.00KB (16384 bytes)


other-sys: 1.21MB (1266624 bytes)


gc-sys: 492.00KB (503808 bytes)


next-gc: when heap-alloc >= 4.00MB (4194304 bytes)


last-gc: 2018-10-18 13:37:04.37511973 +0800 CST


gc-pause-total: 9.209158ms


gc-pause: 52831


num-gc: 60


enable-gc: true


debug-gc: false

gops gc (<pid>|<addr>)

用法: gops gc (<pid>|<addr>) 查看指定程序的垃圾回收(GC)信息

gops setgc (<pid>|<addr>)

用法: gops setgc (<pid>|<addr>) 设定指定程序的 GC 目标百分比

gops version (<pid>|<addr>)

用法: gops version (<pid>|<addr>) 查看指定程序构建时的 Go 版本号

gops stats (<pid>|<addr>)

用法: gops stats (<pid>|<addr>) 查看指定程序的 goroutine 数量、GOMAXPROCS 值等信息

$ gops stats 127.0.0.1:9105


goroutines: 11


OS threads: 14


GOMAXPROCS: 4


num CPU: 4

gops pprof-cpu (<pid>|<addr>)

用法: gops pprof-cpu (<pid>|<addr>) 调用并展示 go tool pprof 工具中关于 CPU 的性能分析数据,操作与 pprof 一致。

$ gops pprof-cpu 99300


Profiling CPU now, will take 30 secs...


Profile dump saved to: /var/folders/cs/mfl4k8t54_g1thdzvzkdxbbr0000gn/T/profile881383738


Profiling dump saved to: /var/folders/cs/mfl4k8t54_g1thdzvzkdxbbr0000gn/T/profile881383738


Binary file saved to: /var/folders/cs/mfl4k8t54_g1thdzvzkdxbbr0000gn/T/binary970030929


File: binary970030929


Type: cpu


Time: Oct 18, 2018 at 2:43pm (CST)


Duration: 30s, Total samples = 0


Entering interactive mode (type "help" for commands, "o" for options)


(pprof)

gops pprof-heap (<pid>|<addr>)

用法: gops pprof-heap (<pid>|<addr>) 调用并展示 go tool pprof 工具中关于 heap 的性能分析数据,操作与 pprof 一致。

$ gops pprof-heap 99300


Profile dump saved to: /var/folders/cs/mfl4k8t54_g1thdzvzkdxbbr0000gn/T/profile045800436


Profiling dump saved to: /var/folders/cs/mfl4k8t54_g1thdzvzkdxbbr0000gn/T/profile045800436


Binary file saved to: /var/folders/cs/mfl4k8t54_g1thdzvzkdxbbr0000gn/T/binary315133123


File: binary315133123


Type: inuse_space


Time: Oct 18, 2018 at 2:46pm (CST)


Entering interactive mode (type "help" for commands, "o" for options)


(pprof)

gops trace (<pid>|<addr>)

用法: gops trace (<pid>|<addr>) 追踪程序运行5秒,生成可视化报告,并可在浏览器中查看: http://127.0.0.1:61380

$ gops trace 99300


Tracing now, will take 5 secs...


Trace dump saved to: /var/folders/cs/mfl4k8t54_g1thdzvzkdxbbr0000gn/T/trace136310737


2018/10/18 14:49:06 Parsing trace...


2018/10/18 14:49:06 Serializing trace...


2018/10/18 14:49:06 Splitting trace...


2018/10/18 14:49:06 Opening browser. Trace viewer is listening on http://127.0.0.1:61380


原文发布时间为:2018-10-24

本文作者:Shocker

本文来自云栖社区合作伙伴“Golang语言社区”,了解相关信息可以关注“Golang语言社区”。

相关文章
|
3天前
|
存储 Go C语言
如何用Go开发eBPF程序
【2月更文挑战第7天】
|
3天前
|
安全 Go
Go语言并发:释放程序潜能的魔力
Go语言并发:释放程序潜能的魔力
27 0
|
7月前
|
Java 编译器 Go
Go 语言 入门 && 基于 GoLand 2023.1 创建第一个Go程序
Go 语言 入门 && 基于 GoLand 2023.1 创建第一个Go程序
63 0
|
8月前
|
Go 虚拟化 云计算
如何在 Go 语言开发的宿主程序中嵌入 WebAssembly
如何在 Go 语言开发的宿主程序中嵌入 WebAssembly
93 0
|
3天前
|
存储 Java Linux
聊聊Go程序是如何运行的
本文作者 **sharkChili** 是一名 Java 和 Go 语言开发者,同时也是 CSDN 博客专家和 JavaGuide 维护者。文章探讨了 Go 语言的执行过程,从汇编角度出发,解释了如何从 `main.go` 文件开始,经过入口跳转、参数拷贝、启动协程、运行 `g0` 的 `main` 方法等步骤,最终执行到用户定义的 `main` 函数。文章还展示了相关汇编代码片段,并提供了运行时检查、系统初始化和调度器初始化的细节。结尾提到,有兴趣的读者可以加入作者创建的交流群进行深入讨论。
12 0
|
3天前
|
运维 Serverless Go
Serverless 应用引擎产品使用之在阿里云函数计算中,Go语言的函数计算服务Go程序没有正确打包如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
26 0
|
3天前
|
Unix Linux Go
Golang深入浅出之-信号(Signals)处理与优雅退出Go程序
【4月更文挑战第25天】Go语言中的信号处理关乎程序对外部事件的响应,尤其是优雅地终止进程。本文介绍了信号基础,如SIGINT、SIGTERM等常见信号,以及处理流程:注册处理器、等待信号、执行清理和优雅退出。强调了三个易错点及避免方法,并提供实战代码示例展示如何监听和响应信号。信号处理应简洁高效,确保程序健壮性和用户体验。
21 0
|
3天前
|
Go
Golang深入浅出之-信号(Signals)处理与优雅退出Go程序
【4月更文挑战第23天】在Go语言中,使用`os/signal`包处理信号对实现程序优雅退出和响应中断至关重要。本文介绍了如何注册信号处理器、处理常见问题和错误,以及提供代码示例。常见问题包括未捕获关键信号、信号处理不当导致程序崩溃和忽略清理逻辑。解决方案包括注册信号处理器(如`SIGINT`、`SIGTERM`)、保持信号处理器简洁和执行清理逻辑。理解并正确应用这些原则能增强Go程序的健壮性和可管理性。
23 1
|
3天前
|
程序员 Go 数据中心
掌握Go语言:探索Go语言中的代码块和作用域,增强程序灵活性与可维护性(5)
掌握Go语言:探索Go语言中的代码块和作用域,增强程序灵活性与可维护性(5)
|
6月前
|
机器学习/深度学习 NoSQL Go
如何进行Go程序的打包发布
如何进行Go程序的打包发布
108 7