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语言社区”。

相关文章
|
4月前
|
人工智能 数据可视化 编译器
Go interface实现分析
本文深入探讨了Go语言中接口的定义、实现及性能影响。接口作为一种“约定”,包含方法签名集合,无需依赖具体类型即可调用方法,隐藏了内部实现细节。文章分析了接口的两种实现方式(iface和eface)、按值与按指针实现的区别,以及nil接口与普通nil的区别。同时,通过反汇编代码对比了接口动态调用与类型直接调用的性能差异,指出接口调用存在内存逃逸和无法内联的问题。最后总结了接口的优势与局限性,强调在实际开发中需根据场景合理选择是否使用接口。
102 13
|
4月前
|
Kubernetes Linux Go
使用 Uber automaxprocs 正确设置 Go 程序线程数
`automaxprocs` 包就是专门用来解决此问题的,并且用法非常简单,只需要使用匿名导入的方式 `import _ "go.uber.org/automaxprocs"` 一行代码即可搞定。
243 78
|
4月前
|
Go 调度
GO语言函数的内部运行机制分析
以上就是Go语言中函数的内部运行机制的概述,展示了函数在Go语言编程中如何发挥作用,以及Go如何使用简洁高效的设计,使得代码更简单,更有逻辑性,更易于理解和维护。尽管这些内容深入了一些底层的概念,但我希望通过这种方式,将这些理论知识更生动、更形象地带给你,让你在理解的同时找到编程的乐趣。
76 5
|
5月前
|
存储 监控 算法
员工行为监控软件中的 Go 语言哈希表算法:理论、实现与分析
当代企业管理体系中,员工行为监控软件已逐步成为维护企业信息安全、提升工作效能的关键工具。这类软件能够实时记录员工操作行为,为企业管理者提供数据驱动的决策依据。其核心支撑技术在于数据结构与算法的精妙运用。本文聚焦于 Go 语言中的哈希表算法,深入探究其在员工行为监控软件中的应用逻辑与实现机制。
147 14
|
6月前
|
Java 编译器 Go
go的内存逃逸分析
内存逃逸分析是Go编译器在编译期间根据变量的类型和作用域,确定变量分配在堆上还是栈上的过程。如果变量需要分配在堆上,则称作内存逃逸。Go语言有自动内存管理(GC),开发者无需手动释放内存,但编译器需准确分配内存以优化性能。常见的内存逃逸场景包括返回局部变量的指针、使用`interface{}`动态类型、栈空间不足和闭包等。内存逃逸会影响性能,因为操作堆比栈慢,且增加GC压力。合理使用内存逃逸分析工具(如`-gcflags=-m`)有助于编写高效代码。
134 2
|
7月前
|
存储 缓存 监控
企业监控软件中 Go 语言哈希表算法的应用研究与分析
在数字化时代,企业监控软件对企业的稳定运营至关重要。哈希表(散列表)作为高效的数据结构,广泛应用于企业监控中,如设备状态管理、数据分类和缓存机制。Go 语言中的 map 实现了哈希表,能快速处理海量监控数据,确保实时准确反映设备状态,提升系统性能,助力企业实现智能化管理。
120 3
|
7月前
|
算法 测试技术 Go
Go 1.24.0 重磅发布:新特性、新工具,开发者必看!
`Go 1.24.0` 已正式发布,带来诸多改进和新特性。语言层面上,泛型类型别名现已被完全支持;性能方面,通过优化 `map` 实现和内存分配,减少了 2-3% 的 CPU 开销;工具链新增模块工具依赖跟踪及测试分析器;标准库增加了弱引用包、FIPS 140-3 合规机制等;WebAssembly 支持也得到了增强。快来下载体验吧!
415 7
|
10月前
|
Go API 数据库
Go 语言中常用的 ORM 框架,如 GORM、XORM 和 BeeORM,分析了它们的特点、优势及不足,并从功能特性、性能表现、易用性和社区活跃度等方面进行了比较,旨在帮助开发者根据项目需求选择合适的 ORM 框架。
本文介绍了 Go 语言中常用的 ORM 框架,如 GORM、XORM 和 BeeORM,分析了它们的特点、优势及不足,并从功能特性、性能表现、易用性和社区活跃度等方面进行了比较,旨在帮助开发者根据项目需求选择合适的 ORM 框架。
868 4
|
10月前
|
Go 数据处理 开发者
Go 语言的反射机制允许程序在运行时动态检查和操作类型信息,提供极大的灵活性和扩展性
Go 语言的反射机制允许程序在运行时动态检查和操作类型信息,提供极大的灵活性和扩展性。本文探讨了反射的基本原理、主要操作、应用场景及注意事项,并通过实例展示了反射的实际应用,帮助开发者更好地理解和使用这一强大特性。
131 2
|
10月前
|
中间件 Go API
Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架
本文概述了Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架。
1034 1