Categorygithub.com/TingYunGo/goagent
modulepackage
1.8.4
Repository: https://github.com/tingyungo/goagent.git
Documentation: pkg.go.dev

# README

听云 goagent

TingYun APM3.0 - GoAgent

简介

听云 goagent 能为您的 Go 语言应用程序提供运行时状态监控功能。

它能帮助您追踪事务请求,外部调用,数据调用,nosql调用(redis, mongodb等) 以及自定义过程的性能数据和错误等运行状态信息。

为方便理解,下面这部分简单介绍Go语言的特点,如果您熟悉Go语言,请转到 听云 goagent 嵌码 开始阅读。

Go 语言简介

与c和c++语言类似, Go 语言是编译类型的语言。

Go语言程序如何运行?

Go语言源程序经过Go编译器编译,生成独立的二进制ELF(linux)/EXE(windows) 格式的可执行文件,运行时不再需要Go源程序参与。

Go语言如何使用第三方模块?

Go语言通过import语句引入第三方模块 示例代码:

package main
import (
	tingyun "github.com/TingYunGo/goagent"
)
func RoutineID() int64 {
	return tingyun.GetGID()
}

其中: tingyun 为引入模块的别名。

如果只是引入模块,并不直接使用模块的方法,那么引入模块的别名使用下划线 _ 代替, 否则Go编译器提示错误:

package main
import (
	_ "github.com/TingYunGo/goagent"
)

Go语言第三方模块如何下载安装到本地?

Go语言的所有第三方模块都是源码形式发布到git服务器上的。 第三方模块的下载安装分为 GOPATH 模式和 GOMOD 模式两种情况:

  • GOPATH模式 : Go语言版本低于1.11,或者禁用了GOMOD (设置环境变量GO111MODULE=off)模式时,处于GOPATH模式。
    这种模式下, Go编译器检测GOPATH环境变量,在GOPATH环境变量指定的每个路径下根据名字查找第三方库。GOPATH未设置时, 缺省值是当前用户的跟路径下的 go 文件夹。
    GOPATH模式第三方模块安装有两种方法:

    • 自动安装:
      使用命令 go get <第三方库路径>, 举例, 安装 tingyun goagent:

      $ go get github.com/TingYunGo/goagent
      

      命令执行后,会自动下载模块到GOPATH下的src/github.com/TingYunGo/goagent 下, 并且,递归下载该模块依赖的模块到相应目录。

    • 手动安装:
      在GOPATH下手动创建路径src/github.com/TingYunGo/goagent , 并将代码复制到该文件夹下。

  • GOMOD模式 : Go语言版本大于等于1.11, 并且设置环境变量GO111MODULE=on时, 处于GOMOD模式。
    GOMOD 模式下,在Go应用的根路径下需要go.mod文件,主要内容为应用名,Go语言版本和依赖包及版本。
    范例:

    module http_example
    go 1.12
    require (
    	github.com/TingYunGo/goagent v1.3.2
        github.com/golang/protobuf v1.5.2 // indirect
    )
    

    其中:

    • http_example 是应用的名字。
    • go 1.12 : 是要求go版本不低于 v1.12 。
    • require: 这部分指定依赖的第三方模块及对应的版本。

    GOMOD模式下依赖包的下载:

    • 使用命令:
      go mod tidy
      
      这个命令将自动检查当前应用的依赖并下载所有依赖包,并且校验依赖包的hash值,写入到go.sum文件。

Go语言应用如何编译?

进入应用源码路径,执行 go build 命令,即生成应用的可执行文件。

听云 goagent 嵌码

听云 goagent 是什么?

  • 听云 goagent是一个Go语言第三方模块, 发布根路径是: github.com/TingYunGo/goagent
  • 听云 goagent 支持 amd64架构处理器 的linux环境, go1.9 到 最新的 go1.21.x Go语言版本。
  • 听云 goagent 提供自动嵌码和自定义嵌码(Go API)两种嵌码机制。
  • 自动嵌码支持列表参考 框架支持列表组件支持列表

听云 goagent 如何安装?


与所有第三方模块的安装方式相同。

  • GOPATH模式下安装:
    $ go get github.com/TingYunGo/goagent
    
  • GOMOD模式下安装:
    在应用文件夹下执行:
    $ go mod tidy
    

听云 goagent如何使用(嵌码)?

根据应用使用http框架的不同, 需要import 不同的路径。

我们以一个使用内置http框架举的简单例子说明如何嵌码:
源文件: main.go 代码如下:

package main
import (
	"encoding/json"
	"net/http"
)
func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		header := w.Header()
		header.Set("Cache-Control", "no-cache")
		header.Set("Content-Type", "application/json; charset=utf-8")
		w.WriteHeader(http.StatusOK)
		b, _ := json.Marshal(map[string]interface{}{
			"status": "success",
			"URI":    r.URL.RawQuery,
		})
		w.Write(b)
	})
	http.ListenAndServe(":3000", nil)
}

要对如上这个应用嵌码, 在源文件同级目录下,创建tingyun.go文件,内容如下:

package main
import (
	_ "github.com/TingYunGo/goagent"
)

全部嵌码工作即完成。

嵌码说明:
此例应用使用了内置http框架, 对于内置http框架, 需要 引入 github.com/TingYunGo/goagent 。

如何确定嵌码要使用哪个/哪些 import 模块路径?

下边整理了 goagent 支持的 框架/组件支持列表, 通过查表获得引用依赖。

获取当前应用的依赖模块:

  • GOMOD 方式: 查看go.mod文件,或者使用命令:
	$ go mod graph
  • GOPATH 方式: 编译时使用 -a -v 参数:
	$ go build -a -v

听云探针框架支持列表:

框架听云探针嵌码 import 模块路径支持版本
net/http
内置http框架
github.com/TingYunGo/goagentgo1.9 ~ go1.21.x
github.com/gin-gonic/gin
gin框架
github.com/TingYunGo/goagent/frameworks/gingin v1.3.0 ~ gin v1.8.2
github.com/astaxie/beego
beego框架: GOPATH模式
github.com/TingYunGo/goagent/frameworks/beego/path/astaxiebeego v1.12.0 ~ beego v2.0.0-beta
github.com/beego/beego
beego框架: GOPATH模式
github.com/TingYunGo/goagent/frameworks/beego/pathbeego v1.12.0 ~ beego v2.0.1
github.com/beego/beego
beego框架v1: GOMOD模式
github.com/TingYunGo/goagent/frameworks/beegobeego v1.12.0 ~ beego v1.12.3
github.com/beego/beego/v2
beego框架v2: GOMOD模式
github.com/TingYunGo/goagent/frameworks/beego/v2beego v2.0.0 ~ beego v2.0.1
github.com/labstack/echo
echo 框架 GOPATH模式
github.com/TingYunGo/goagent/frameworks/echoecho v3.3.10 ~ echo v4.6.1
github.com/labstack/echo/v4
echo 框架 V4 GOMOD模式
github.com/TingYunGo/goagent/frameworks/echo/v4echo v4.0.0 ~ echo v4.6.1
github.com/kataras/iris/v12
iris 框架 v12.1.x
github.com/TingYunGo/goagent/frameworks/iris/v12iris v12.1.0 ~ iris v12.1.8
github.com/kataras/iris/v12
iris 框架 v12.2
github.com/TingYunGo/goagent/frameworks/iris/v12/2iris v12.2.0-alpha ~ iris v12.2.0-alpha3
google.golang.org/grpc
grpc 框架
github.com/TingYunGo/goagent/frameworks/grpcgrpc v1.32.0 ~ grpc v1.57.0
github.com/go-kratos/kratos/v2
kratos 框架 v2
github.com/TingYunGo/goagent/frameworks/kratosV2kratos v2.0.0 ~ kratos v2.6.3

听云探针组件支持列表

组件听云探针嵌码 import 模块路径支持版本
database/sql
数据库
github.com/TingYunGo/goagent/databasego1.9 ~ go1.21.x
驱动列表:
mssql: github.com/denisenkom/go-mssqldb v0.9.0 ~ v0.11.0
mysql: github.com/go-sql-driver/mysql v1.0.0 ~ v1.6.0
postgresql: github.com/lib/pq v1.0.0 ~ v1.10.3
sqlite: github.com/mattn/go-sqlite3 v1.0.0 ~ v1.14.8
github.com/gomodule/redigo
redis: redigo
github.com/TingYunGo/goagent/nosql/redigov1.7.0 ~ v1.8.5
github.com/go-redis/redis
redis: go-redis, GOPATH模式
github.com/TingYunGo/goagent/nosql/go-redisv6.10.0 ~ v8.11.4
github.com/go-redis/redis
redis: go-redis default, GOMOD模式
github.com/TingYunGo/goagent/nosql/go-redisv6.10.0 ~ v8.11.4
github.com/go-redis/redis/v7
redis: go-redis v7, GOMOD模式
github.com/TingYunGo/goagent/nosql/go-redis/v7v7.0.0 ~ v7.4.1
github.com/go-redis/redis/v8
redis: go-redis v8, GOMOD模式
github.com/TingYunGo/goagent/nosql/go-redis/v8v8.0.0 ~ v8.11.4
github.com/redis/go-redis/v9
redis: go-redis v9, GOMOD模式
github.com/TingYunGo/goagent/nosql/go-redis/v9v9.0.0 ~ v9.1.0
go.mongodb.org/mongo-driver/mongo
mongodb
github.com/TingYunGo/goagent/nosql/mongodbv1.1.0 ~ v1.7.3
gopkg.in/mgo.v2
mongodb
github.com/TingYunGo/goagent/nosql/mgolatest
go.uber.org/zap
zap 日志溯源
github.com/TingYunGo/goagent/frameworks/zapv1.0.0 ~ latest

嵌码实例演示

以开源项目 photoprism 为例 : 项目地址 https://github.com/photoprism/photoprism

  • 步骤1. 首先克隆项目:

    $ git clone https://github.com/photoprism/photoprism.git
    
  • 步骤2. 确定项目使用哪些框架和库:

    进入项目文件夹,查看 go.mod文件:

    $ cd photoprism
    $ cat go.mod
    

    我们会看到,此项目使用了gin框架, 数据库支持:

    postgresql:(github.com/lib/pq)
    mysql:(github.com/go-sql-driver/mysql)
    sqlite:(github.com/mattn/go-sqlite3)
    
  • 步骤3: 查表确定引用路径,添加源码:

    查看框架支持列表, 我们的嵌码操作需要引用两个路径:

    github.com/TingYunGo/goagent/frameworks/gin
    github.com/TingYunGo/goagent/database
    

    在代码目录 internal/photoprism下创建 tingyun.go文件,内容如下:

    package photoprism
    import (
    	_ "github.com/TingYunGo/goagent/database"
    	_ "github.com/TingYunGo/goagent/frameworks/gin"
    )
    
  • 步骤4. 执行 go mod tidy, 编译:

    在项目的go.mod文件所在的文件夹下,执行:

    $ go mod tidy
    $ make
    

    以上4个步骤完成后,项目编译和探针嵌码工作就全部完成。

常用Go语言第三方组件支持的数据库版本列表

组件支持版本
mssql: github.com/denisenkom/go-mssqldbSQL Server 2008 SP3 +
mysql: github.com/go-sql-driver/mysqlmysql 5.5+
postgresql: github.com/lib/pqpostgresql 9.6+
sqlite: github.com/mattn/go-sqlite3sqlite 3.8.5 ~ 3.36.0
redis: redigo github.com/gomodule/redigoredis 4.0.0+
redis: go-redis github.com/go-redis/redisredis 4.0.0+
mongodb: go.mongodb.org/mongo-driver/mongomongodb 2.6.1+

配置&运行

已经嵌码的应用, 听云agent 部分如何配置?

为保证应用程序的最大限度的安全,缺省不配置的情况下, 嵌码逻辑是处于禁用状态。

指定配置文件:

要启用agent监控,需要设置环境变量: TINGYUN_GO_APP_CONFIG 指定配置文件路径。

$ export TINGYUN_GO_APP_CONFIG=/[configfilepath]/tingyun.conf
$ /your app path/appname [your app args]

注意!!! 必须在应用程序启动前设置环境变量,在应用程序里设置环境变量是无效的。

听云agent 配置项:

参考配置 tingyun.conf:


######## 应用配置项 ########

# 设置应用名字符串类型, 可选项, 缺省取进程名做应用名 
# app_name = "My Go App"

# Agent启用标志, bool 类型, 可选项, 缺省为 true
# agent_enabled = true


######## 授权 / 服务器配置项 #########

# 授权序列码, 字符串类型, 必选项, 不能为空 
#license_key = "999-999-999"

# collector服务器地址, 多个地址用逗号分隔, 必选项, 不能为空
#collector.address = "collector_ip:port"

# 向collector服务器发送请求是否启用ssl(https), 缺省值 false
# ssl = false


######## 日志配置项 ########

# 日志文件路径, 必选项. 置空或不配置此项时, 无日志输出
agent_log_file = agent.log

# 日志输出级别设置, 可设置级别: debug, info, error, off
# debug: 输出最多日志
#  info: 输出 info级别和 error级别日志
# error: 仅输出 error级别日志
#   off: 关闭日志输出
# 缺省值: info
agent_log_level = info

# 审计模式, bool类型, 缺省值 false; 配合日志级别, 控制日志的输出
# 设置为 false 时, 部分审计模式日志不输出
audit_mode = true

# 日志文件大小, 整数, 单位 MB, 缺省值10
# 日志文件大小超过此阈值时, 将创建新的日志文件, 旧的日志将依次更新日志文件名
agent_log_file_size = 10

# 保留日志文件个数, 整数, 缺省值3
# 日志文件个数超过此阈值将从最早的文件开始删除
agent_log_file_count = 3

######## 指标采集配置项 ########

# gorilla/websocket 框架采集启用控制选项: bool 类型, 缺省值 false;
gorilla.websocket=false

# websocket采集 阈值,单位:毫秒; 缺省值0
# websocket消息处理耗时低于此阈值时,不采集websocket消息处理事务, 为0时全部采集
websocket.ignore.duration=0

######## 内存控制阈值 ########

# 事务数据采集对象在内存缓冲队列中存放的最大数量, 缺省值10000
# 超过此阈值意味着当前并发数过高, 后台工作协程的处理能力不足以消费完采集到的数据
# 为防止数据积压导致的应用内存无限制增长, 当事务缓冲队列超过此阈值时, 不再采集事务性能数据 
action_cache_max = 10000

# 每次向collector发送数据包含的最大事务数量, 缺省值5000 
action_report_max = 5000

# 向collector发送的数据缓冲队列长度, 缺省值10 
# 发送队列长度超过此阈值意味网络缓慢或者collector处理能力不足 
# 为防止数据积压导致的内存无限制增长, 当发送队列长度超过此阈值时, 新的发送请求将被丢弃 
report_queue_count = 5

# 每个事务可采集的最大组件调用次数, 缺省值3000
# 事务采集的组件次数超过此阈值后,此事务的采集过程将不再采集新的组件调用数据
agent_component_max = 3000

# sql语句的最大字节长度,缺省值5000
# 超过此阈值,采集的sql将被截断为阈值设定长度
agent_sql_size_max = 5000

环境变量支持

某些特殊场合,有可能需要通过环境变量灵活控制配置项。作为配置文件的补充,听云agent也提供了相应支持。 听云agent支持的环境变量:

agent_enabled  # 启用探针选项, 取值: true/false; 缺省值: true
audit_mode  # 审计模式, 审计模式日志开启选项, 取值: true/false; 缺省值: false
agent_log_level  # 日志级别设置, 取值: debug/info/error/off; 缺省值: info
agent_log_file  # 日志文件路径
license_key  # 授权序列码
collectors  # collector服务器地址,多个地址以逗号分隔
agent_init_delay  # 探针延时初始化时间,整数,单位秒, 缺省值1.  说明: 如果探针初始化过早,可能在应用开始listen之前初始化, 这种情况下探针抓不到应用listen的端口. 增加初始化延时以解决此问题.
TINGYUN_GO_APP_NAME  # 应用名称

自动嵌码演示范例

使用听云 goagent嵌码,请参考部分范例程序 听云 goagent演示

自定义嵌码(听云 goagent API)

自定义嵌码部分请参考阅读 听云 goagent API

Code License

听云 goagent 使用 Apache 2.0 协议发布.

交叉编译

OSX 系统

引入听云探针后,MAC系统环境下的交叉编译(linux,amd64), 需要安装交叉编译工具(C编译器及LIBC库),如果未安装相关工具,可参考使用如下包(使用MUSL C):

$ brew install FiloSottile/musl-cross/musl-cross

Go语言项目 MUSL C的交叉编译命令请参考:

# CC: C语言交叉编译器
# GOARCH: 编译后的可执行文件运行的CPU架构
# GOOS: 编译后的可执行文件运行的操作系统
# "-extldflags -static" : 静态链接
$ CC=x86_64-linux-musl-gcc GOARCH=amd64 GOOS=linux CGO_ENABLED=1 go build -ldflags "-linkmode external -extldflags -static"

# Packages

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Functions

ConfigRead : 读配置项.
CreateAction : 在方法method中调用并 创建一个名为 name的事务,.
No description provided by the author
No description provided by the author
No description provided by the author
go:noinline.
GetAction : 辅助功能函数: 将存储到协程局部存储器的Action对象取出.
GetCallerName : 取layer层调用栈函数名go:noinline.
GetCallerPC return caller pcgo:noinline.
GetComponent : 辅助功能函数: 将存储到协程局部存储器的组件对象取出.
No description provided by the author
go:noinline.
return token_name, token_value.
Clear Routine Local Storage.
LocalDelete : 从协程局部存储器中删除key为 id的对象,并返回这个对象.
LocalGet : 从协程局部存储器中取出key为 id的对象,没有则返回nil.
LocalSet : 以id为key, 将对象object写入协程局部存储器.
Log : 返回日志对象接口.
go:noinline.
No description provided by the author
No description provided by the author
SetAction : 辅助功能函数: 将事务存到协程局部存储器.
SetComponent : 辅助功能函数: 将组件存到协程局部存储器.
No description provided by the author

# Constants

* 日志级别/审计模式控制 */.
* 组件类型定义 */.
* 组件类型定义 */.
* 组件类型定义 */.
* 组件类型定义 */.
* 组件类型定义 */.
* 组件类型定义 */.
* 组件类型定义 */.
* 组件类型定义 */.
* 组件类型定义 */.
* 组件类型定义 */.
* 组件类型定义 */.
* 组件类型定义 */.
* 组件类型定义 */.
No description provided by the author
No description provided by the author
* 日志级别/审计模式控制 */.
* 日志级别/审计模式控制 */.
* 日志级别/审计模式控制 */.
* 日志级别/审计模式控制 */.
* 日志级别/审计模式控制 */.
* 日志级别/审计模式控制 */.
* 日志级别/审计模式控制 */.
* 日志级别/审计模式控制 */.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Structs

Action : 事务对象.
Component : 构成事务的组件过程.
No description provided by the author
RoutineLocal : 事务线程局部存储对象.
No description provided by the author
Unit is The GoRoutine LocalStorage Unit.