项目文档
- 1: JKFrame
- 1.1: api
- 1.2: compress
- 1.3: daemon
- 1.4: kvconf
- 1.5: l2cache
- 1.6: logging
- 1.7: mysqlschema
- 1.8: stat
- 1.9: utils
- 1.10: yaml
- 2: LibAgent
- 3: Agent生态体系
- 3.1: 服务端
- 3.2: example-agent
- 3.3: exec-agent
- 3.4: metrics-agent
- 4: SmartAgent老版本
- 4.1: API接口文档
- 4.1.1: 安装软件相关接口
- 4.1.1.1: /install/run
- 4.1.1.2: /install/status
- 4.1.2: 插件相关接口
- 4.1.2.1: /plugin/reload
- 4.1.3: 服务器端相关接口
- 4.1.3.1: /server/info
- 4.1.4: 节点相关接口
- 4.1.4.1: /host/info
- 4.1.4.2: /host/list
- 4.1.4.3: /host/search
- 4.1.5: 流程编排相关接口
- 4.1.5.1: /layout/run
- 4.1.5.2: /layout/status
- 4.1.6: 命令行相关接口
- 4.1.6.1: /cmd/kill
- 4.1.6.2: /cmd/ps
- 4.1.6.3: /cmd/pty
- 4.1.6.4: /cmd/run
- 4.1.6.5: /cmd/status
- 4.1.6.6: /cmd/sync_run
- 4.1.7: 日志采集相关接口
- 4.1.7.1: /logging/config
- 4.1.7.2: /logging/remove
- 4.1.7.3: /logging/start
- 4.1.7.4: /logging/stop
- 4.1.7.5: /logging/task_info
- 4.1.8: 文件操作相关接口
- 4.1.8.1: /file/download
- 4.1.8.2: /file/ls
- 4.1.8.3: /file/upload_from
- 4.1.8.4: /file/upload
- 4.1.9: 主机信息采集相关接口
- 4.1.9.1: /hm/static
1 - JKFrame
项目地址: https://github.com/jkstack/jkframe
最新版本:
1.1 - api
1.2 - compress
1.3 - daemon
1.4 - kvconf
1.5 - l2cache
1.6 - logging
1.7 - mysqlschema
1.8 - stat
1.9 - utils
1.10 - yaml
2 - LibAgent
项目地址: https://github.com/jkstack/libagent
最新版本:
流程图
Agent启动过程
- 加载配置文件
- 初始化logging模块,设置rotate等参数
- 初始化limit模块
- 若当前系统为linux操作系统则通过cgroups进行资源限制
- 若当前系统为windows操作系统则通过go语言的runtime库进行CPU和内存的资源限制
- 启动monitor模块,定时上报监控数据
- 创建WebSocket连接,交换AgentID和当前操作系统信息
- 启动异步读/写协程处理从服务端收到的任务
- 启动keepalive模块,定时发送心跳
技术实现细节
公共配置
精鲲Agent产品在经过了若干个版本的迭代后,提炼出了一些每一类Agent都会有的公共配置信息如下:
id = <agent-id>
server = <server-addr>
log.target = stdout,file # log写入目标,目前仅支持stdout和file
log.dir = <dir> # log文件保存路径
log.size = 10M # log文件滚动生成时的文件大小
log.rotate = 7 # log文件滚动生成时的保留数量
monitor.enabled = true # 是否开启监控信息上报
monitor.interval = 30s # 监控数据上报频率
limit.cpu_quota = 100 # CPU最大使用率,100表示一个CPU核心
limit.memory_limit = 512M # 内存最大使用容量
# 以下配置项的内容为一个json数组,其中的字段含义如下:
# dev: 磁盘设备号,可通过lsblk命令查询
# read_bytes: 每秒读取字节数
# write_bytes: 每秒写入字节数
# read_iops: 每秒读取次数
# write_iops: 每秒写入次数
# 注意: 该配置项只支持linux操作系统,且支持cgroups时有效
limit.disk_limit = [{"dev":"8:0","read_bytes":"10M","write_bytes":"10M","read_iops":1000,"write_iops":1000}]
WebSocket连接
本地Agent与服务器端使用WebSocket协议进行RPC通信,在连接过程中双方会交换当前节点的AgentID,若本地Agent未指定AgentID时将由服务器端自动分配。
创建WebSocket链接时需要进行一次握手,握手请求由Agent端发起,数据格式如下:
type ComePayload struct {
ID string `json:"id"` // agent-id
Name string `json:"name"`
Version string `json:"version"` // 版本号
IP net.IP `json:"ip"` // ip地址
MAC string `json:"mac"` // mac地址
HostName string `json:"host_name"` // 主机名
OS string `json:"os"` // 操作系统名称,windows或linux
Platform string `json:"platform"` // 操作系统名称,debian、centos等
PlatformVersion string `json:"platform_version"` // 操作系统版本号,如7.7.1908
KernelVersion string `json:"kernel_version"` // 内核版本号,如3.10.0-1062.el7.x86_64
Arch string `json:"arch"` // 操作系统位数,amd64、i386等
CPU string `json:"cpu"` // CPU型号,如AMD Ryzen 7 4800U with Radeon Graphics
CPUCore uint64 `json:"cpu_core"` // CPU核心数
Memory uint64 `json:"memory"` // 内存大小
}
服务端在创建WebSocket链接时会等待本次的握手报文,超时时间为1分钟,若客户端一直未发送握手报文则将断开该链接。后续处理逻辑如下:
- 当握手报文中未包含AgentID时,自动生成一个随机的AgentID并返回给Agent
- 若指定AgentID在当前链接列表中已存在时,将会返回
agent id conflict
的错误 - 返回链接成功报文
其中返回数据的报文格式如下:
type HandshakePayload struct {
OK bool `json:"ok"` // 握手是否成功
ID string `json:"id"` // 被分配的agent id
Msg string `json:"msg"` // 错误信息
Redirect []string `json:"redirect,omitempty"` // 重定向地址
}
通过以上连接过程即可实现Agent端程序与服务器端程序的正常连接,并可在后续操作中实现任务的下发与调度执行。
断线重连
当Agent端程序发生链接断开时(如服务器端升级重启),LibAgent将会进行断线重连,重连过程中以1s、2s、4s的间隔时间进行尝试,最多间隔4s,详情可见start中的循环处理逻辑。
监控数据
Agent运行时会上报一些基础的监控信息,可通过配置文件中的monitor.enabled
字段进行关闭,该数据由Prometheus定义,可通过服务器端的/metrics
接口获取,内容如下:
# HELP agent_info
# TYPE agent_info gauge
agent_info{agent_type="example-agent",id="example-agent",tag="cpu_usage"} 0.1730158030986786
agent_info{agent_type="example-agent",id="example-agent",tag="gc_0"} 1.0801e-05
agent_info{agent_type="example-agent",id="example-agent",tag="gc_0.25"} 1.0801e-05
agent_info{agent_type="example-agent",id="example-agent",tag="gc_0.5"} 1.6512e-05
agent_info{agent_type="example-agent",id="example-agent",tag="gc_0.75"} 1.6512e-05
agent_info{agent_type="example-agent",id="example-agent",tag="gc_1"} 1.6512e-05
agent_info{agent_type="example-agent",id="example-agent",tag="heap_in_use"} 1.9652608e+07
agent_info{agent_type="example-agent",id="example-agent",tag="in_bytes"} 0
agent_info{agent_type="example-agent",id="example-agent",tag="in_packets"} 0
agent_info{agent_type="example-agent",id="example-agent",tag="memory_usage"} 0.9135397672653198
agent_info{agent_type="example-agent",id="example-agent",tag="out_bytes"} 0
agent_info{agent_type="example-agent",id="example-agent",tag="out_packets"} 0
agent_info{agent_type="example-agent",id="example-agent",tag="read_chan_size"} 0
agent_info{agent_type="example-agent",id="example-agent",tag="reconnect_count"} 0
agent_info{agent_type="example-agent",id="example-agent",tag="report_time"} 1.668065623e+09
agent_info{agent_type="example-agent",id="example-agent",tag="routines"} 10
agent_info{agent_type="example-agent",id="example-agent",tag="startup"} 1.668065613e+09
agent_info{agent_type="example-agent",id="example-agent",tag="threads"} 10
agent_info{agent_type="example-agent",id="example-agent",tag="write_chan_size"} 0
# HELP agent_version
# TYPE agent_version gauge
agent_version{go_version="go1.19.3",id="example-agent",version="1.0.0"} 1
埋点代码,字段定义如下:
startup
: 该Agent的启动时间戳report_time
: 最后一次上报时的时间戳cpu_usage
: 该Agent进程的CPU占用率(百分比)memory_usage
: 该Agent进程的内存占用率(百分比)heap_in_use
: 占用的内存字节数gc_0
: GC耗时的0分位数(秒)gc_0.25
: GC耗时的25分位数(秒)gc_0.5
: GC耗时的50分位数(秒)gc_0.75
: GC耗时的75分位数(秒)gc_1
: GC耗时的100分位数(秒)in_bytes
: 收到的数据包字节数in_packets
: 收到的数据包数量out_bytes
: 发送的数据包字节数out_packets
: 发送的数据包数量read_chan_size
: 接收队列当前长度write_chan_size
: 发送队列当前长度reconnect_count
: 重连次数threads
: 当前线程数routines
: 当前协程数go_version
: 该Agent编译的GO版本号version
: 该Agent的版本号
linux/windows系统服务注册
目前LibAgent通过service库进行Agent程序的系统服务注册与控制,目前已测试通过的操作系统列表如下:
系统 | 版本号 | 内核版本 |
ubuntu | 12.04 | 3.2 |
ubuntu | 14.04 | 3.13 |
ubuntu | 16.04 | 4.4 |
ubuntu | 18.04 | 4.15 |
ubuntu | 20.04 | 5.4 |
ubuntu | 22.04 | 5.15 |
suse | 11(SP4) | 3.0.101-108.135.1 |
suse | 12(SP5) | 4.12.14-122.130.1 |
suse | 15(SP4) | 5.14.21-150400.24.18.1 |
redhat | 6.1 | 2.6.32-754 |
redhat | 7.9 | 3.10.0-1160 |
redhat | 8.6 | 4.18.0-372.9.1 |
centos | 6.1 | 2.6.32-754 |
centos | 7.9-2009 | 3.10.0-1160 |
centos | 8.5.2111 | 4.18.0-348 |
windows | 7 Enterprise with Service Pack 1 | |
windows | 7 Professional with Service Pack 1, VL Build | |
windows | 10 Enterprise LTSC 2021 | |
windows | 2008 R2 Enterprise | |
windows | 2008 R2 Datacenter | |
windows | 2016 VL | |
windows | 2016(Updated Feb 2018) | |
windows | 2016 Essentials | |
windows | 2019(Updated July 2020) | |
windows | 2022(updated Aug 2022) |
3 - Agent生态体系
产品架构图
部署架构图
3.1 - 服务端
项目地址: https://github.com/jkstack/agent-server
最新版本:
3.2 - example-agent
项目地址: https://github.com/jkstack/example-agent
最新版本:
3.2.1 - Agent开发
Agent开发
创建项目并导入libagent库
go get github.com/jkstack/libagent
定义一个结构体并实现App接口
在main函数中添加RegisterService、UnregisterService和Run等libagent库中的接口调用
switch *act { case "install": agent.RegisterService(app) case "uninstall": agent.UnregisterService(app) default: agent.Run(app) }
研发与打包规范
- 项目根目录中必须包含一个
CHANGELOG.md
文件,在打包过程中会自动读取该文件中的内容并自动填写到Release的描述信息中,格式可参考样例 - 项目根目录中必须包含一个
Makefile
文件,在打包过程中会使用该文件中的第一个目标进行打包,打包成功后的产物必须存放到release目录下 - 开发的代码在原则上需要支持谷歌维护的最新的两个go语言版本,因此在go.mod文件中目前会被设置为1.18版本
- 在项目初始化的过程中需要修改contrib目录下的文件,如修改正确的打包路径等
- 为方便于外部工具化部署,需要正确修改
manifest.yaml
文件,使其符合配置文件中的配置项描述
打包方法
通过在项目中引入workflows目录下的build.yml和release.yml可实现项目的自动化打包。
- build.yml中定义了当master分支发生合并时会进行代码的lint检查及go build测试
- release.yml中定义了当该项目被打上了
v*.*.*
的标签后将会触发release动作,首先会进行各种系统下的跨平台编译与打包,然后读取CHANGELOG.md
中对应版本的描述信息进行创建release操作,并将release目录下的文件进行上传
更多示例
- exec-agent: 远程执行脚本以及文件传输
- metrics-agent: 监控数据采集
3.2.2 - 配置项描述
每一个Agent项目中的conf目录下必须包含一个manifest.yaml
文件用于描述该Agent的配置项信息,该文件被用于外部工具做自动化部署时的展示。
该文件的内容最顶层为一个数组,其中每一个元素代表配置文件中的某一个字段,该字段的描述信息如下:
key
: 该字段在配置文件中的名称name.zh
: 该字段的中文名称,用于自动化部署工具的展示desc.zh
: 该字段的中文描述type
: 该字段类型,目前已支持以下类型string
: 字符串enum
: 枚举值csv
: 逗号分隔的字符串,允许多个值int
: 有符号整数uint
: 无符号整数float
: 浮点数bool
: 布尔值naddr
: 网络地址,<ip>:<port>path
: 文件路径bytes
: 可视化字节数,(n)G、(n)M、(n)KB、(n)B等duration
: 时长,(n)h、(n)m、(n)s等uuid
: 唯一标识ID
required
: 是否必填default
: (可选)默认值enum_valid
: (可选)enum字段允许输入的内容csv_valid
: (可选)csv字段允许输入的内容str_valid
: (可选)string类型的匹配正则表达式min
: (可选)最小值,支持的数据类型int
、uint
、float
、bytes
、duration
max
: (可选)最大值,支持的数据类型int
、uint
、float
、bytes
、duration
len
: (可选)最大长度,支持的数据类型string
、csv
、path
allow_relative
: (可选)是否允许使用相对路径,支持的数据类型path
category
: (可选)配置项分类
示例
- key: basic.id
type: string
name:
zh: AgentID
desc:
zh: Agent的ID,在当前服务器下的集群内唯一
required: true
- key: basic.server
type: naddr
name:
zh: 服务端地址
desc:
zh: 链接服务器端的地址
default: 127.0.0.1:13081
required: true
- key: basic.log.target
type: csv
name:
zh: 日志保存目标
desc:
zh: 日志保存目标,目前仅支持stdout和文件
default: stdout
csv_valid: [ stdout, file ]
required: false
- key: basic.log.dir
type: path
name:
zh: 日志保存路径
desc:
zh: 日志保存路径
default: ./logs
required: false
- key: basic.log.size
type: bytes
name:
zh: 日志文件滚动大小
desc:
zh: 日志文件生成时每个文件的大小
default: 10M
min: 1M
max: 100M
required: false
- key: basic.log.rotate
type: uint
name:
zh: 日志文件保留份数
desc:
zh: 日志文件生成时最多保留份数
default: 7
min: 1
max: 100
required: false
关联关系
示例1
log.target = stdout,file
log.dir = ./logs
log.size = 10M
log.rotate = 7
当log.target
字段未设置file
属性时,log.dir
、log.size
、log.rotate
配置项是无效的。
示例2
monitor.enabled = true
monitor.interval = 10s
当monitor.enabled
字段设置为false时,monitor.interval
配置项是无效的。
基于以上两种情况,增加配置字段如下:
- key: basic.log.dir
...
enabled:
when:
target: basic.log.target
contain: file
- key: basic.monitor.interval
...
enabled:
when:
target: basic.monitor.enabled
equal: true
enabled
字段用于表示当前字段的有效范围when
字段表示当条件中的描述符合要求时该字段有效target
: 该字段表示需要关联到的原始字段名称contain
: 针对于原始字段为csv
类型时csv内容中包含该配置项时当前字段才有效equal
: 针对于原始字段为bool
或数值
类型时原始字段的值与要求内容相符时才有效
3.4 - metrics-agent
项目地址: https://github.com/jkstack/metrics-agent
最新版本:
兼容性
系统 | 版本号 | 内核版本 | 是否支持 |
---|---|---|---|
ubuntu | 12.04 | 3.2 | ✅ |
ubuntu | 14.04 | 3.13 | ✅ |
ubuntu | 16.04 | 4.4 | ✅ |
ubuntu | 18.04 | 4.15 | ✅ |
ubuntu | 20.04 | 5.4 | ✅ |
ubuntu | 22.04 | 5.15 | ✅ |
suse | 10(SP4) | 2.6.16.60-0.132.1 | ❌ |
suse | 11(SP4) | 3.0.101-108.135.1 | ✅ |
suse | 12(SP5) | 4.12.14-122.130.1 | ✅ |
suse | 15(SP4) | 5.14.21-150400.24.18.1 | ✅ |
redhat | 5.11 | 2.6.18-398 | ❌ |
redhat | 6.1 | 2.6.32-754 | ✅ |
redhat | 7.9 | 3.10.0-1160 | ✅ |
redhat | 8.6 | 4.18.0-372.9.1 | ✅ |
centos | 5.11 | 2.6.18-398 | ❌ |
centos | 6.1 | 2.6.32-754 | ✅ |
centos | 7.9-2009 | 3.10.0-1160 | ✅ |
centos | 8.5.2111 | 4.18.0-348 | ✅ |
windows | XP | ❌ | |
windows | 7 Enterprise with Service Pack 1 | ✅ | |
windows | 7 Professional with Service Pack 1, VL Build | ✅ | |
windows | 10 Enterprise LTSC 2021 | ✅ | |
windows | 2008 R2 Enterprise | ✅ | |
windows | 2008 R2 Datacenter | ✅ | |
windows | 2016 VL | ✅ | |
windows | 2016(Updated Feb 2018) | ✅ | |
windows | 2016 Essentials | ✅ | |
windows | 2019(Updated July 2020) | ✅ | |
windows | 2022(updated Aug 2022) | ✅ |
采集项
采集项分为静态数据、usage数据、进程列表数据、连接列表数据、传感器温度数据,这5类数据可单独设置采集频率。
静态数据
静态数据的默认采集频率为1天,该部分数据的特点是基本不太会变化,如CPU核心数、CPU型号、内存总大小等,可采集到的内容如下:
采集项 | 描述 |
---|---|
host_name | 主机名 |
uptime | 系统启动时长 |
os_name | 操作系统类型,如linux、windows等 |
platform_name | 操作系统名称,如debian、centos等 |
platform_version | 操作系统版本号,如7.7.1908 |
install | 操作系统安装时间 |
startup | 操作系统启动时间 |
kernel_version | 内核版本号 |
arch | 操作系统位数,如amd64、i386等 |
physical_cpu | 物理核心数,表示有多少块CPU |
logical_cpu | 逻辑核心数 |
gateway | 网关地址 |
nameservers | dns服务器列表 |
其中cores
字段表示该主机的CPU核心列表,内容如下:
采集项 | 描述 |
---|---|
processor | 当前是第几个核心 |
model | 核心型号,如Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz |
core | 该核心所在物理核心编号 |
cores | 该核心所在CPU上的编号 |
physical | 该核心所在CPU在主板上的物理编号 |
mhz | 该核心的频率 |
其中disks
字段表示该机器的磁盘列表,内容如下:
采集项 | 描述 |
---|---|
model | 品牌型号 |
total | 总容量 |
type | 磁盘类型,0=硬盘;1=软盘;2=光盘 |
partitions | 分区列表 |
其中partitions
字段表示该机器的硬盘分区信息,内容如下:
采集项 | 描述 |
---|---|
mount | linux系统为挂载路径如/run,windows系统为盘符如C: |
type | 分区类型,如NTFS等 |
options | 挂载选项,如rw,nosuid,nodev等 |
total | 该分区总容量 |
inodes | 该分区总inode数量 |
其中interfaces
字段表示该机器的网卡列表信息,内容如下:
采集项 | 描述 |
---|---|
index | 该网卡下标 |
name | 网卡名称,如eth0 |
mtu | 该网卡的mut配置 |
flags | 该网卡的附加参数,如BROADCAST,RUNNING,MULTICAST等 |
addrs | 该网卡绑定的IP列表,包含IPv4和IPv6地址 |
mac | 该网卡的mac地址 |
其中users
字段表示该主机上的账号列表,内容如下:
采集项 | 描述 |
---|---|
name | 用户名 |
id | 用户ID |
gid | 用户所在组ID |
usage数据
usage数据表示该主机的使用率数据,默认采集频率为5秒,可采集到的内容如下:
采集项 | 描述 |
---|---|
cpu_usage | CPU使用率 |
memory_used | 内存占用字节数 |
memory_free | 内存剩余字节数 |
memory_available | 可用内存字节数 |
memory_usage | 内存使用率 |
swap_used | 已使用swap内存字节数 |
swap_free | 剩余swap内存字节数 |
cpu_load_1 | CPU的最近1分钟负载 |
cpu_load_5 | CPU的最近5分钟负载 |
cpu_load_15 | CPU的最近15分钟负载 |
其中partitions
字段表示磁盘分区当前使用率列表,内容如下:
采集项 | 描述 |
---|---|
mount | linux系统为挂载路径如/run,windows系统为盘符如C:,用于与静态数据关联 |
used | 已使用字节数 |
free | 未使用字节数 |
usage | 使用率 |
inode_used | 已使用的inode数量 |
inode_free | 未使用的inode数量 |
inode_usage | inode使用率 |
read_per_second | 每秒读取字节数 |
write_per_second | 每秒写入字节数 |
iops_in_progress | 正在等待的IO操作数量 |
其中interfaces
字段表示网卡信息,内容如下:
采集项 | 描述 |
---|---|
name | 网卡名称,如eth0,用于与静态数据关联 |
bytes_sent | 已发送字节数 |
bytes_recv | 已接收字节数 |
packets_sent | 已发送数据包数量 |
packets_recv | 已接收数据包数量 |
进程列表数据
该采集项用于采集主机上的进程列表信息,内容如下:
采集项 | 描述 |
---|---|
id | 进程ID |
parent_id | 父进程ID |
user | 所属用户 |
cpu_usage | CPU使用率 |
rss | 物理内存字节数 |
vms | 虚拟内存字节数 |
swap | swap内存字节数 |
memory_usage | 内存使用率 |
cmd | 启动命令行参数 |
listen | 监听端口列表 |
connections | 连接数 |
连接列表数据
该采集项用于采集主机上的连接列表信息,内容如下:
采集项 | 描述 |
---|---|
fd | 句柄编号 |
pid | 所属进程ID |
type | 连接类型,0=tcp IPv4;1=tcp IPv6;2=udp IPv4;3=udp IPv6;4=unix domain socket;5=unix file socket |
local | 本地地址 |
remote | 远程地址 |
status | 连接状态,如ESTABLISHED等 |
传感器温度数据
该采集项用于采集主机上的传感器温度信息,如CPU温度、显卡温度等,内容如下:
采集项 | 描述 |
---|---|
name | 设备名称 |
temp | 温度,单位摄氏度 |
4 - SmartAgent老版本
实现原理
smartagent底层通过websocket协议进行服务端与客户端的RPC通信,同时通过内部的心跳机制来进行节点保活,从宏观上看agent的处理逻辑如下
- smartagent底层使用websocket协议与服务端进行连接,在连接过程中含有一次握手的过程,握手过程中agent会上报配置文件中的agent_id信息与当前操作系统信息,服务端在收到握手信息后会通过manifest.json中的描述信息来分发对应操作系统的插件
- 握手过程中若发现当前上报的agent_id已存在(当前活跃连接中已包含该agent_id的agent连接)则会返回握手失败消息并告知id冲突
- executor为插件执行器,在非windows操作系统下支持插件切换到其他用户身份运行
- smartagent使用containerd/cgroups库来限制linux系统下的资源使用,目前仅支持cgroups v1
Msg结构
Msg结构为smartagent底层通信的核心数据结构,其结构如下
type Msg struct {
Type TypeName `json:"type"` // 消息类型,详见消息类型章节
Important bool `json:"-"` // 是否是关键消息
TaskID string `json:"tid,omitempty"` // 任务ID
Plugin *PluginInfo `json:"plugin,omitempty"` // 所需调用的插件信息
ErrorMsg string `json:"errmsg,omitempty"` // 错误消息的详情
// ctrl
Come *ComePayload `json:"come,omitempty"` // 握手请求
Handshake *HandshakePayload `json:"handshake,omitempty"` // 握手返回结果
...
}
type字段是一个整数类型的字段,用于表明该消息的类型,目前已定义区段如下
0~9: 系统保留,用于服务端到agent通信 10+: 各插件使用
tid字段用于表明该消息的id
plugin字段用于表明该消息所需使用的插件信息,其中包含插件的版本号等,当agent收到的msg非系统消息且不包含plugin信息时该消息将被丢弃
type PluginInfo struct { Name string `json:"name"` // 插件名称 Version string `json:"version"` // 插件版本号 MD5 [md5.Size]byte `json:"md5"` // 插件文件的md5 URI string `json:"uri"` // 插件下载的uri }
在Msg结构的设计时,应尽量缩短字段名并增加omitempty关键字来忽略控制,以此来减少数据传输时的数据量
executor与插件化
executor是smartagent中的插件执行器,目前实现了以下功能:
下载并管理插件的可执行文件,当某个插件的低版本所有进程退出时进行旧版本文件清理
插件运行时参数配置信息生成,插件的运行参数将会被写入到临时文件内,插件运行参数通过临时文件尽心传递,在运行完毕后该临时文件将会被删除
插件运行时的日志将会通过stderr进行输出,executor在收集到日志后将会在每一行前面加上时间
插件返回数据可通过stdout进行输出,每一次插件运行允许输出多条数据,输出的格式如下
<length(4字节)><crc32(4字节)><payload>
插件的基本实现原理如下
4.1 - API接口文档
4.1.1 - 安装软件相关接口
4.1.1.1 - /install/run
参数
id
: 机器iduri
: 下载uri,可选url
: 下载url,可选dir
: 安装或解压路径,可选timeout
: 超时时间,单位秒,可选,默认300auth
: sudo、su或空值,可选user
: 账号,可选pass
: 密码,可选
返回值
{
"code": 0,
"payload": 任务ID
}
错误,未找到机器
{
"code": 404,
"msg": "client not found"
}
错误,其他运行时错误
{
"code": 500,
"msg": 错误内容
}
说明
dir
参数仅当msi
、exe
或压缩包时有效url
和uri
参数必须传一个,且uri
参数的优先级高于url
参数- 目前仅支持
deb
、rpm
、tar
、tar.gz
、tar.bz2
、zip
、msi
和exe
类型的安装包
4.1.1.2 - /install/status
参数
task_id
: 任务ID
返回值
{
"code": 0,
"payload": {
"done": 是否完成,
"actions": [
{
"action": 任务类型,
"name": 名称,
"time": 时间戳,
"ok": 是否成功,
"msg": 失败信息
}, ...
]
}
}
错误,任务不存在
{
"code": 404,
"msg": 错误信息
}
说明
- 任务类型包含以下几种:
download
: 下载安装包install
: 安装或解压安装包file
: 附加文件done
: 完成
name
字段定义:download
: 安装包下载路径install
: 安装包下载路径file
: 附加文件保存路径
4.1.2 - 插件相关接口
4.1.2.1 - /plugin/reload
参数
无
返回值
{
"code": 0
}
4.1.3 - 服务器端相关接口
4.1.3.1 - /server/info
参数
无
返回值
{
"code": 0,
"payload": {
"clients": 连接客户端数量,
"plugins": 插件数量,
"version": 版本号,
"created": 安装时间
}
}
4.1.4 - 节点相关接口
4.1.4.1 - /host/info
参数
id
: 机器ID
返回值
{
"code": 0,
"payload": {
"hostname": 主机名,
"os": linux或windows
}
}
4.1.4.2 - /host/list
参数
ids
: 需获取主机ID列表,可选,csv
返回值
{
"code": 0,
"payload": [
{
"id": 机器ID,
"version": agent版本号,
"ip": ip地址,
"mac": mac地址,
"os": 操作系统(windows或linux),
"platform": 操作系统名称(centos或debian),
"arch": 操作系统位数(amd64或i386)
}, ...
]
}
说明
- 当不传ids参数时表示获取所有主机列表,否则获取给定ID的列表,若给定ID不存在则忽略
4.1.4.3 - /host/search
参数
keyword
: IP地址或MAC地址
返回值
{
"code": 0,
"payload": 主机ID
}
错误,未找到
{
"code": 404,
"msg": "client not found"
}
4.1.5 - 流程编排相关接口
4.1.5.1 - /layout/run
参数
ids
: id列表,csv格式mode
: 执行顺序,可选,默认sequencecontinue
: 出错时是否继续,可选,默认为falsefile
: 资源文件tar包user
: 账号,可选pass
: 密码,可选
返回值
{
"code": 0,
"payload": 任务ID
}
错误,检测未通过
{
"code": 1,
"msg": 错误内容
}
错误,指定agentid未找到
{
"code": 404,
"msg": 错误内容
}
说明
mode
参数支持以下执行方式:sequence: 顺序执行,按给定的id列表顺序一个一个agent执行 parallel: 并发执行,按给定的id列表同时执行,此时continue参数无效 evenodd: 奇偶模式执行,按给定的id列表顺序分为两组,分别执行
上传的tar包中必须包含main.yaml或main.json文件作为执行时的编排文件
tar包中不允许包含软链文件,在解压时软链文件将被忽略
4.1.5.2 - /layout/status
参数
task_id
: 任务ID
返回值
{
"code": 0,
"payload": {
"done": 是否全部完成,
"created": 开始时间戳,
"finished": 结束时间戳未完成时为0,
"total_count": 总触达节点数量,
"finished_count": 完成节点数量,
"nodes": [
{
"id": 节点ID,
"created": 开始时间戳,
"finished": 结束时间戳未完成时为0,
"ok": 是否成功,
"msg": 错误信息
}, ...
]
}
}
错误,任务不存在
{
"code": 404,
"msg": 错误内容
}
4.1.6 - 命令行相关接口
4.1.6.1 - /cmd/kill
参数
id
: 机器idpid
: 进程id
返回值
{
"code": 0
}
错误,未找到机器
{
"code": 404,
"msg": "(client|process) not found"
}
4.1.6.2 - /cmd/ps
参数
id
: 机器ID
返回值
{
"code": 0,
"payload": [
{
"id": 进程ID,
"channel": 输出信息的管道ID,
"name": 进程名称,
"start_time": 进程创建时间戳,
"up_time": 启动时间(秒)
}, ...
]
}
错误,未找到机器
{
"code": 404,
"msg": "client not found"
}
4.1.6.3 - /cmd/pty
参数
id
: 机器IDpid
: 进程ID
返回值
http_code=200
body=内容
pid不存在
http_code=404
body=process not found
错误,其他异常
http_code=500
body=错误内容
4.1.6.4 - /cmd/run
参数
id
: 机器IDcmd
: 命令args
: 运行参数,csv,逗号用%2c%编码timeout
: 运行超时秒数,可选(默认3600)auth
: sudo、su或空值,可选user
: 账号,可选pass
: 密码,可选workdir
: 工作目录,可选env
: 环境变量,csv,逗号用%2c%编码defer_rm
: 运行完毕后删除的文件路径,可选callback
: 运行完毕后回调地址,可选
返回值
{
"code": 0,
"payload": {
"channel_id": "20220706-00002-f230bae72f2ca269", // 任务ID
"pid": 9655 // 进程id
}
}
错误,未找到机器
{
"code": 404,
"msg": "client not found"
}
错误,超时
{
"code": 408,
"msg": "timeout"
}
错误,命令执行失败
{
"code": 1,
"msg": "错误原因"
}
说明
- 当给定
defer_rm
参数时命令执行完毕后将会删除给定路径的文件 - 当给定
callback
参数时将会通过GET
的方式进行回调,同时将以下参数拼接在url内部agent_id
: 执行agent的IDpid
: 创建进程ID
4.1.6.5 - /cmd/status
参数
id
: 机器IDpid
: 进程ID
返回值
{
"code": 0,
"payload": {
"id": 进程ID,
"channel": 该进程的channel id,
"created": 进程创建时间,
"running": 该进程是否在执行中,
"code": 返回码(仅当running=false时有效)
}
}
错误,未找到机器或进程
{
"code": 404,
"msg": 错误内容
}
4.1.6.6 - /cmd/sync_run
参数
id
: 机器IDcmd
: 命令args
: 运行参数,csv,逗号用%2c%编码timeout
: 运行超时秒数,可选(默认60,最大60)auth
: sudo、su或空值,可选user
: 账号,可选pass
: 密码,可选workdir
: 工作目录,可选env
: 环境变量,csv,逗号用%2c%编码defer_rm
: 运行完毕后删除的文件路径,可选
返回值
{
"code": 0,
"payload": {
"code": 0, // 返回码(-65535表示执行失败或超时)
"data": "aGVsbG8gd29ybGQ=", // 返回内容经过base64编码
}
}
错误,未找到机器
{
"code": 404,
"msg": "client not found"
}
错误,超时
{
"code": 408,
"msg": "timeout"
}
错误,命令执行失败
{
"code": 1,
"msg": "错误原因"
}
说明
- 当给定
defer_rm
参数时当命令执行完毕后将会执行对应操作
4.1.7 - 日志采集相关接口
4.1.7.1 - /logging/config
参数
pid
: 项目IDtype
: k8s、docker、logtail中的任意一个exclude
: 去除日志的正则,可选batch
: 批量上报条数,默认1000buffer
: 批量上报数据量,单位字节,默认4096interval
: 批量上报间隔超时时间,单位秒,默认30
k8s参数
ns
: 所需采集的namespacename
: 所需采集的项目名,csvdir
: 文件路径,支持通配符api
: k8s接口地址token
: k8s采集时所需的token信息
docker参数
ids
: 目标机器id,csvct_name
: 容器名称ct_tag
: 容器tag,可选dir
: 文件路径,支持通配符
logtail参数
ids
: 目标机器id,csvdir
: 文件路径,支持通配符
返回值
{
"code": 0
}
错误:没有可用的采集节点
{
"code": 1,
"msg": 错误内容
}
说明
- 当
type
参数为k8s
或docker
且dir
参数为空时表示采集该容器的stdout输出信息
4.1.7.2 - /logging/remove
参数
pid
: 项目ID
返回值
{
"code": 0
}
错误,任务不存在
{
"code": 404,
"msg": 错误内容
}
4.1.7.3 - /logging/start
参数
pid
: 项目ID
返回值
{
"code": 0
}
错误,项目已启动
{
"code": 1,
"msg": 错误内容
}
错误,任务不存在
{
"code": 404,
"msg": 错误内容
}
4.1.7.4 - /logging/stop
参数
pid
: 项目ID
返回值
{
"code": 0
}
错误,项目未启动
{
"code": 1,
"msg": 错误内容
}
错误,任务不存在
{
"code": 404,
"msg": 错误内容
}
4.1.7.5 - /logging/task_info
参数
pid
: 项目ID
返回值
{
"code": 0,
"payload": {
"type": 任务类型,
"exclude": 去除日志的正则,
"batch": 批量上报条数,
"buffer": 批量上报数据量,
"interval": 批量上报间隔超时时间,
"created": 创建时间戳,
"nodes": [
{
"id": 节点ID,
"status": running或stoped,
"info": [
{ // k8s
"ns": namespace,
"name": 项目名,
"dir": 文件路径,
"pods": 上一次采集时的pod数量,定期上报
},
{ // docker
},
{ // file
"dir": 文件路径
}, ...
]
}, ...
]
}
}
}
错误,任务不存在
{
"code": 404,
"msg": 错误内容
}
4.1.8 - 文件操作相关接口
4.1.8.1 - /file/download
参数
id
: 机器iddir
: 文件路径timeout
: 超时事件,默认10分钟
返回值
文件内容
错误,未找到机器或文件
http_code=404
body=(client/file) not found
错误,超时
http_code=408
body=timeout
错误,校验码错误
http_code=409
body=invalid checksum
错误,运行时错误
http_code=503
body=错误内容
4.1.8.2 - /file/ls
参数
id
: 机器IDdir
: 目录
返回值
{
"code": 0,
"payload": {
"dir": 目录,
"files": [
{
"name": 名称,
"auth": 权限,
"user": 所属用户,
"group": 所属组,
"size": 文件大小,
"mod_time": 更新时间戳,
"is_dir": 是否是目录,
"is_link": 是否是软链
}, ...
]
}
}
错误,未找到机器或目录不存在
{
"code": 404,
"msg": "(client/directory) not found"
}
错误,超时
{
"code": 408,
"msg": "timeout"
}
错误,其他错误
{
"code": 500,
"msg": 错误内容
}
4.1.8.3 - /file/upload_from
参数
id
: 机器iddir
: 保存位置name
: 文件名uri
: 下载uriauth
: sudo、su或空值,可选user
: 账号,可选pass
: 密码,可选mod
: 文件权限,十进制,可选,默认0644own_user
: 文件所属用户own_group
: 文件所属分组timeout
: 超时时间,单位秒,可选,默认60
返回值
{
"code": 0,
"payload": {
"dir": 文件存放路径
}
}
错误,未找到机器
{
"code": 404,
"msg": "client not found"
}
错误,其他运行时错误
{
"code": 500,
"msg": 错误内容
}
错误,上传失败
{
"code": 1,
"msg": 错误内容
}
错误,文件内容错误
{
"code": 2,
"msg": 错误内容
}
4.1.8.4 - /file/upload
参数
id
: 机器iddir
: 保存位置auth
: sudo、su或空值,可选user
: 账号,可选pass
: 密码,可选mod
: 文件权限,十进制,可选,默认0644own_user
: 文件所属用户own_group
: 文件所属分组file
: http标准文件上传字段timeout
: 超时时间,单位秒,可选,默认60md5
: 文件md5,可选
返回值
{
"code": 0,
"payload": null
}
错误,未找到机器
{
"code": 404,
"msg": "client not found"
}
错误,其他运行时错误
{
"code": 500,
"msg": 错误内容
}
错误,上传失败
{
"code": 1,
"msg": 错误内容
}
错误,文件内容错误
{
"code": 2,
"msg": 错误内容
}
4.1.9 - 主机信息采集相关接口
4.1.9.1 - /hm/static
参数
id
: 机器ID
返回值
{
"code": 0,
"payload": {
"timestamp": 上报时间戳,
"host_name": 主机名,
"uptime": 启动时长,
"os_name": 系统类型,linux、windows,
"platform": 系统名称,如debian、centos,
"platform_version": 系统版本号,
"kernel_arch": 内核类型,如i386、amd64,
"kernel_version": 内核版本,如3.10.0-1062.el7.x86_64,
"physical_core": 物理核心数,
"logical_core": 逻辑核心数,
"cores": [
{
"processor": 该核心编号,
"model": 名称,如Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz,
"core": 所在物理核上的编号,
"cores": 某块CPU上的编号,
"physical": 物理CPU编号
}, ...
]
"physical_memory": 物理内存大小,
"swap_memory": swap内存大小,
"disks": [
{
"name": 名称,linux为挂载路径如/run,windows为盘符如C:,
"type": 文件系统类型,如NTFS,
"options": [附加参数,如rw,nosuid,nodev, ...],
"total": 总容量,
"inodes": inode数量
}, ...
],
"intfs": [
{
"index": 编号,
"name": 名称,
"mtu": mtu,
"flags": [附加信息, ...],
"mac": mac地址,
"addrs": [ip地址, ...],
}, ...
]
}
}
错误,未找到机器
{
"code": 404,
"msg": "client not found"
}
错误,超时
{
"code": 408,
"msg": "timeout"
}