diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b639f68ef81e47f5d1ca0c3e13497b3d586b058e Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore index cab19059ca54dc1e96fa511dc0e71aecdb6998a5..40a844cf97c51e9911797ce9870e063f2b71d5ed 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ *.o.cmd *.ko *.ko.cmd - +*.idea Module.symvers modules.builtin modules.order diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..13566b81b018ad684f3a35fee301741b2734c8f4 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000000000000000000000000000000000000..53624c9e1f9ab0331fd10b32c26747519ace5794 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,18 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000000000000000000000000000000000000..35eb1ddfbbc029bcab630581847471d7f238ec53 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/source/.DS_Store b/source/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..fe62bc3d37d7e43ee3c765a76137456f136a5618 Binary files /dev/null and b/source/.DS_Store differ diff --git a/source/lib/internal/ebpf/coolbpf b/source/lib/internal/ebpf/coolbpf index ae774b805b2185fcbfafb71457ad1e37065466ff..d0fabf821d2d8eb9d27da8eefd4797dc181cc92b 160000 --- a/source/lib/internal/ebpf/coolbpf +++ b/source/lib/internal/ebpf/coolbpf @@ -1 +1 @@ -Subproject commit ae774b805b2185fcbfafb71457ad1e37065466ff +Subproject commit d0fabf821d2d8eb9d27da8eefd4797dc181cc92b diff --git a/source/tools/.DS_Store b/source/tools/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..12272494a9145ab77e6821d51a35aa9e656937e1 Binary files /dev/null and b/source/tools/.DS_Store differ diff --git a/source/tools/monitor/.DS_Store b/source/tools/monitor/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..54403a1caa441bc5047ab36847f73aef327fef34 Binary files /dev/null and b/source/tools/monitor/.DS_Store differ diff --git a/source/tools/monitor/unity/beaver/guide/metrics.md b/source/tools/monitor/unity/beaver/guide/metrics.md index 2a84de2e195bf81422273d17b47285bf76f9ab9e..f8984bef0f903ce571b8713c024d1c702caf63d6 100644 --- a/source/tools/monitor/unity/beaver/guide/metrics.md +++ b/source/tools/monitor/unity/beaver/guide/metrics.md @@ -6,28 +6,128 @@ ------------- -### uptime 表 +### cpu\_total 表 + +* 对应export 指标 sysak\_proc\_cpu\_total +* 属性标签: mode + | 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | | :--- | ---: | :---- | :---- | :--- | -| uptime | 秒 | 从系统启动到现在的时间 | | collector/proc\_uptime.lua | -| idletime | 秒 | 系统总空闲的时间 | | collector/proc\_uptime.lua | -| stamp | 秒 | 系统时间戳 | unix 时间 | collector/proc\_uptime.lua | +| softirq | % | 软中断百分比 | | collector/proc\_stat.lua | +| user | % | 用户态占用率百分比 | | collector/proc\_stat.lua | +| guestnice | % | guestnice百分比 | | collector/proc\_stat.lua | +| guest | % |guest百分比 | | collector/proc\_stat.lua | +| steal | % |steal百分比 | | collector/proc\_stat.lua | +| hardirq | % | 硬中断百分比 | | collector/proc\_stat.lua | +| nice | % | nice百分比 | | collector/proc\_stat.lua | +| idle | % | idle百分比 | | collector/proc\_stat.lua | +| sys | % | sys百分比 | | collector/proc\_stat.lua | +| iowait | % | iowait百分比 | | collector/proc\_stat.lua | + +### cpus 表 + +* 对应export 指标 sysak\_proc\_cpus +* 属性标签: mode -### uname 表 -每小时获取一次 +| 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | +| :--- | ---: | :---- | :---- | :--- | +| cpu_name | | CPU 名称 | | collector/proc\_stat.lua | +| softirq | % | 软中断百分比 | | collector/proc\_stat.lua | +| user | % | 用户态占用率百分比 | | collector/proc\_stat.lua | +| guestnice | % | guestnice百分比 | | collector/proc\_stat.lua | +| guest | % |guest百分比 | | collector/proc\_stat.lua | +| steal | % |steal百分比 | | collector/proc\_stat.lua | +| hardirq | % | 硬中断百分比 | | collector/proc\_stat.lua | +| nice | % | nice百分比 | | collector/proc\_stat.lua | +| idle | % | idle百分比 | | collector/proc\_stat.lua | +| sys | % | sys百分比 | | collector/proc\_stat.lua | +| iowait | % | iowait百分比 | | collector/proc\_stat.lua | + + +### cpus 表 + +* 对应export 指标 sysak\_proc\_cpus +* 属性标签: mode + + +| 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | +| :--- | ---: | :---- | :---- | :--- | +| cpu_name | | CPU 名称 | | collector/proc\_stat.lua | +| softirq | % | 软中断百分比 | | collector/proc\_stat.lua | +| user | % | 用户态占用率百分比 | | collector/proc\_stat.lua | +| guestnice | % | guestnice百分比 | | collector/proc\_stat.lua | +| guest | % |guest百分比 | | collector/proc\_stat.lua | +| steal | % |steal百分比 | | collector/proc\_stat.lua | +| hardirq | % | 硬中断百分比 | | collector/proc\_stat.lua | +| nice | % | nice百分比 | | collector/proc\_stat.lua | +| idle | % | idle百分比 | | collector/proc\_stat.lua | +| sys | % | sys百分比 | | collector/proc\_stat.lua | +| iowait | % | iowait百分比 | | collector/proc\_stat.lua | + + +### stat\_counters表 + +* 对应export 指标 sysak\_proc\_stat\_counters +* 属性标签: counter + +| 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | +| :--- | ---: | :---- | :---- | :--- | +| procs_blocked | | D状态任务数量 | | collector/proc\_stat.lua | +| processes_forks | | fork 任务数量 | | collector/proc\_stat.lua | +| btime | | 启动时间 | | collector/proc\_stat.lua | +| procs_running | | 并行任务数量 | | collector/proc\_stat.lua | +| ctxt | | 上下文切换次数 | | collector/proc\_stat.lua | + + +### proc\_loadavg 表 + +* 对应 export 指标: sysak\_proc\_loadavg +* 属性标签:value | 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | |:---------| ---: | :---- | :---- | :--- | -| nodename | - | uname -r | | collector/proc\_uptime.lua | -| version | - | uname -r | | collector/proc\_uptime.lua | -| release | - | uname -r | | collector/proc\_uptime.lua | -| machine | - | uname -r | | collector/proc\_uptime.lua | -| sysname | - | uname -r | | collector/proc\_uptime.lua | +| runq | - | rq队列长度 | | collector/proc\_load.lua | +| load1 | - | load1 | | collector/proc\_load.lua | +| load5 | - | load5 | | collector/proc\_load.lua | +| load10 | - | load10 | | collector/proc\_load.lua | +| plit | - | plit | | collector/proc\_load.lua | + + +### proc\_loadavg 表 + +* 对应 export 指标: sysak\_proc\_loadavg +* 属性标签:value + +| 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | +|:---------| ---: | :---- | :---- | :--- | +| runq | - | rq队列长度 | | collector/proc\_load.lua | +| load1 | - | load1 | | collector/proc\_load.lua | +| load5 | - | load5 | | collector/proc\_load.lua | +| load10 | - | load10 | | collector/proc\_load.lua | +| plit | - | plit | | collector/proc\_load.lua | + + +### meminfo 表 + +* 对应 export 指标: sysak\_proc\_meminfo +* 属性标签:value + +指标说明参考[/proc/meminfo内存文件详解](https://zhuanlan.zhihu.com/p/145524701) + +### vmstat 表 + +* 对应 export 指标: sysak\_proc\_vmstate +* 属性标签:value + +指标说明参考[/proc/vmstat输出含义](https://blog.csdn.net/kaka__55/article/details/125236633) ### cgroups 表 +* 对应 export 指标: sysak\_cgroups +* 属性标签:value + | 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | | :--- | --- | :---- | :---- | :--- | | type | - | subsys类型 | | collector/proc\_cgroups.lua | @@ -46,6 +146,9 @@ ### interrupts 表 +* 对应 export 指标: sysak\_interrupts +* 属性标签:value + | 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | | :--- | --- | :---- | :---- | :--- | | cpu | - | CPU ID | | collector/proc\_interrupts.lua | @@ -53,6 +156,9 @@ ### mounts 表 +* 对应 export 指标: sysak\_fs\_stat +* 属性标签:value + | 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | | :--- | --- | :---- | :---- | :--- | | fs | - | sysfs | | collector/proc\_mounts.lua | @@ -67,6 +173,9 @@ ### softirqs 表 +* 对应 export 指标: sysak\_softirqs +* 属性标签:value + | 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | | :--- | --- | :---- | :---- | :--- | | cpu | - | CPU ID | | collector/proc\_softirqs.lua | @@ -82,7 +191,10 @@ | RCU | 次 | RCU软中断触发次数 | | collector/proc\_softirqs.lua | ### self_statm 表 -统计监控进程的statm信息 + +* 统计监控进程的statm信息 +* 对应 export 指标: sysak\_self\_statm +* 属性标签:value | 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | | :--- | --- | :---- | :---- | :--- | @@ -100,13 +212,18 @@ ### arp +* 对应 export 指标: sysak\_arp +* 属性标签:value + | 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | | :--- | ---: | :---- | :---- | :--- | | count | 个 | 网卡名 | 网卡上对应arp表数量 | collector/proc\_arp.lua | ### networks -这是网卡流量统计信息,已做差值处理 +* 这是网卡流量统计信息,已做差值处理 +* 对应 export 指标: sysak\_proc\_networks +* 属性标签:value | 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | | :--- | ---: | :---- | :---- | :--- | @@ -129,7 +246,9 @@ ### pkt_status -这里统计所有包状态,详细可以通过 pkt_logs 获取 +* 对应 export 指标: sysak\_proc\_pkt\_status +* 属性标签:counter +* 这里统计所有包状态,详细可以通过 pkt\_logs 获取 | 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | | :--- | ---: | :---- | :---- | :--- | @@ -143,6 +262,9 @@ ### sock_stat +* 对应 export 指标: sysak\_sock\_stat +* 属性标签:value + 统计所有包状态。[参考连接](https://developer.aliyun.com/article/484451) | 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | @@ -163,7 +285,8 @@ ### softnets -This parser parses the stats from network devices. These stats includes events per cpu\(in row\), number of packets processed i.e packet_process \(first column\), number of packet drops packet\_drops \(second column\), time squeeze eg net\_rx\_action performed time_squeeze\(third column\), cpu collision eg collision occur while obtaining device lock while transmitting cpu\_collision packets \(eighth column\), received_rps number of times cpu woken up received\_rps \(ninth column\), number of times reached flow limit count flow\_limit\_count \(tenth column\), backlog status \(eleventh column\), core id \(twelfth column\). +* 对应 export 指标: sysak\_softnets +* 属性标签:value | 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | | :--- | ---: | :---- | :---- | :--- | @@ -176,6 +299,9 @@ This parser parses the stats from network devices. These stats includes events p ### cgroups 表 +* 对应 export 指标: sysak\_cgroups +* 属性标签:value + | 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | | :--- | --- | :---- | :---- | :--- | | type | - | subsys类型 | | collector/proc\_cgroups.lua | @@ -192,56 +318,6 @@ This parser parses the stats from network devices. These stats includes events p | perf\_event | 个 | perf_event cgroup数量 | | collector/proc\_cgroups.lua | | memory | 个 | memory cgroup数量 | | collector/proc\_cgroups.lua | -### interrupts 表 - -| 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | -| :--- | --- | :---- | :---- | :--- | -| cpu | - | CPU ID | | collector/proc\_interrupts.lua | -| 中断名称 | 次 | 中断触发次数 | | collector/proc\_interrupts.lua | - -### mounts 表 - -| 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | -| :--- | --- | :---- | :---- | :--- | -| fs | - | sysfs | | collector/proc\_mounts.lua | -| mount | - | 挂载目录 | | collector/proc\_mounts.lua | -| f\_bsize | - | Filesystem block size | | collector/proc\_mounts.lua | -| f\_blocks | - | Size of fs in f_frsize units | | collector/proc\_mounts.lua | -| f\_bfree | - | Number of free blocks | | collector/proc\_mounts.lua | -| f\_bavail | - | Number of free blocks for unprivileged users | | collector/proc\_mounts.lua | -| f\_files | - | Number of inodes | | collector/proc\_mounts.lua | -| f\_ffree | - | Number of free inodes | | collector/proc\_mounts.lua | -| f\_favail | - | Number of free inodes for unprivileged users | | collector/proc\_mounts.lua | - -### softirqs 表 - -| 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | -| :--- | --- | :---- | :---- | :--- | -| cpu | - | CPU ID | | collector/proc\_softirqs.lua | -| HI | 次 | HI软中断触发次数 | | collector/proc\_softirqs.lua | -| TIMER | 次 | TIMER软中断触发次数 | | collector/proc\_softirqs.lua | -| NET\_TX | 次 | NET\_TX软中断触发次数 | | collector/proc\_softirqs.lua | -| NET\_RX | 次 | NET\_RX软中断触发次数 | | collector/proc\_softirqs.lua | -| BLOCK | 次 | BLOCK软中断触发次数 | | collector/proc\_softirqs.lua | -| IRQ_POLL | 次 | IRQ\_POLL软中断触发次数 | | collector/proc\_softirqs.lua | -| TASKLET | 次 | TASKLET软中断触发次数 | | collector/proc\_softirqs.lua | -| SCHED | 次 | SCHED软中断触发次数 | | collector/proc\_softirqs.lua | -| HRTIMER | 次 | HRTIMER软中断触发次数 | | collector/proc\_softirqs.lua | -| RCU | 次 | RCU软中断触发次数 | | collector/proc\_softirqs.lua | - -### self_statm 表 -统计监控进程的statm信息 - -| 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | -| :--- | --- | :---- | :---- | :--- | -| size | - | total program size | | collector/proc\_statm.lua | -| resident | - | resident set size | | collector/proc\_statm.lua | -| shared | - | number of resident shared pages | | collector/proc\_statm.lua | -| text | - | text (code) | | collector/proc\_statm.lua | -| lib | - | library | | collector/proc\_statm.lua | -| data | - | data + stack | | collector/proc\_statm.lua | -| dt | - | dirty pages | | collector/proc\_statm.lua | - ## IO指标 @@ -275,12 +351,20 @@ This parser parses the stats from network devices. These stats includes events p ----------- ### cg_cpu_stat 表 + +* 对应 export 指标: sysak\_ +* 属性标签:value + | 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | | :--- | --- | :---- | :---- | :--- | | nr_throttled | - | total throttled number | | collector/container/cg\_cpu\_stat.lua | | throttled_time | ms | total throttled time | | collector/container/cg\_cpu\_stat.lua | ### cg_proc_stat 表 + +* 对应 export 指标: sysak\_ +* 属性标签:value + | 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | | :--- | --- | :---- | :---- | :--- | | user | % | usr cpu util | | collector/container/cg\_cpuacct\_proc\_stat.lua | @@ -302,11 +386,19 @@ This parser parses the stats from network devices. These stats includes events p | nr_uninterruptible | - | number of deep sleep tasks | | collector/container/cg\_cpuacct\_proc\_stat.lua | ### cg_memfail_cnt 表 + +* 对应 export 指标: sysak\_ +* 属性标签:value + | 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | | :--- | --- | :---- | :---- | :--- | | fail_cnt | - | number of mem fail counts | | collector/container/cg\_memory\_fail\_cnt.lua | ### cg_memdrcm_latency 表 + +* 对应 export 指标: sysak\_ +* 属性标签:value + This table show the hist of the latency of direct memory reclamation | 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | | :--- | --- | :---- | :---- | :--- | @@ -318,6 +410,10 @@ This table show the hist of the latency of direct memory reclamation | memDrcm_lat_1000ms | - | times more than 1s | | collector/container/cg\_memory\_drcm\_latency.lua | ### cg_memmcmp_latency 表 + +* 对应 export 指标: sysak\_ +* 属性标签:value + This table show the hist of the latency of direct memory compaction | 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | | :--- | --- | :---- | :---- | :--- | @@ -329,6 +425,10 @@ This table show the hist of the latency of direct memory compaction | memDcmp_lat_1000ms | - | times more than 1s | | collector/container/cg\_memory\_dcmp\_latency.lua | ### pmu_events 表 + +* 对应 export 指标: sysak\_ +* 属性标签:value + | 指标名 | 单位 | 标签说明 | 备注 | 源码路径 | | :--- | --- | :---- | :---- | :--- | | cpu_cycles | - | cycles | | collector/plugin/pmu_events/pmu\_events.c | diff --git a/source/tools/monitor/unity/beaver/guide/outLine.md b/source/tools/monitor/unity/beaver/guide/outLine.md index 22a77dcd9ed46f9fdd6cebba7f18815a4dd367f4..d1788e81a59a0ddf18f1454bf11aec293fb0b627 100644 --- a/source/tools/monitor/unity/beaver/guide/outLine.md +++ b/source/tools/monitor/unity/beaver/guide/outLine.md @@ -1,9 +1,11 @@ # 外部数据写入支持 -unity-mon可以作为一个独立的TSDB 数据库进行使用,支持[行协议](https://jasper-zhang1.gitbooks.io/influxdb/content/Write_protocols/line_protocol.html)写入数据,并按需完成对外数据吐出。 +unity-mon可以作为一个独立的TSDB 数据库进行使用,支持[行协议](https://jasper-zhang1.gitbooks.io/influxdb/content/Write_protocols/line_protocol.html)写入数据,并按需完成对外数据吐出,如exporter等接口。 ## 行协议格式支持情况 unity-mon 当前除了不支持时间戳,支持行协议其它所有的数据类型,包含数值和日志。写行数据时,有以下注意事项: +* 指标写入周期需要与大循环刷新周期保持一致,参考 yaml/config/freq 参数配置; + * 不要将同一表名和同一索引,但数值不同的数据放在同一批次写入操作中,会发生时序数据覆盖,如; ``` @@ -18,7 +20,7 @@ talbe_a,index=table_a value1=1,value2=2 talbe_a,index=table_b value1=3,value2=4 ``` -不要出现同一张表,但是写入的索引和数值不的情况,如: +* 不要出现同一张表,但是写入的索引和数值不的情况,如: ``` talbe_a,index=table_a value1=1 @@ -34,7 +36,7 @@ unity-mon 同时支持管道和http post 两种方式进行写入,两者差别 | --- | --- | --- | | 适用范围 | 内部 | 内部 + 外部 | | 写入效率 | 高 | 低 | -| 最大写入数据长度 | 64K | 2M | +| 最大单次写入数据长度 | 64K | 2M | 使用者可以结合自己的实际情况进行推送 diff --git a/source/tools/monitor/unity/beaver/localBeaver.lua b/source/tools/monitor/unity/beaver/localBeaver.lua index 22d679e88f44942c0f7071341771cc4ae2d6f4c7..d0c2c5dea9dbafc1eeed5e4c0f23384d562090cc 100644 --- a/source/tools/monitor/unity/beaver/localBeaver.lua +++ b/source/tools/monitor/unity/beaver/localBeaver.lua @@ -23,12 +23,17 @@ end function CLocalBeaver:_init_(frame, fYaml) local port, ip, backlog, unix_socket = setupServer(fYaml) + self:_installFFI() if not unix_socket then self._bfd = self:_install_fd(port, ip, backlog) else self._bfd = self:_install_fd_unisock(backlog, unix_socket) end - self._efd = self:_installFFI() + --self._efd = self:_installFFI() + + local efd = self._cffi.init(self._bfd) + assert(efd > 0) + self._efd = efd self._cos = {} self._last = os.time() @@ -85,18 +90,16 @@ function CLocalBeaver:_installFFI() self._ffi = ffi.ffi self._cffi = ffi.cffi - local efd = self._cffi.init(self._bfd) - assert(efd > 0) - return efd end -local function localBind(fd, tPort) +local function localBind(cffi, fd, tPort) local try = 0 local res, err, errno -- can reuse for time wait socket. - res, err, errno = socket.setsockopt(fd, socket.SOL_SOCKET, socket.SO_REUSEADDR, 1); - if not res then + --res, err, errno = socket.setsockopt(fd, socket.SOL_SOCKET, socket.SO_REUSEADDR, 1); + res = cffi.setsockopt_AP(fd) + if res<0 then system:posixError("set sock opt failed."); end @@ -120,7 +123,7 @@ function CLocalBeaver:_install_fd_unisock(backlog,unix_socket) fd, err, errno = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0) if fd then -- for socket local tPort = {family=socket.AF_UNIX, path=unix_socket} - local r, msg = pcall(localBind, fd, tPort) + local r, msg = pcall(localBind, self._cffi, fd, tPort) if r then res, err, errno = socket.listen(fd, backlog) if res then -- for listen @@ -130,7 +133,7 @@ function CLocalBeaver:_install_fd_unisock(backlog,unix_socket) system:posixError("socket listen failed", err, errno) end else - print(msg) + print("call localBind failed, report: " .. msg) unistd.close(fd) os.exit(1) end @@ -144,7 +147,7 @@ function CLocalBeaver:_install_fd(port, ip, backlog) fd, err, errno = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) if fd then -- for socket local tPort = {family=socket.AF_INET, addr=ip, port=port} - local r, msg = pcall(localBind, fd, tPort) + local r, msg = pcall(localBind, self._cffi, fd, tPort) if r then res, err, errno = socket.listen(fd, backlog) if res then -- for listen @@ -154,7 +157,7 @@ function CLocalBeaver:_install_fd(port, ip, backlog) system:posixError("socket listen failed", err, errno) end else - print(msg) + print("call localBind failed, report: " .. msg) unistd.close(fd) os.exit(1) end diff --git a/source/tools/monitor/unity/beaver/native/beavercffi.lua b/source/tools/monitor/unity/beaver/native/beavercffi.lua index a3d00f11323f881ea57719cd822494ba9eb2b92e..9aa9cef9289cba53c4b7cc66be400eca94f88051 100644 --- a/source/tools/monitor/unity/beaver/native/beavercffi.lua +++ b/source/tools/monitor/unity/beaver/native/beavercffi.lua @@ -24,6 +24,7 @@ int add_fd(int efd, int fd); int mod_fd(int efd, int fd, int wr); int del_fd(int efd, int fd); int poll_fds(int efd, int tmo, native_events_t* nes); +int setsockopt_AP(int fd); void deinit(int efd); ]] diff --git a/source/tools/monitor/unity/beaver/native/local_beaver.c b/source/tools/monitor/unity/beaver/native/local_beaver.c index 641e8837fffa6c406c80d432fb63b43c1bc4530a..634907813f204e4027c2d695bfde37047835fc9b 100644 --- a/source/tools/monitor/unity/beaver/native/local_beaver.c +++ b/source/tools/monitor/unity/beaver/native/local_beaver.c @@ -4,6 +4,7 @@ #include "local_beaver.h" #include +#include #include #include #include @@ -11,6 +12,16 @@ #include #include +int setsockopt_AP(int fd){ + int opt =1; + int r = setsockopt(fd, SOL_SOCKET,SO_REUSEPORT,(char*)&opt,sizeof(int)); +// SO_REUSEPORT + if(r<0){ + perror("set sock opt"); + } + return r; +} + static int socket_non_blocking(int sfd) { int flags, res; diff --git a/source/tools/monitor/unity/beaver/url_api.lua b/source/tools/monitor/unity/beaver/url_api.lua index e54fa5c3d1b8a03b69e7a6b0237edbae0e4c5f9d..47389f6b62f50270bd5694a1fdf27054caaa33cc 100644 --- a/source/tools/monitor/unity/beaver/url_api.lua +++ b/source/tools/monitor/unity/beaver/url_api.lua @@ -45,11 +45,11 @@ local function reqOSS(oss, uuid, stream) end function CurlApi:oss(tReq) - local stat, tJson = pcall(self.getJson, self, tReq) - if stat and tJson then - local uuid = tJson.uuid - local stream = tJson.stream - if uuid and stream then + local uuid = tReq.header['uuid'] + local cLen = tonumber(tReq.header['content-length']) + if uuid and cLen and cLen > 0 then + local stream = tReq.data + if stream then local stat, body = pcall(reqOSS, self._oss, uuid, stream) if stat then return body @@ -57,10 +57,10 @@ function CurlApi:oss(tReq) return "bad req dns " .. body, 400 end else - return "need uuid and stream arg.", 400 + return "need stream arg.", 400 end else - return "bad dns " .. tReq.data, 400 + return "need uuid and content-length > 0." .. tReq.data, 400 end end diff --git a/source/tools/monitor/unity/beeQ/clock/ee_clock.c b/source/tools/monitor/unity/beeQ/clock/ee_clock.c index 3ccebd204062d102d3aef1bb3bb337d505d52d19..37e5df54a59a81f07a41aa33fb71b14ae8b012e6 100644 --- a/source/tools/monitor/unity/beeQ/clock/ee_clock.c +++ b/source/tools/monitor/unity/beeQ/clock/ee_clock.c @@ -7,8 +7,10 @@ #include #include #include +#include #define TIME_SECOND_UNIT 100000UL // 睡眠校准时间, +#define MICRO_UNIT (1000 * 1000UL) static ee_clock_t clk_coef = 0; @@ -20,24 +22,43 @@ static ee_clock_t get_cycles() { return res; } +ee_clock_t get_native_us(void) { + ee_clock_t res = 0; + struct timeval tv; + + if (gettimeofday(&tv, NULL) == 0) { + res = tv.tv_sec * MICRO_UNIT + tv.tv_usec; + } + return res; +} + // 校准时钟 int calibrate_local_clock(){ ee_clock_t coef1, coef2; - ee_clock_t t1, t2, t3; + ee_clock_t t1, t2; + ee_clock_t ts1, ts2; ee_clock_t delta1, delta2; + ee_clock_t dts1, dts2; ee_clock_t res; t1 = get_cycles(); + ts1 = get_native_us(); usleep(TIME_SECOND_UNIT); t2 = get_cycles(); - usleep(TIME_SECOND_UNIT); - t3 = get_cycles(); - + ts2 = get_native_us(); delta1 = t2 - t1; - delta2 = t3 - t2; + dts1 = ts2 - ts1; + + t1 = get_cycles(); + ts1 = get_native_us(); + usleep(TIME_SECOND_UNIT); + t2 = get_cycles(); + ts2 = get_native_us(); + delta2 = t2 - t1; + dts2 = ts2 - ts1; - coef1 = delta1 / TIME_SECOND_UNIT; - coef2 = delta2 / TIME_SECOND_UNIT; + coef1 = delta1 / dts2; + coef2 = delta2 / dts1; if (coef1 <= 100 || coef2 <= 100) { fprintf(stderr, "read clock too small.\n"); @@ -47,6 +68,7 @@ int calibrate_local_clock(){ res = 100 * coef1 / coef2; if (res >= 110 || res <= 90) { fprintf(stderr, "calibrate local clock failed.\n"); + fprintf(stderr, "delta1: %ld, delta2: %ld, dts1: %ld, dts2: %ld.\n", delta1, delta2, dts1, dts2); return -EIO; } diff --git a/source/tools/monitor/unity/beeQ/foxRecv.lua b/source/tools/monitor/unity/beeQ/foxRecv.lua index 1e3c2dd62b45d75c7d5cfca275483187259279d7..fb3323dc01f12afbe3c493217b36fac819bdea05 100644 --- a/source/tools/monitor/unity/beeQ/foxRecv.lua +++ b/source/tools/monitor/unity/beeQ/foxRecv.lua @@ -24,6 +24,9 @@ local function setupCo(fYaml) fcntl.fcntl(fdIn, 1031, 1024 * 1024) fcntl.fcntl(fdOut, 1031, 1024 * 1024) + + system:fdNonBlocking(fdOut) + lua_push_start(fdIn) return fdIn, fdOut end @@ -50,11 +53,19 @@ function CfoxRecv:_del_() end end -function CfoxRecv:outToFd(stream) +local function pipeOut(fd, stream) local len = #stream local s = struct.pack("mtx); if (q->stop) { @@ -243,11 +244,14 @@ int beeQ_send(struct beeQ *q, void *msg) { } if (isempty(q)) { - pthread_cond_signal(&q->cond); // need to wakeup. + wake = 1; } q->send = (q->send + 1) % q->size; q->msgs[q->send] = msg; pthread_mutex_unlock(&q->mtx); + if (wake) { + pthread_cond_signal(&q->cond); // need to wakeup. + } return 0; } diff --git a/source/tools/monitor/unity/collector/btfLoader.lua b/source/tools/monitor/unity/collector/btfLoader.lua index c9354b8339ec56c9dfbed911a43003c7e37af043..44770eaf3931caab1276c09ed9003e90c5a2726e 100644 --- a/source/tools/monitor/unity/collector/btfLoader.lua +++ b/source/tools/monitor/unity/collector/btfLoader.lua @@ -70,7 +70,7 @@ local function downKo(path, name, region, machine, release) end function CbtfLoader:_init_(root) - local distro = utsname.uname() + --local distro = utsname.uname() if distro then local release, machine = distro.release, distro.machine local path = '/boot/vmlinux-' .. release diff --git a/source/tools/monitor/unity/collector/container/cg_memory_util.lua b/source/tools/monitor/unity/collector/container/cg_memory_util.lua new file mode 100644 index 0000000000000000000000000000000000000000..54316714212fbe234af962f080fabc8d31997e4a --- /dev/null +++ b/source/tools/monitor/unity/collector/container/cg_memory_util.lua @@ -0,0 +1,80 @@ +require("common.class") +local pystring = require("common.pystring") +local CvProc = require("collector.vproc") +local root = "sys/fs/cgroup/memory/" +local dfile = "/memory.stat" +local usage = "/memory.usage_in_bytes" +local limit = "/memory.limit_in_bytes" +local system = require("common.system") + +local CgMemUtil = class("cg_memory_util", CvProc) + +--ls{}, (pod_name and docker_name +function CgMemUtil:_init_(proto, pffi, mnt, path, ls) + CvProc._init_(self, proto, pffi, mnt, root .. path .. dfile) + self.ls = ls + self.path = mnt..root..path..dfile + self.limitpath = mnt..root..path..limit + self.usagepath = mnt..root..path..usage + self.limit = 0 + self.usage = 0 +end + +function CgMemUtil:_getLimit_() + local pfile = io.open(self.limitpath, "r") + local line = pfile:read() + self.limit = tonumber(line) + io.close(pfile) +end + +function CgMemUtil:_getUsage_() + local pfile = io.open(self.usagepath, "r") + local line = pfile:read() + self.usage = tonumber(line) + io.close(pfile) +end + +function CgMemUtil:proc(elapsed, lines) + local c = 1 + local k = 1 + CvProc.proc(self) + self:_getLimit_() + self:_getUsage_() + local values = {} + for line in io.lines(self.pFile) do + local name + local cell = pystring:split(line) + local num = #cell + local val = tonumber(cell[num]) + local metrics = {["total_cache"] = 1, ["total_rss"] = 1, ["total_shmem"]=1,["total_dirty"]=1,["total_pgpgin"]=1,["total_pgpgout"]=1, + ["total_inactive_anon"] =1, ["total_active_anon"]=1,["total_inactive_file"] =1, ["total_active_file"] =1,["total_pgfault"]=1} + --we assume that: memory.use_hierarchy is "1" + if metrics[cell[1]] then + name = string.sub(cell[1], 7) + values[k] = { + name = name, + value = val + } + k = k + 1 + if ("total_cache" == cell[1]) or ("total_rss" == cell[1]) then + local ratio = (100.00*val) / tonumber(self.usage) + values[k] = { + name = name.."_ratio", + value = ratio + } + k = k + 1 + end + end + end + values[k] = { + name = "usage", + value = self.usage + } + values[k+1] = { + name = "mem_util", + value = (tonumber(self.usage)*100.0)/ tonumber(self.limit) + } + self:appendLine(self:_packProto("cg_memory_util", self.ls, values)) + self:push(lines) +end +return CgMemUtil diff --git a/source/tools/monitor/unity/collector/guard/calcJiffies.lua b/source/tools/monitor/unity/collector/guard/calcJiffies.lua index 922f345bcc7ab5c9d6ee6f6bef882741e0a2d40d..bbb914e91eae64074c0a2e71f3c9dee0993d31de 100644 --- a/source/tools/monitor/unity/collector/guard/calcJiffies.lua +++ b/source/tools/monitor/unity/collector/guard/calcJiffies.lua @@ -6,6 +6,7 @@ local mod = {} local ptime = require("posix.time") +local pstime = require("posix.sys.time") local unistd = require("posix.unistd") local system = require("common.system") @@ -26,7 +27,16 @@ local function read_jiffies(path, procffi) return res end -local function nproc() +local function get_native_us() + local res, err, errno = pstime.gettimeofday() + if res then + return res.tv_sec * 1e6 + res.tv_usec + else + system:posixError("gettimeofday failed", err, errno) + end +end + +local function nproc() -- get cpu numbers, exec nproc local r, err, errno = unistd.sysconf(84) if err then system:posixError("sysconf failed", err, errno) @@ -40,26 +50,30 @@ function mod.calc(mnt, procffi) local r, err, errno local j1 = read_jiffies(path, procffi) + local ns1 = get_native_us() r, err, errno = ptime.nanosleep(t) if err then system:posixError("nano sleep failed", err, errno) end local j2 = read_jiffies(path, procffi) + local ns2 = get_native_us() ptime.nanosleep(t) if err then system:posixError("nano sleep failed", err, errno) end local j3 = read_jiffies(path, procffi) + local ns3 = get_native_us() + local delta1, delta2 = j2 - j1, j3 -j2 - local comp = delta1 / delta2 + local dts1, dts2 = ns2 - ns1, ns3 - ns2 + local comp = (delta1 / dts1) / ( delta2 / dts2 ) if comp >= 1.1 or comp < 0.9 then - error("calculate jiffies failed.") + error(string.format("calculate jiffies failed, delta1: %d, delta2: %d, dts1: %d, dts2: %d", delta1, delta2, dts1, dts2)) end - - return (delta1 + delta2) * 2.5 / nproc() + return (delta1 + delta2) * ( 1e6 / (dts1 + dts2)) / nproc() end return mod diff --git a/source/tools/monitor/unity/collector/guard/guardSched.lua b/source/tools/monitor/unity/collector/guard/guardSched.lua index e248ea1c24fa0194ae7b0d584471a38a9ec451b9..46c21d1461ddb63fb30f493952d354828ea5ee83 100644 --- a/source/tools/monitor/unity/collector/guard/guardSched.lua +++ b/source/tools/monitor/unity/collector/guard/guardSched.lua @@ -15,7 +15,7 @@ function CguardSched:_init_(tid, procs, names, jperiod) self._jperiod = jperiod self._procs = procs self._names = names - self._limit = 1e5*5 -- 500 ms + self._limit = 1e5 * 5 -- 500 ms end function CguardSched:proc(t, lines) @@ -38,7 +38,7 @@ function CguardSched:proc(t, lines) if stop - start - overTime >= self._limit then -- print(stop - start) local j2 = self._stat:jiffies() - if j2 - j1 >= self._limit / 1e6 * self._jperiod * 3 / 4 then -- 3/4 time used bye plugin + if j2 - j1 >= self._limit / 1e6 * self._jperiod * 3 / 4 then -- 3/4 time used by plugin table.insert(toRemove, i) end end diff --git a/source/tools/monitor/unity/collector/loop.lua b/source/tools/monitor/unity/collector/loop.lua index 9156c8a5f46fd20e4e6800e123639d3d60ceb8ac..47e793ded8ae19fe1eb7a5740ca2b9d2206d828f 100644 --- a/source/tools/monitor/unity/collector/loop.lua +++ b/source/tools/monitor/unity/collector/loop.lua @@ -16,8 +16,8 @@ local CguardDaemon = require("collector.guard.guardDaemon") local CguardSelfStat = require("collector.guard.guardSelfStat") local CpostPlugin = require("collector.postPlugin.postPlugin") local CforkRun = require("collector.execEngine.forkRun") -local CpodFilter = require("collector.podMan.podFilter") - +---local CpodFilter = require("collector.podMan.podFilter") +local CpodsAll = require("collector.podMan.podsAll") local Cloop = class("loop") function Cloop:_init_(que, proto_q, fYaml, tid) @@ -51,11 +51,12 @@ function Cloop:loadLuaPlugin(res, proc_path, procffi) c = c + 1 end end - --self._procs[c] = CpodsAll.new(res, self._proto, procffi, proc_path) - --self._names[c] = "podMon" if res.container then - self._procs[c] = CpodFilter.new(res, self._proto, procffi, proc_path) - self._names[c] = "podFilter" + ---self._procs[c] = CpodFilter.new(res, self._proto, procffi, proc_path) + ---self._names[c] = "podFilter" + self._procs[c] = CpodsAll.new(res, self._proto, procffi, proc_path) + self._names[c] = "podMon" + end print("add " .. system:keyCount(self._procs) .. " lua plugin.") end diff --git a/source/tools/monitor/unity/collector/native/plugincffi.lua b/source/tools/monitor/unity/collector/native/plugincffi.lua index 037ba320191235b2a7cdead8373e7c9cdbbffbf7..9c23c9e3e73f661c85d4869ef2f8ddee4af748ae 100644 --- a/source/tools/monitor/unity/collector/native/plugincffi.lua +++ b/source/tools/monitor/unity/collector/native/plugincffi.lua @@ -39,6 +39,9 @@ void deinit(void); void free(void *p); int setns(int fd, int nstype); +char* scanall(); +int monitor_init(const char* proc); +void monitor_exit(); ]] return ffi diff --git a/source/tools/monitor/unity/collector/plugin/podmem/Makefile b/source/tools/monitor/unity/collector/plugin/podmem/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..ee676b26bc55a689222fd0bdaee798b7fb705440 --- /dev/null +++ b/source/tools/monitor/unity/collector/plugin/podmem/Makefile @@ -0,0 +1,21 @@ +CC := g++ +CFLAG := -g -fpic +LDFLAG := -g -fpic -shared -static-libstdc++ +OBJS := memcg.o offset.o memread.o +SO := libpodmem.so +LIBS += -L ${OBJ_LIB_PATH}/lib -lcoolbpf -lelf -lz -lpthread +LDFLAG += -Wall $(LIBS) + +all: $(SO) install + +%.o: %.cpp + $(CC) -c $< -o $@ $(CFLAG) + +$(SO): $(OBJS) + $(CC) -o $@ $(OBJS) $(LDFLAG) + +install: $(SO) + cp $(SO) ../../native/ + +clean: + rm -f $(SO) $(OBJS) diff --git a/source/tools/monitor/unity/collector/plugin/podmem/btfparse.h b/source/tools/monitor/unity/collector/plugin/podmem/btfparse.h new file mode 100644 index 0000000000000000000000000000000000000000..3a586d0f0bdec166b25804215f644cd3cfef8a52 --- /dev/null +++ b/source/tools/monitor/unity/collector/plugin/podmem/btfparse.h @@ -0,0 +1,38 @@ + + +#ifndef __BTF_PARSE_H +#define __BTF_PARSE_H + + + +/** + * btf_load: load btf from btf_custom_path + * + * @btf_custom_path: path of btf file + */ +struct btf *btf_load(char *btf_custom_path); +typedef unsigned int uint32_t; + +struct member_attribute +{ + uint32_t size; // size of structure's member + uint32_t real_size; // real_size mean + uint32_t offset; // offset of member in strucutre +}; + +/** + * btf_find_struct_member - find struct btfid by structure's name + * + * @btf: + * @struct_name: name of struct + * @member_name: name of structure's member + * @return: NULL mean error, get error number from errno. + * + * Note: Remember to free pointer of struct member_attribute + */ +struct member_attribute *btf_find_struct_member(struct btf *btf, char *struct_name, char *member_name); +void btf__free(struct btf *btf); + + +#endif + diff --git a/source/tools/monitor/unity/collector/plugin/podmem/cache.h b/source/tools/monitor/unity/collector/plugin/podmem/cache.h new file mode 100644 index 0000000000000000000000000000000000000000..8b8c14bc63d0518973648426c6771f1475f4a14f --- /dev/null +++ b/source/tools/monitor/unity/collector/plugin/podmem/cache.h @@ -0,0 +1,103 @@ +/* + * Page scan tool + */ +#ifndef _PAGESCAN_UTIL_H +#define _PAGESCAN_UTIL_H + +#include +#include +#include +#include +#include +#include + + +extern unsigned long page_shift; +#define MAX_ORDER 11 +#define PAGE_SIZE (1UL << page_shift) +#define HUGE_SIZE (PAGE_SIZE * HUGE_PAGE_NR) +#define BUFF_MAX 4096 +#define SIZE_KB (1UL << 10) +#define SIZE_MB (1UL << 20) +#define MAX_KCORE_ELF_HEADER_SIZE 32768 + + +#ifdef DEBUG +#define LOG_DEBUG(...) fprintf(stderr, __VA_ARGS__) +#else +#define LOG_DEBUG(...) do { } while (0) +#endif /* DEBUG */ + +#define LOG_INFO(...) fprintf(stdout, __VA_ARGS__) +#define LOG_WARN(...) fprintf(stderr, __VA_ARGS__) +#define LOG_ERROR(...) fprintf(stderr, __VA_ARGS__) + +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX(a,b) (((a)>(b))?(a):(b)) + +extern unsigned long vmemmap_base; +extern unsigned long page_offset_base; +extern uint64_t g_max_phy_addr; +extern unsigned long memstart_addr; +#define PAGE_STRUCT_SIZE 64 + +#ifdef __aarch64__ /*arm arch*/ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) /*kernel 510*/ +#define VA_BITS (48) +#define SZ_2M 0x00200000 +#define STRUCT_PAGE_MAX_SHIFT (6) +#define VA_BITS_MIN (48) + +#define _PAGE_END(va) (-((unsigned long )(1) << ((va) - 1))) +#define _PAGE_OFFSET(va) (-((unsigned long )(1) << (va))) +#define PAGE_OFFSET (_PAGE_OFFSET(VA_BITS)) +#define VMEMMAP_SIZE ((_PAGE_END(VA_BITS_MIN) - PAGE_OFFSET) \ + >> (page_shift - STRUCT_PAGE_MAX_SHIFT)) +#define PHYS_OFFSET (memstart_addr) +#define VMEMMAP_START (-VMEMMAP_SIZE - SZ_2M) +#define vmemmap (VMEMMAP_START - (memstart_addr >> page_shift)*PAGE_STRUCT_SIZE) + +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 9)/*kernel 419*/ +#define VA_BITS (48) +#define VA_START ((unsigned long )(0xffffffffffffffff) - \ + ((unsigned long )(1) << VA_BITS) + 1) +#define PAGE_OFFSET ((unsigned long )(0xffffffffffffffff) - \ + ((unsigned long )(1) << (VA_BITS - 1)) + 1) +#define STRUCT_PAGE_MAX_SHIFT (6) +#define VMEMMAP_SIZE ((unsigned long )(1) << (VA_BITS - page_shift - 1 + STRUCT_PAGE_MAX_SHIFT)) +#define VMEMMAP_START (PAGE_OFFSET - VMEMMAP_SIZE) +#define vmemmap (VMEMMAP_START - (memstart_addr >> page_shift)*PAGE_STRUCT_SIZE) + +#else /*others*/ +#define SZ_64K 0x00010000 +#define PAGE_OFFSET (unsigned long )(0xffffffc000000000) +#define VMALLOC_END (PAGE_OFFSET - (unsigned long)(0x400000000) - SZ_64K) +#define vmemmap ((struct page *)(VMALLOC_END + SZ_64K)) + +#endif /*end to check ver, arm arch*/ +#define PFN_TO_VIRT(pfn) (((unsigned long)((pfn) - PHYS_OFFSET) | PAGE_OFFSET) + ((pfn) << page_shift)) +#define PFN_TO_PAGE(pfn) (vmemmap + (pfn) * PAGE_STRUCT_SIZE) +#define is_kvaddr(kvaddr) (!!(kvaddr >= PAGE_OFFSET)) +#else /*x86 arch*/ + +#define PFN_TO_VIRT(pfn) (page_offset_base + ((pfn) << page_shift)) +#define PFN_TO_PAGE(pfn) (vmemmap_base + (pfn) * PAGE_STRUCT_SIZE) +#define is_kvaddr(kvaddr) (!!(kvaddr >= page_offset_base)) +#endif +#define max_pfn (g_max_phy_addr>>12) + +struct options { + bool podmem; + bool fullscan; + char *cgroupfile; + char *cgroup; + unsigned int rate; + unsigned int top; +}; + +#define KPF_SIZE 8 +ssize_t kpageflags_read(void *buf, size_t count, off_t offset); +ssize_t kpagecgroup_read(void *buf, size_t count, off_t offset); +uintptr_t lookup_kernel_symbol(const char *symbol_name); +ssize_t kcore_readmem(unsigned long kvaddr, void *buf, ssize_t size); +#endif /* _PAGESCAN_UTIL_H */ diff --git a/source/tools/monitor/unity/collector/plugin/podmem/memcg.cpp b/source/tools/monitor/unity/collector/plugin/podmem/memcg.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bea1c24f824cb52f2730e2828efd4c70e4ee94d2 --- /dev/null +++ b/source/tools/monitor/unity/collector/plugin/podmem/memcg.cpp @@ -0,0 +1,598 @@ +#include +#include +#include +#include +#include +#include "cache.h" +#include "memcg.h" +#include "btfparse.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +#ifndef KPF_RESERVED +#define KPF_RESERVED 32 +#endif + +#ifndef KPF_IDLE +#define KPF_IDLE (25) +#endif + +#define MAX_BIT (26) + + +static bool full_scan; +static unsigned int scan_rate = 4; +struct file_info { + char filename[256]; + unsigned long inode; + unsigned long cached; + unsigned long cgcached; + unsigned long size; + unsigned long active; + unsigned long dirty; + unsigned long inactive; + unsigned long cinode; + int shmem; + int del; +}; +struct myComp2 +{ + bool operator()(const pair &a,const pair &b) + { + return a.second>b.second; + } +}; + +set ,myComp2> cachedset; +map files; +struct myComp +{ + bool operator()(const unsigned long &a,const unsigned long &b) + { + return files[a]->cached >= files[b]->cached; + } +}; +set fileset; +map inodes; +map history_inodes; +extern struct member_attribute *get_offset(string struct_name, string member_name); + +static int prepend(char **buffer, int *buflen, const char *str, int namelen, int off) +{ + *buflen -= namelen + off; + if (*buflen < 0) + return -1; + *buffer -= namelen + off; + if (off) + **buffer = '/'; + memcpy(*buffer + off, str, namelen); + return 0; +} + +static unsigned long inode2mount(unsigned long inode) +{ + unsigned long sb; + unsigned long mount; + struct member_attribute *att; + att = get_offset("inode", "i_sb"); + if (!att) { + return 0; + } + kcore_readmem(inode + att->offset, &sb, sizeof(sb)); + att = get_offset("super_block", "s_mounts"); + if (!att) { + return 0; + } + kcore_readmem(sb+ att->offset, &mount, sizeof(mount)); + att = get_offset("mount", "mnt_instance"); + if (!att) { + return 0; + } + mount -= att->offset; + return mount; +} + +static int get_filename(unsigned long dentry, char *filename, int len) +{ + unsigned long parent; + char name[4096] = {0}; + char tmp[4096] = {0}; + char *end = tmp + 4095; + int buflen = 4095; + struct qstr str; + struct member_attribute *att; + while (dentry) { + + memset(name, 0, 128); + att = get_offset("dentry", "d_parent"); + kcore_readmem(dentry+att->offset, &parent, sizeof(parent)); + att = get_offset("dentry", "d_name"); + if (!att) { + return 0; + } + kcore_readmem(dentry + att->offset, &str, sizeof(str)); + if (parent == dentry || str.len<=0) + break; + dentry = parent; + if (str.len > 4096) + str.len = 4096; + + kcore_readmem((unsigned long)str.name, name, str.len); + prepend(&end, &buflen, name, strlen(name), 1); + } + strncpy(filename, end, len); + return 0; +} + +int get_top_dentry(unsigned long pfn, int top) +{ + unsigned long page = PFN_TO_PAGE(pfn); + map::iterator iter2; + struct member_attribute *att; + struct member_attribute *att2; + unsigned long map = 0; + unsigned long cached = 0; + unsigned long inode = 0; + unsigned long i_ino; + char* tables; + att = get_offset("page", "mapping"); + if (!att) { + return 0; + } + + kcore_readmem(page + att->offset, &map, sizeof(map)); + if (!is_kvaddr(map)) + return 0; + att = get_offset("address_space", "host"); + if (!att) { + return 0; + } + att2 = get_offset("address_space", "nrpages"); + if (!att2) { + return 0; + } + tables = (char*)malloc(att2->offset-att->offset + sizeof(cached)); + kcore_readmem(map + att->offset, tables, att2->offset-att->offset + sizeof(cached)); + inode = *((unsigned long*) tables); + cached = *((unsigned long*) (tables+att2->offset-att->offset)); + free(tables); + /* skip file cache < 100K */ + //printf("top:%d, cached size:%d, cached:%d\n",top, cachedset.size(), cached*4); + if (history_inodes.find(inode) != history_inodes.end() or (cachedset.size() >= top and (cached*4 < (--cachedset.end())->second))) + return 0; + + cachedset.insert(pair(inode,cached*4)); + history_inodes[inode] = 1; + if (cachedset.size() > top) + cachedset.erase(--cachedset.end()); +} + +static int get_dentry_top() +{ + set, myComp2>::iterator iter; + unsigned long map = 0; + unsigned long inode = 0; + unsigned long i_ino; + unsigned long i_size; + unsigned long inode_dentry =0; + unsigned long dentry_first = 0; + unsigned long hdentry = 0; + unsigned long pdentry = 0; + unsigned long mount = 0; + unsigned long cached; + int del = 0; + struct file_info *info; + struct member_attribute *att; + for(iter=cachedset.begin();iter!=cachedset.end();iter++) + { + char tmp[4096] = {0}; + char *end = tmp + 4095; + int buflen = 4095; + char filename[1024] = {0}; + cached = iter->second; + inode = iter->first; + att = get_offset("inode", "i_ino"); + if (!att) { + return 0; + } + kcore_readmem(inode + att->offset, &i_ino, sizeof(i_ino)); + att = get_offset("inode", "i_size"); + if (!att) { + return 0; + } + kcore_readmem(inode + att->offset, &i_size, sizeof(i_size)); + + mount = inode2mount(inode); + att = get_offset("inode","i_dentry"); + if (!att) { + return 0; + } + kcore_readmem(inode + att->offset, &inode_dentry, sizeof(inode)); + if (!is_kvaddr(inode_dentry)) + continue; + att = get_offset("dentry", "d_alias"); + if (!att) { + att = get_offset("dentry", "d_u"); + if (!att) + return 0; + } + + dentry_first = inode_dentry - att->offset; + memset(filename, 0, 1024); + att = get_offset("dentry", "d_parent"); + if (!att) { + return 0; + } + kcore_readmem(dentry_first+att->offset, &pdentry, sizeof(pdentry)); + att = get_offset("dentry", "d_hash"); + if (!att) { + return 0; + } + kcore_readmem(dentry_first+att->offset + sizeof(void*), &hdentry, sizeof(hdentry)); + if ((dentry_first != pdentry) && !hdentry) + del = 1; + do { + unsigned long mount_parent = 0; + unsigned long mount_dentry = 0; + int len = 0; + int ret = 0; + + get_filename(dentry_first, filename, 1024); + len = strlen(filename); + if (len <=0 || ((len == 1) && (filename[0] == '/'))) + break; + + prepend(&end, &buflen, filename, strlen(filename), 0); + att = get_offset("mount", "mnt_parent"); + if (!att) { + return 0; + } + ret = kcore_readmem(mount + att->offset, &mount_parent , sizeof(mount_parent)); + if (ret != sizeof(mount_parent)) + break; + att = get_offset("mount", "mnt_mountpoint"); + if (!att) { + return 0; + } + kcore_readmem(mount+ att->offset, &mount_dentry, sizeof(mount_dentry)); + if (mount_parent == mount || mount_dentry==dentry_first) + break; + dentry_first = mount_dentry; + mount = mount_parent; + } while(true); + + if (buflen >= 4092) + continue; + info = (struct file_info *)malloc(sizeof(struct file_info)); + if (!info) { + printf("alloc file info error \n"); + continue; + } + memset(info, 0, sizeof(struct file_info)); + info->inode = i_ino; + //info->shmem = shmem; + info->cached = cached; + info->cgcached = 1; + info->active = 0; + info->dirty = 0; + info->inactive = 0; + info->del = del; + + info->size = i_size>>10; + strncpy(info->filename, end, sizeof(info->filename) - 2); + info->filename[sizeof(info->filename) -1] = '0'; + files[i_ino] = info; + fileset.insert(i_ino); + } + return 0; +} + +/* + * pfn: page pfn + * cinode: cgroup inode + */ +static int get_dentry(unsigned long pfn, unsigned long cinode, int active, int shmem, int dirty, int top) +{ + map::iterator iter; + unsigned long page = PFN_TO_PAGE(pfn); + unsigned long map = 0; + unsigned long cached = 0; + unsigned long inode = 0; + unsigned long inode_dentry =0; + unsigned long dentry_first = 0; + unsigned long hdentry = 0; + unsigned long pdentry = 0; + unsigned long mount = 0; + char filename[1024] = {0}; + char tmp[4096] = {0}; + char *end = tmp + 4095; + int buflen = 4095; + unsigned long i_ino; + unsigned long i_size; + struct file_info *info; + int del = 0; + struct member_attribute *att; + att = get_offset("page", "mapping"); + if (!att) { + return 0; + } + + kcore_readmem(page + att->offset, &map, sizeof(map)); + if (!is_kvaddr(map)) + return 0; + att = get_offset("address_space", "nrpages"); + if (!att) { + return 0; + } + kcore_readmem(map + att->offset, &cached, sizeof(cached)); + /* skip file cache < 100K */ + if (fileset.size() >= top and (cached*4 < (files[*(--fileset.end())]->cached))) + return 0; + + att = get_offset("address_space", "host"); + if (!att) { + return 0; + } + kcore_readmem(map + att->offset, &inode, sizeof(inode)); + att = get_offset("inode", "i_ino"); + if (!att) { + return 0; + } + kcore_readmem(inode + att->offset, &i_ino, sizeof(i_ino)); + iter = files.find(i_ino); + if (iter != files.end()) { + info = iter->second; + if (active) { + info->active += 1; + }else { + info->inactive += 1; + } + if (dirty) { + info->dirty += 1; + } + + if (info->cinode == cinode) + info->cgcached++; + return 0; + } + att = get_offset("inode", "i_size"); + if (!att) { + return 0; + } + kcore_readmem(inode + att->offset, &i_size, sizeof(i_size)); + + mount = inode2mount(inode); + att = get_offset("inode","i_dentry"); + if (!att) { + return 0; + } + kcore_readmem(inode + att->offset, &inode_dentry, sizeof(inode)); + if (!is_kvaddr(inode_dentry)) + return 0; + att = get_offset("dentry", "d_alias"); + if (!att) { + att = get_offset("dentry", "d_u"); + if (!att) + return 0; + } + + dentry_first = inode_dentry - att->offset; + memset(filename, 0, 1024); + att = get_offset("dentry", "d_parent"); + if (!att) { + return 0; + } + kcore_readmem(dentry_first+att->offset, &pdentry, sizeof(pdentry)); + att = get_offset("dentry", "d_hash"); + if (!att) { + return 0; + } + kcore_readmem(dentry_first+att->offset + sizeof(void*), &hdentry, sizeof(hdentry)); + if ((dentry_first != pdentry) && !hdentry) + del = 1; + do { + unsigned long mount_parent = 0; + unsigned long mount_dentry = 0; + int len = 0; + int ret = 0; + + get_filename(dentry_first, filename, 1024); + len = strlen(filename); + if (len <=0 || ((len == 1) && (filename[0] == '/'))) + break; + + prepend(&end, &buflen, filename, strlen(filename), 0); + att = get_offset("mount", "mnt_parent"); + if (!att) { + return 0; + } + ret = kcore_readmem(mount + att->offset, &mount_parent , sizeof(mount_parent)); + if (ret != sizeof(mount_parent)) + break; + att = get_offset("mount", "mnt_mountpoint"); + if (!att) { + return 0; + } + kcore_readmem(mount+ att->offset, &mount_dentry, sizeof(mount_dentry)); + if (mount_parent == mount || mount_dentry==dentry_first) + break; + dentry_first = mount_dentry; + mount = mount_parent; + } while(true); + + if (buflen >= 4092) + return 0; + info = (struct file_info *)malloc(sizeof(struct file_info)); + if (!info) { + printf("alloc file info error \n"); + return 0; + } + memset(info, 0, sizeof(sizeof(struct file_info))); + info->inode = i_ino; + info->shmem = shmem; + info->cached = cached*4; + info->cgcached = 1; + info->active = 0; + info->dirty = 0; + info->inactive = 0; + info->del = del; + if (active) + info->active = 1; + else + info->inactive = 1; + if (dirty) + info->dirty = 1; + + info->cinode = cinode; + info->size = i_size>>10; + strncpy(info->filename, end, sizeof(info->filename) - 2); + info->filename[sizeof(info->filename) -1] = '0'; + files[i_ino] = info; + fileset.insert(i_ino); + if(fileset.size() > top) + { + i_ino = *(--fileset.end()); + fileset.erase(--fileset.end()); + iter=files.find(i_ino); + free(iter->second); + files.erase(iter); + } + return 0; +} + +unsigned long get_cgroup_inode(unsigned long pfn) +{ + unsigned long ino; + int ret = 0; + + ret = kpagecgroup_read(&ino, sizeof(ino), pfn*sizeof(ino)); + if (ret != sizeof(ino)) { + return 0; + } + return ino; +} + +int check_cgroup_inode(unsigned long inode) +{ + return (full_scan||(inodes.find(inode)!=inodes.end())); +} + +bool cached_cmp(const pair& a, const pair& b) { + struct file_info *a_file = a.second; + struct file_info *b_file = b.second; + if (!a_file || !b_file) + return 1; + return a_file->cached > b_file->cached; +} + +static int output_file_cached_string(unsigned int top, char *res) +{ + set::iterator iter2; + struct file_info *info; + int size = 0; + + for (iter2 = fileset.begin(); iter2 != fileset.end(); ++iter2) { + info = files[*iter2]; + if (!info) { + continue; + } + size += sprintf(res + size, "cinode=%lu cached=%lu size=%lu file=%s\n", info->cinode,info->cached, info->size,info->filename); + free(info); + } + files.clear(); + fileset.clear(); + cachedset.clear(); + history_inodes.clear(); + + return 0; +} + +int scan_pageflags_nooutput(struct options *opt, char *res) +{ + unsigned long pageflag; + unsigned long pfn = 0; + unsigned long inode = 0; + int active = 0; + int dirty = 0; + int shmem = 0; + + if (opt->rate != 0) { + scan_rate = opt->rate; + } + full_scan = opt->fullscan; + while (1) { + int ret = 0; + pageflag = 0; + + pfn += scan_rate ;/* skip 2M*/ + + if (pfn > max_pfn) + break; + ret = kpageflags_read(&pageflag, sizeof(pageflag), sizeof(pageflag)*pfn); + if (ret != sizeof(pageflag)) { + break; + } + if (pageflag & (1 << KPF_NOPAGE) || !pageflag) + continue; + + if ((pageflag & (1<> KPF_RESERVED) & 0x1)) + continue; + if (pageflag & (1 << KPF_ANON)) + continue; + + active = !!((1<top); + } + } + get_dentry_top(); + output_file_cached_string(opt->top, res); + return 0; +} + +int memcg_cgroup_path(const char *cgrouppath) +{ + struct stat st; + if (access(cgrouppath, F_OK)) { + return 0; + } + + stat(cgrouppath, &st); + inodes[st.st_ino] = 1; + return 0; +} + +int memcg_cgroup_file(const char *cgroupfile) +{ + ifstream filename(cgroupfile); + string cgroup; + int count = 0; + + if (!filename) { + printf("open %s failed\n", cgroupfile); + return 0; + } + + while (getline(filename, cgroup)) + { + memcg_cgroup_path(cgroup.c_str()); + count ++; + } + filename.close(); + return count; +} diff --git a/source/tools/monitor/unity/collector/plugin/podmem/memcg.h b/source/tools/monitor/unity/collector/plugin/podmem/memcg.h new file mode 100644 index 0000000000000000000000000000000000000000..b5556824453bcfc9681665f405ea1430102d1e97 --- /dev/null +++ b/source/tools/monitor/unity/collector/plugin/podmem/memcg.h @@ -0,0 +1,33 @@ +#ifndef __POD__ +#define __POD__ + +#include +#include +#include +using namespace std; + +#define SIZE (32) +#define NAME (4096) + +/*file */ +struct fileinfo { + char name[NAME]; + unsigned long cached; + unsigned long size; + unsigned long inode; + unsigned long ino; +}; +typedef unsigned int u32; +typedef unsigned long long u64; + +struct qstr { + union { + struct { + u32 hash; + u32 len; + }; + u64 hash_len; + }; + const unsigned char *name; +}; +#endif diff --git a/source/tools/monitor/unity/collector/plugin/podmem/memread.cpp b/source/tools/monitor/unity/collector/plugin/podmem/memread.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d53189b27f8430dc208aebca601d1dff0d41bb42 --- /dev/null +++ b/source/tools/monitor/unity/collector/plugin/podmem/memread.cpp @@ -0,0 +1,434 @@ +/* + * pod memory tool + */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#ifndef _LARGEFILE64_SOURCE +#define _LARGEFILE64_SOURCE +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cache.h" +#define MAX_CGROUP 256 + +extern int scan_pageflags(struct options * opt); +extern int scan_pageflags_nooutput(struct options * opt,char *res); +extern int memcg_cgroup_file(const char *cgroupfile); +extern int memcg_cgroup_path(const char *cgrouppath); +extern int offset_init(void); +extern int sym_uninit(void); + +extern "C" { +char* scanall(); +int monitor_init(const char* proc); +void monitor_exit(); +} + +struct options opt = {0}; + +struct proc_kcore_data { + unsigned int flags; + unsigned int segments; + char *elf_header; + size_t header_size; + Elf64_Phdr *load64; + Elf64_Phdr *notes64; + Elf32_Phdr *load32; + Elf32_Phdr *notes32; + void *vmcoreinfo; + unsigned int size_vmcoreinfo; +}; + +static struct proc_kcore_data proc_kcore_data = { 0 }; +static struct proc_kcore_data *pkd = &proc_kcore_data; + +static int kcore_fd = 0; +static int kpageflags_fd = 0; +static int kpagecgroup_fd = 0; +uint64_t g_max_phy_addr; + + +/* + * kernel vmemmap_base page_offset_base + * 3.10 0xffffea0000000000UL 0xffff880000000000UL + * 4.9 0xffffea0000000000UL 0xffff880000000000UL + * 4.19 0xffffea0000000000UL 0xffff888000000000UL + * + * We use default vmemmap_base and page_offset_base values on kernel 4.9, + * which is the same on kernel 3.10, and reassign these two values on + * kernel 4.19 due to kaslr, by kcore. + */ +unsigned long vmemmap_base = 0xffffea0000000000UL; +unsigned long page_offset_base = 0xffff880000000000UL; +unsigned long memstart_addr = 0x0; +unsigned long page_shift = 0; + +/* + * Routines of kpageflags, i.e., /proc/kpageflags + */ +ssize_t kpageflags_read(void *buf, size_t count, off_t offset) +{ + return pread(kpageflags_fd, buf, count, offset); +} + +ssize_t kpagecgroup_read(void *buf, size_t count, off_t offset) +{ + ssize_t ret = 0; + if (kpagecgroup_fd > 0) + ret = pread(kpagecgroup_fd, buf, count, offset); + + return ret; +} + +/* + * Routines of kcore, i.e., /proc/kcore + */ +uintptr_t lookup_kernel_symbol(const char *symbol_name, const char *proc) +{ + std::string tmp(proc); + tmp += "/proc/kallsyms"; + const char *kallsyms_file = tmp.c_str(); + FILE *fp; + char line[BUFF_MAX]; + char *pos; + uintptr_t addr = -1UL; + + fp = fopen(kallsyms_file, "r"); + if (fp == NULL) { + perror("fopen: /proc/kallsyms"); + return -1; + } + + while (fgets(line, BUFF_MAX, fp)) { + if ((pos = strstr(line, symbol_name)) == NULL) + continue; + + /* Remove trailing newline */ + line[strcspn(line, "\n")] = '\0'; + + /* Exact match */ + if (pos == line || !isspace(*(pos - 1))) + continue; + if (!strcmp(pos, symbol_name)) { + addr = strtoul(line, NULL, 16); + break; + } + } + + if (addr == -1UL) + LOG_ERROR("failed to lookup symbol: %s\n", symbol_name); + + fclose(fp); + return addr; +} + +static int kcore_elf_init(void) +{ + Elf64_Ehdr *elf64; + Elf64_Phdr *load64; + Elf64_Phdr *notes64; + char eheader[MAX_KCORE_ELF_HEADER_SIZE]; + size_t load_size, notes_size; + + if (read(kcore_fd, eheader, MAX_KCORE_ELF_HEADER_SIZE) != + MAX_KCORE_ELF_HEADER_SIZE) { + perror("read: /proc/kcore ELF header"); + return -1; + } + + elf64 = (Elf64_Ehdr *)&eheader[0]; + notes64 = (Elf64_Phdr *)&eheader[sizeof(Elf64_Ehdr)]; + load64 = (Elf64_Phdr *)&eheader[sizeof(Elf64_Ehdr) + + sizeof(Elf64_Phdr)]; + + pkd->segments = elf64->e_phnum - 1; + + notes_size = load_size = 0; + if (notes64->p_type == PT_NOTE) + notes_size = notes64->p_offset + notes64->p_filesz; + if (notes64->p_type == PT_LOAD) + load_size = (unsigned long)(load64+(elf64->e_phnum)) - + (unsigned long)elf64; + + pkd->header_size = MAX(notes_size, load_size); + if (!pkd->header_size) + pkd->header_size = MAX_KCORE_ELF_HEADER_SIZE; + + if ((pkd->elf_header = (char *)malloc(pkd->header_size)) == NULL) { + perror("malloc: /proc/kcore ELF header"); + return -1; + } + + memcpy(&pkd->elf_header[0], &eheader[0], pkd->header_size); + pkd->notes64 = (Elf64_Phdr *)&pkd->elf_header[sizeof(Elf64_Ehdr)]; + pkd->load64 = (Elf64_Phdr *)&pkd->elf_header[sizeof(Elf64_Ehdr) + + sizeof(Elf64_Phdr)]; + + return 0; +} + +static int kcore_init(const char* proc) +{ + unsigned long vmemmap_symbol_addr; + unsigned long page_offset_symbol_addr; + unsigned long memstart_addr_addr; + std::string tmp(proc); + tmp += "/proc/kcore"; + int size; + + if ((kcore_fd = open(tmp.c_str(), O_RDONLY)) < 0) { + perror("open: /proc/kcore"); + return -1; + } + + if (kcore_elf_init()) + goto failed; + + vmemmap_symbol_addr = lookup_kernel_symbol("vmemmap_base",proc); + if (vmemmap_symbol_addr == (unsigned long )-1) { + LOG_WARN("continue to use default vmemmap_base: 0x%lx\n", + vmemmap_base); + } else { + size = kcore_readmem(vmemmap_symbol_addr, &vmemmap_base, 8); + if (size < 8) + goto failed; + } + + page_offset_symbol_addr = lookup_kernel_symbol("page_offset_base", proc); + if (page_offset_symbol_addr == (unsigned long)-1) { + LOG_WARN("continue to use default page_offset_base: 0x%lx\n", + page_offset_base); + } else { + size = kcore_readmem(page_offset_symbol_addr, &page_offset_base, 8); + if (size < 8) + goto failed; + } + + memstart_addr_addr = lookup_kernel_symbol("memstart_addr",proc); + if (memstart_addr_addr == (unsigned long)-1) { + LOG_WARN("continue to use default memstart_addr_base: 0x%lx\n", + memstart_addr); + } else { + size = kcore_readmem(memstart_addr_addr, &memstart_addr, 8); + if (size < 8) + goto failed; + } + return 0; + +failed: + close(kcore_fd); + return -1; +} + +/* + * We may accidentally access invalid pfns on some kernels + * like 4.9, due to known bugs. Just skip it. + */ +ssize_t kcore_readmem(unsigned long kvaddr, void *buf, ssize_t size) +{ + Elf64_Phdr *lp64; + unsigned long offset = -1UL; + ssize_t read_size; + unsigned int i; + + for (i = 0; i < pkd->segments; i++) { + lp64 = pkd->load64 + i; + if ((kvaddr >= lp64->p_vaddr) && + (kvaddr < (lp64->p_vaddr + lp64->p_memsz))) { + offset = (off_t)(kvaddr - lp64->p_vaddr) + + (off_t)lp64->p_offset; + break; + } + } + if (i == pkd->segments) { + for (i = 0; i < pkd->segments; i++) { + lp64 = pkd->load64 + i; + LOG_DEBUG("%2d: [0x%lx, 0x%lx)\n", i, lp64->p_vaddr, + lp64->p_vaddr + lp64->p_memsz); + } + //printf("invalid kvaddr 0x%lx\n", kvaddr); + goto failed; + } + + if (lseek(kcore_fd, offset, SEEK_SET) < 0) { + perror("lseek: /proc/kcore"); + goto failed; + } + + read_size = read(kcore_fd, buf, size); + if (read_size < size) { + perror("read: /proc/kcore"); + goto failed; + } + + return read_size; + +failed: + return -1; +} + +static void kcore_exit(void) +{ + if (pkd->elf_header) + free(pkd->elf_header); + if (kcore_fd > 0) + close(kcore_fd); +} + + +static uint64_t get_max_phy_addr(const char *proc) +{ + std::string iofile(proc); + iofile += "/proc/iomem"; + const char *iomem_file = iofile.c_str(); + printf("%s\n",iomem_file); + FILE *fp = NULL; + char line[BUFF_MAX], *pos, *end = NULL; + uint64_t max_phy_addr = 0; + + fp = fopen(iomem_file, "r"); + if (fp == NULL) { + perror("fopen: /proc/iomem"); + return 0ULL; + } + + while (fgets(line, BUFF_MAX, fp)) { + if (strstr(line, "System RAM") == NULL) + continue; + + pos = strchr(line, '-'); + if (pos == NULL) + break; + pos++; + + max_phy_addr = strtoull(pos, &end, 16); + if (end == NULL) { + perror("strtoull: max_phy_addr"); + max_phy_addr = 0; + break; + } + } + + fclose(fp); + return max_phy_addr; +} + +static int setup(const char* proc) +{ + std::string filename(proc); + std::string tmp; + g_max_phy_addr = get_max_phy_addr(proc); + if (g_max_phy_addr == 0ULL) { + g_max_phy_addr = 64 * 1024 * 1024 * 1024; + LOG_ERROR("failed to get max physical address\n"); + } + LOG_DEBUG("max physical address = %#lx\n", g_max_phy_addr); + + tmp = filename+"/proc/kpageflags"; + kpageflags_fd = open(tmp.c_str(), O_RDONLY); + if (kpageflags_fd < 0) { + perror("open: /proc/kpageflags"); + return -1; + } + tmp = filename+"/proc/kpagecgroup"; + kpagecgroup_fd = open(tmp.c_str(), O_RDONLY); + if (kpagecgroup_fd < 0) { + perror("open: /proc/kpagecgroup"); + } + if (kcore_init(proc) < 0) { + LOG_ERROR("failed to init kcore\n"); + return -1; + } + + return offset_init(); +} + +static void cleanup(void) +{ + if (kpageflags_fd > 0) + close(kpageflags_fd); + + if (kpagecgroup_fd > 0) { + close(kpagecgroup_fd); + } + sym_uninit(); + kcore_exit(); +} + +static int get_pageshift() +{ + int page_size = getpagesize(); + + if(page_size <= 0 ) + { + LOG_ERROR("failed to get page size\n"); + return -1; + } + while (page_size > 1) { + page_size >>= 1; + page_shift++; + } + return 0; +} + +static void show_usage(void) +{ + LOG_INFO("Usage: %s [OPTIONS]\n" + "\n" + " -h, --help display this help and exit\n" + "\n" + "Supported options:\n" + " -m, pod cache tools \n" + "\n" + ); +} + +int monitor_init(const char* proc) +{ + int ret = get_pageshift(); + if (ret != 0) { + printf("failed to page shift\n"); + return ret; + } + ret = setup(proc); + if (ret != 0) { + printf("failed to setup\n"); + return ret; + } + return 0; +} + +void monitor_exit() +{ + cleanup(); +} + +char* scanall() +{ + const char *filename="/tmp/.memcg.txt"; + char *outputres = NULL; + + opt.rate = 100; + opt.top = 10; + int count = memcg_cgroup_file(filename); + if (count < 0) + return NULL; + count = (count < 0 || count>MAX_CGROUP) ? MAX_CGROUP:count; + count = 350 * opt.top * count; + outputres = (char*)malloc(count); + memset(outputres,0,count); + + scan_pageflags_nooutput(&opt,outputres); + return outputres; +} diff --git a/source/tools/monitor/unity/collector/plugin/podmem/offset.cpp b/source/tools/monitor/unity/collector/plugin/podmem/offset.cpp new file mode 100644 index 0000000000000000000000000000000000000000..882aae60c750156e5bd1d08386848fe923e73d35 --- /dev/null +++ b/source/tools/monitor/unity/collector/plugin/podmem/offset.cpp @@ -0,0 +1,226 @@ +#include +#include +#include +#include +#include +#include +extern "C" { +#include "btfparse.h" +} + +#include +#include +using namespace std; +struct btf * handle; +#define LEN (128) + +map struct_offset; + +int sym_init(char *btf_name) +{ + handle = btf_load(btf_name); + + return !!(handle == NULL); +} + +int sym_uninit(void) +{ + btf__free(handle); + map::iterator iter; + struct member_attribute *info; + + for (iter = struct_offset.begin(); iter != struct_offset.end(); ++iter) { + info = (*iter).second; + if (info) { + free(info); + (*iter).second = NULL; + } + } + return 0; +} + +struct member_attribute *get_offset(string struct_name, string member_name) +{ + string index; + struct member_attribute *att; + map::iterator iter; + + index = struct_name + "_" + member_name; + iter = struct_offset.find(index); + if (iter != struct_offset.end()) { + return iter->second; + } + att = btf_find_struct_member(handle, (char*)struct_name.c_str(), (char*)member_name.c_str()); + if (!att) { + //printf("get %s error \n", index.c_str()); + return NULL; + } + //printf("%s:offset:%d, size:%d\n", index.c_str(),att->offset, att->size); + att->offset = att->offset/8; + struct_offset[index] = att; + return att; +} + +void stripWhiteSpace (string &str) +{ + if (str == "") + { + return; + } + + string::iterator cur_it; + cur_it = str.begin(); + + while (cur_it != str.end()) + { + if (((*cur_it) != '\t') && ((*cur_it) != ' ')) + { + break; + } + else + { + cur_it = str.erase (cur_it); + } + } + + cur_it = str.begin(); + + while (cur_it != str.end()) + { + if ((*cur_it) == '\n') + { + cur_it = str.erase (cur_it); + } + else + { + cur_it++; + } + } +} + +static int do_cmd(const char *cmd, char *result, int len) +{ + FILE *res; + char region[LEN] = {0}; + string str; + + res = popen(cmd, "r"); + if (res == NULL) { + printf("get region id failed\n"); + return -1; + } + + if (feof(res)) { + printf("cmd line end\n"); + return 0; + } + fgets(region, sizeof(region)-1, res); + str = region; + stripWhiteSpace(str); + /* skip \n */ + strncpy(result, str.c_str(), len - 1); + result[len - 1] = '\0'; + pclose(res); + return 0; +} + +static int download_btf(void) +{ + char region[LEN] = {0}; + char arch[LEN] = {0}; + char kernel[LEN] = {0}; + char dw[LEN+LEN] = {0}; + string sysak_path = "/boot"; + string timeout = "-internal"; + string cmd = "curl -s --connect-timeout 2 http://100.100.100.200/latest/meta-data/region-id 2>&1"; + + do_cmd(cmd.c_str(), region, LEN); + if (!strstr(region,"cn-")) { + strcpy(region, "cn-hangzhou"); + timeout = ""; + } + //printf("region:%s\n", region); + cmd = "uname -m"; + do_cmd(cmd.c_str(), arch, LEN); + //printf("arch:%s\n", arch); + + cmd = "uname -r"; + do_cmd(cmd.c_str(), kernel, LEN); + //printf("kernel:%s\n", kernel); + + if(getenv("SYSAK_WORK_PATH") != NULL) + { + sysak_path = getenv("SYSAK_WORK_PATH") ; + sysak_path += "/tools/"; + sysak_path += kernel; + } + + snprintf(dw, LEN + LEN + LEN, "wget -T 5 -t 2 -q -O %s/vmlinux-%s https://sysom-cn-%s.oss-cn-%s%s.aliyuncs.com/home/hive/btf/%s/vmlinux-%s",sysak_path.c_str(), kernel, ®ion[3],®ion[3],timeout.c_str(),arch, kernel); + + do_cmd(dw, kernel, LEN); + return 0; +} + +static int check_btf_file(char *btf) +{ + struct stat fstat; + int ret = 0; + + ret = stat(btf, &fstat); + if (ret) + return -1; + if (fstat.st_size < 10*1024) + return -1; + + return 0; +} + +int offset_init(void) +{ + int ret = 0; + char btf[LEN] = {0}; + char ver[LEN] = {0}; + const char *cmd; + + cmd = string("uname -r").c_str(); + do_cmd(cmd, ver, LEN); + if(getenv("SYSAK_WORK_PATH") != NULL) + sprintf(btf,"%s/tools/%s/vmlinux-%s", getenv("SYSAK_WORK_PATH"), ver, ver); + else + sprintf(btf,"/boot/vmlinux-%s", ver); + + if (check_btf_file(btf)) { + download_btf(); + }; + + if (check_btf_file(btf)) { + printf("btf file:%s not found \n", btf); + return -1; + } + ret = sym_init(btf); + if (!!ret) { + printf("get sym init error\n"); + return -1; + } + + get_offset("page", "mapping"); + get_offset("address_space", "host"); + get_offset("address_space", "nrpages"); + get_offset("inode", "i_ino"); + get_offset("inode", "i_size"); + get_offset("inode", "i_sb"); + get_offset("inode", "i_dentry"); + get_offset("dentry", "d_alias"); + get_offset("dentry", "d_parent"); + get_offset("dentry", "d_hash"); + get_offset("dentry", "d_name"); + get_offset("dentry", "d_name"); + get_offset("super_block", "s_mounts"); + get_offset("mount", "mnt_instance"); + get_offset("mount", "mnt_parent"); + get_offset("mount", "mnt_mountpoint"); + get_offset("mount", "mnt_mountpoint"); + + return 0; +} + diff --git a/source/tools/monitor/unity/collector/podMan/podsAll.lua b/source/tools/monitor/unity/collector/podMan/podsAll.lua index 3a15d5a46df4c4c4cfcebd43c7e0c39f54472de4..ae3b563bde418f462c058e934f53ac04825f8b8f 100644 --- a/source/tools/monitor/unity/collector/podMan/podsAll.lua +++ b/source/tools/monitor/unity/collector/podMan/podsAll.lua @@ -11,6 +11,7 @@ local system = require("common.system") local pystring = require("common.pystring") local Cinotifies = require("common.inotifies") local unistd = require("posix.unistd") +local json = require("cjson") local CpodsAll = class("podsApi") @@ -72,12 +73,22 @@ local function setupCons(res) local cli = ChttpCli.new() local cons = {} local c = 0 - + local blacklist = {["arms-prom"] = 1, ["kube-system"] = 1, ["kube-public"] = 1, ["kube-node-lease"] = 1} local content = cli:get("http://127.0.0.1:10255/pods") local obj = cli:jdecode(content.body) + if not obj then + local cmd = ' curl -s -k -XGET https://127.0.0.1:10250/pods --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt --header "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token) "' + local f = io.popen(cmd,"r") + local podsinfo = f:read("*a") + f:close() + obj = json.decode(podsinfo) + end for _, pod in ipairs(obj.items) do local metadata = pod.metadata + if blacklist[metadata.namespace] then + goto continue + end local lpod = {name = metadata.name, namespace = metadata.namespace, uid = pystring:replace(metadata.uid, "-", "_"), @@ -97,8 +108,50 @@ local function setupCons(res) cons[c] = cell end end + ::continue:: + end + + return cons +end + +function CpodsAll:getAllcons(procfs) + local mnt = procfs + local runtime = getRuntime(mnt) + local cli = ChttpCli.new() + local cons = {} + local c = 0 + local content = cli:get("http://127.0.0.1:10255/pods") + local obj = cli:jdecode(content.body) + if not obj then + local cmd = ' curl -s -k -XGET https://127.0.0.1:10250/pods --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt --header "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token) "' + local f = io.popen(cmd,"r") + local podsinfo = f:read("*a") + f:close() + obj = json.decode(podsinfo) end + for _, pod in ipairs(obj.items) do + local metadata = pod.metadata + --print(string.format("podns :%s, pod:%s",metadata.namespace, metadata.name)) + local lpod = {name = metadata.name, + namespace = metadata.namespace, + uid = pystring:replace(metadata.uid, "-", "_"), + qos = pystring:lower(pod.status.qosClass), + } + local containerStatuses = pod.status.containerStatuses + for _, con in ipairs(containerStatuses) do + local cell = { + pod = lpod, + name = con.name, + id = spiltConId(con.containerID) + } + cell.path = joinPath(cell, runtime) + if unistd.access(mnt .. "/sys/fs/cgroup/memory/" .. cell.path) == 0 then + c = c + 1 + cons[c] = cell + end + end + end return cons end @@ -110,19 +163,15 @@ local function setupPlugins(res, proto, pffi, mnt, ino) for _, con in ipairs(cons) do local ls = { { - name = "pod_name", + name = "podname", index = con.pod.name, }, { - name = "con_name", - index = con.name, - }, - { - name = "qos", - index = con.pod.qos, + name = "container", + index = con.name.."-"..string.sub(con.id,0,4), }, { - name = "ns", + name = "podns", index = con.pod.namespace, }, { @@ -155,15 +204,23 @@ function CpodsAll:_init_(resYaml, proto, pffi, mnt) self._ino = Cinotifies.new() self._plugins = setupPlugins(self._resYaml, self._proto, self._pffi, self._mnt, self._ino) + + self._ino:add(mnt .. "sys/fs/cgroup/memory/kubepods.slice") + self._ino:add(mnt .. "sys/fs/cgroup/memory/kubepods.slice/kubepods-besteffort.slice") + self._ino:add(mnt .. "sys/fs/cgroup/memory/kubepods.slice/kubepods-burstable.slice") + print( "pods plugin add " .. #self._plugins) end function CpodsAll:proc(elapsed, lines) local rec = {} - if self._ino:isChange() then + if self._ino:isChange() or #self._plugins == 0 then print("cgroup changed.") self._ino = Cinotifies.new() self._plugins = setupPlugins(self._resYaml, self._proto, self._pffi, self._mnt, self._ino) + self._ino:add(self._mnt .. "sys/fs/cgroup/memory/kubepods.slice") + self._ino:add(self._mnt .. "sys/fs/cgroup/memory/kubepods.slice/kubepods-besteffort.slice") + self._ino:add(self._mnt .. "sys/fs/cgroup/memory/kubepods.slice/kubepods-burstable.slice") end for i, plugin in ipairs(self._plugins) do --local res = plugin:proc(elapsed, lines) diff --git a/source/tools/monitor/unity/collector/pod_allocpage.lua b/source/tools/monitor/unity/collector/pod_allocpage.lua index f40439683f1cce9a880884b073fdf16db921ab0b..9a54123458231eae8b5245a0fb34770be7059336 100644 --- a/source/tools/monitor/unity/collector/pod_allocpage.lua +++ b/source/tools/monitor/unity/collector/pod_allocpage.lua @@ -30,7 +30,7 @@ function CPodAlloc:_init_(proto, pffi, mnt, pFile) self.cgroup_pod = {} self.allpods = {} self.blacklist = {["arms-prom"] = 1, ["kube-system"] = 1, ["kube-public"] = 1, ["kube-node-lease"] = 1} - -- self.blacklist= {} + --self.blacklist= {} self.total = 0 self.count = 0 self.cgroup_count = 0 @@ -209,6 +209,13 @@ function CPodAlloc:get_allpods() local cli = ChttpCli.new() local content = cli:get(url) local obj = cli:jdecode(content.body) + if not obj then + local cmd = ' curl -s -k -XGET https://127.0.0.1:10250/pods --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt --header "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token) "' + local f = io.popen(cmd,"r") + local podsinfo = f:read("*a") + f:close() + obj = json.decode(podsinfo) + end for _,v in pairs(obj['items']) do if not self.blacklist[v['metadata']['namespace']] then self.allpods[v['metadata']['name']] = v['metadata']['namespace'] end end diff --git a/source/tools/monitor/unity/collector/podmem.lua b/source/tools/monitor/unity/collector/podmem.lua new file mode 100644 index 0000000000000000000000000000000000000000..f36e8e8d15b99d99b73737bb549fd9d3bf6d42ca --- /dev/null +++ b/source/tools/monitor/unity/collector/podmem.lua @@ -0,0 +1,111 @@ +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by liuxinwnei. +--- DateTime: 2023/05/29 17:00 PM +--- + +require("common.class") +local fcntl = require("posix.fcntl") +local unistd = require("posix.unistd") +local dirent = require("posix.dirent") +local stdlib = require("posix.stdlib") +local stat = require("posix.sys.stat") +local CkvProc = require("collector.kvProc") +local CvProc = require("collector.vproc") +local pystring = require("common.pystring") +local dockerinfo = require("common.dockerinfo") +local json = require("cjson") +local CPodMem = class("podmem", CkvProc) +local ChttpCli = require("httplib.httpCli") +local podman = require("collector.podMan.podsAll") + +function CPodMem:_init_(proto, pffi, mnt, pFile) + CkvProc._init_(self, proto, pffi, mnt, pFile , "podmem") + self._ffi = require("collector.native.plugincffi") + self.cffi = self._ffi.load("podmem") + self.root_fs = mnt + self.proc_fs = mnt .. "/proc/" + self.allcons = {} + self.inodes = {} + self.podmemres = {} + self.blacklist = {["arms-prom"] = 1, ["kube-system"] = 1, ["kube-public"] = 1, ["kube-node-lease"] = 1} + -- self.blacklist= {} + self.cffi.monitor_init(self.root_fs) +end + +-- function CPodMem:_del_() +-- self.cffi.monitor_exit() +-- end + +function CPodMem:get_inode(file) + local f=stat.lstat(file) + if f ~= nil then + return f["st_ino"] + else + return -1 + end +end + + +function CPodMem:get_allcons() + local cri_cons = podman:getAllcons(self.root_fs) + for _,v in pairs(cri_cons) do + if not self.blacklist[v['pod']['namespace']] then + local path = self.root_fs .. "/sys/fs/cgroup/memory/" .. v['path'] + local inode = self:get_inode(path) + self.allcons[v['name']..v['pod']['name']] = {["pod"]=v['pod']['name'], ["ns"]=v['pod']['namespace'], ["path"]=path, ["inode"] = inode, ["cname"]=v['name']} + self.inodes[inode] = v['name']..v['pod']['name'] + end + end +end + +function CPodMem:proc(elapsed, lines) + CvProc.proc(self) + self.allcons = {} + self.inodes = {} + self.podmemres = {} + self:get_allcons() + -- for k,v in pairs(self.inodes) do print(k,v) end + -- for k,v in pairs(self.allcons) do for k1,v1 in pairs(v) do print(k,k1,v1) end end + local fs = io.open("/tmp/.memcg.txt", "w") + for k,v in pairs(self.allcons) do + fs:write(v['path']) + fs:write("\n") + end + fs:close() + + local resptr = self.cffi.scanall() + if not resptr then return end + + local res = self._ffi.string(resptr) + + local reslines = pystring:splitlines(res) + for _,line in pairs(reslines) do + local cinode, cache, size, filen = line:match("cinode=(%d+) cached=(%d+) size=(%d+) file=(%S+)") + if self.inodes[tonumber(cinode)] ~= nil then + if filen:find("overlayfs/snapshots/%d+/fs") ~= nil then + filen = pystring:split(pystring:split(filen,"overlayfs/snapshots/")[2],"/fs/")[2] + filen = "/" .. filen + end + if filen:find("diff") ~= nil then filen = pystring:split(filen,"diff")[2] end + local cname = self.inodes[tonumber(cinode)] + if not self.podmemres[cname] then self.podmemres[cname]= {} end + self.podmemres[cname][filen] = {["pod"]=self.allcons[cname]['pod'], ["ns"]=self.allcons[cname]['ns'], ["size"]=size, ["cache"]=cache, ["cname"]=self.allcons[cname]['cname']} + end + end + self._ffi.C.free(resptr) + + for k,v in pairs(self.podmemres) do + for k1,v1 in pairs(v) do + -- for k2,v2 in pairs(v1) do print(k,k1,k2,v2) end + local cell = {{name="size", value=tonumber(v1['size'])}} + local label = {{name="podname",index=v1['pod'],}, {name="podns",index = v1['ns'],},{name="file",index = k1,},{name="container", index=v1['cname']},} + self:appendLine(self:_packProto("podmem", label, cell)) + cell = {{name="cached", value=tonumber(v1['cache'])}} + label = {{name="podname",index=v1['pod'],}, {name="podns",index = v1['ns'],},{name="file",index = k1,},{name="container", index=v1['cname']},} + self:appendLine(self:_packProto("podmem", label, cell)) + end + end + self:push(lines) +end +return CPodMem diff --git a/source/tools/monitor/unity/collector/proc_meminfo.lua b/source/tools/monitor/unity/collector/proc_meminfo.lua index 2902cd848882d6ea116aed725452f20eca424184..5c6ebc836c918418f40a92d509e51fecea708d81 100644 --- a/source/tools/monitor/unity/collector/proc_meminfo.lua +++ b/source/tools/monitor/unity/collector/proc_meminfo.lua @@ -19,10 +19,6 @@ function CprocMeminfo:_init_(proto, pffi, mnt, pFile) vs = {} } self:readIomem() - self:readVmalloc() - self:readUsed() - self:readHugepage(2048,"huge_2M") - self:readHugepage(1048576,"huge_1G") end function CprocMeminfo:readIomem() @@ -48,7 +44,7 @@ function CprocMeminfo:readVmalloc() end function CprocMeminfo:readUsed() - local f = assert(io.popen('free -k','r')) + local f = io.popen('free -k','r') io.input(f) for line in io.lines() do if string.find(line,'Mem') then @@ -92,6 +88,10 @@ function CprocMeminfo:proc(elapsed, lines) self:readKV(line) end local tmp_dict = self._protoTable_dict.vs + self:readVmalloc() + self:readUsed() + self:readHugepage(2048,"huge_2M") + self:readHugepage(1048576,"huge_1G") local cell = {name="total", value=tmp_dict["MemTotal"]+tmp_dict["res"]} table.insert(self._protoTable["vs"], cell) diff --git a/source/tools/monitor/unity/collector/proc_mounts.lua b/source/tools/monitor/unity/collector/proc_mounts.lua index 2134f8a69e47288af174f9c9ddd834da5e3ea576..96e77b2bc3f37e062b1967d8490019f064e16e51 100644 --- a/source/tools/monitor/unity/collector/proc_mounts.lua +++ b/source/tools/monitor/unity/collector/proc_mounts.lua @@ -47,7 +47,8 @@ end local function get_point(fName) local lines = get_lines(fName) - local lOut = {"devtmpfs", "tmpfs"} + ---local lOut = {"devtmpfs", "tmpfs"} + local lOut = {} local tDev = {} local ret = {} for _, line in ipairs(lines) do @@ -115,4 +116,4 @@ function CprocMounts:proc(elapsed, lines) self:push(lines) end -return CprocMounts \ No newline at end of file +return CprocMounts diff --git a/source/tools/monitor/unity/etc/base.yaml b/source/tools/monitor/unity/etc/base.yaml index 9c780766085d4b1502b361dc294661e27b522190..c784e6423989083471f048adcbc76669d7e6cd32 100644 --- a/source/tools/monitor/unity/etc/base.yaml +++ b/source/tools/monitor/unity/etc/base.yaml @@ -1,6 +1,6 @@ config: freq: 15 # unit second - port: 8405 # bind port + port: 8400 # bind port bind_addr: 0.0.0.0 # bind ip backlog: 32 # listen backlog identity: # support hostip, curl(need url arg), hostname, file(need path arg), specify(need name arg) diff --git a/source/tools/monitor/unity/etc/daemonset.yaml b/source/tools/monitor/unity/etc/daemonset.yaml new file mode 100644 index 0000000000000000000000000000000000000000..da1ef1e6565230b813867dffcb962c31af2cc0e8 --- /dev/null +++ b/source/tools/monitor/unity/etc/daemonset.yaml @@ -0,0 +1,104 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: sysom + namespace: kube-system +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: sysom-role +rules: + - apiGroups: + - '' + resources: + - pods + - nodes + - nodes/status + - nodes/pods + - events + verbs: + - get + - list + - watch + - apiGroups: + - '' + resources: + - nodes/proxy + verbs: + - '*' +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: sysom-binding +subjects: + - kind: ServiceAccount + name: sysom + namespace: kube-system +roleRef: + kind: ClusterRole + name: sysom-role + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + app: sysom + name: sysom + namespace: kube-system +spec: + revisionHistoryLimit: 10 + selector: + matchLabels: + app: sysom + template: + metadata: + labels: + app: sysom + spec: + containers: + - command: + - /bin/sh + - '-c' + - cd /root/dist/app/beeQ && sh ./run.sh + image: 'ackpod-registry.cn-shanghai.cr.aliyuncs.com/mem/sysom:v2.2' + imagePullPolicy: IfNotPresent + name: sysom + ports: + - containerPort: 8889 + hostPort: 8889 + name: sysom + protocol: TCP + resources: + requests: + cpu: 250m + memory: 250Mi + securityContext: + privileged: true + volumeMounts: + - mountPath: /mnt/host + name: volume-sysom + - mountPath: /sys/kernel/debug + name: volume-debugfs + hostNetwork: true + hostPID: true + restartPolicy: Always + serviceAccount: sysom + serviceAccountName: sysom + terminationGracePeriodSeconds: 30 + volumes: + - hostPath: + path: / + type: '' + name: volume-sysom + - hostPath: + path: /sys/kernel/debug + type: '' + name: volume-debugfs + updateStrategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + type: RollingUpdate diff --git a/source/tools/monitor/unity/etc/k8s.yaml b/source/tools/monitor/unity/etc/k8s.yaml new file mode 100644 index 0000000000000000000000000000000000000000..19e6059ec0fe78268c4c0c31e6a926f4ff8cff96 --- /dev/null +++ b/source/tools/monitor/unity/etc/k8s.yaml @@ -0,0 +1,310 @@ +config: + freq: 60 # unit second + port: 8889 # bind port + bind_addr: 0.0.0.0 # bind ip + backlog: 32 # listen backlog + identity: # support hostip, curl(need url arg), hostname, file(need path arg), specify(need name arg) + # mode: curl + # url: "http://100.100.100.200/latest/meta-data/instance-id" + # name: test_specify + mode: curl + url: "http://100.100.100.200/latest/meta-data/instance-id" + # real_timestamps: true + # unix_socket: "/tmp/sysom_unity.sock" + proc_path: /mnt/host/ # in container mode, like -v /:/mnt/host , should use /mnt/host/ + db: + rotate: 7 # tsdb file retention time, unit day + budget: 200 # max query buffer from tsdb. + limit: + cpu: 90 # unit % + mem: 200 # unit mb + tasks: 10 # monitor 10 pid max. + +outline: + - /var/sysom/outline + +container: + mode: "pods" + luaPlugin: ["cg_cpu_cfs_quota","cg_mem_drcm_glob_latency","cg_memory_util","cg_cpu_stat_sample", "cg_cpuacct_stat","cg_memory_drcm_latency", "cg_memory_fail_cnt","cg_memory_dcmp_latency"] + directCgPath: + - "/" + - "/kubepods.slice" + - "/kubepods.slice/kubepods-besteffort.slice" + - "/kubepods.slice/kubepods-burstable.slice" + + indirectCgPath: + - "kubepods.slice" + - "kubepods.slice/kubepods-besteffort.slice" + - "kubepods.slice/kubepods-burstable.slice" + + indirectCgPath1: + - path: "/kubepods.slice" + child1: "/kubepods%-pod" + child2: "/cri%-containerd" + - path: "/kubepods.slice/kubepods-besteffort.slice" + child1: "/kubepods%-besteffort%-pod" + child2: "/cri%-containerd" + - path: "/kubepods.slice/kubepods-burstable.slice" + child1: "/kubepods%-burstable%-pod" + + +luaPlugins: ["podmem","proc_buddyinfo", "proc_diskstats", "proc_meminfo", "proc_mounts", "proc_netdev", + "proc_snmp_stat", "proc_sockstat", "proc_stat", "proc_statm", "proc_vmstat","pod_allocpage", + "proc_uptime", "proc_arp", "proc_cgroups", "proc_softirqs", "proc_softnet_stat", +] + +plugins: + - so: kmsg + description: "collect dmesg info." + - + so: proc_schedstat + description: "collect schedule stat info of percpu" + - + so: proc_loadavg + description: "collect load avg" + - so: net_health + description: "tcp net health." + - so: net_retrans + description: "tcp retrans monitor." + - so: cpudist + description: "sched delay" + #- + # so: unity_irqoff + # description: "irqoff:detect irq turned off and can't response" + #- + # so: gpuinfo + # description: "collect gpuinfo" + +metrics: + - + title: sysom_proc_cpu_total + from: cpu_total + head: mode + help: "cpu usage info for total." + type: "gauge" + - title: sysom_proc_cpus + from: cpus + head: mode + help: "cpu usage info for per-cpu." + type: "gauge" + - title: sysom_proc_sirq + from: sirq + head: type + help: "system soft irq times." + type: "gauge" + - title: sysom_proc_stat_counters + from: stat_counters + head: counter + help: "system state counter." + type: "gauge" + - title: sysom_proc_meminfo + from: meminfo + head: value + help: "meminfo from /proc/meminfo." + type: "gauge" + - title: sysom_proc_vmstat + from: vmstat + head: value + help: "vmstat info from /proc/vmstat." + type: "gauge" + - title: sysom_proc_self_statm + from: self_statm + head: value + help: "statm info from /proc/self/statm." + type: "gauge" + - title: sysom_proc_networks + from: networks + head: counter + help: "networks info from /proc/net/dev." + type: "gauge" + - title: sysom_proc_disks + from: disks + head: counter + help: "disk info from /proc/diskstats." + type: "gauge" + - title: sysom_proc_pkt_status + from: pkt_status + head: counter + help: "net status info from /proc/net/snmp and /proc/net/status." + type: "gauge" + - title: sysom_fs_stat + from: fs_stat + head: counter + help: "file system information." + type: "gauge" + - title: sysom_sock_stat + from: sock_stat + head: value + help: "sock stat counters from /proc/net/sockstat" + type: "gauge" + - title: sysom_proc_schedstat + from: proc_schedstat + head: value + help: "schedule state of percpu." + type: "gauge" + - title: sysom_proc_loadavg + from: proc_loadavg + head: value + help: "loadavg of system from /proc/loadavg" + type: "gauge" + - title: sysom_proc_buddyinfo + from: buddyinfo + head: value + help: "buddyinfo of system from /proc/buddyinfo" + type: "gauge" + - title: sysom_IOMonIndForDisksIO + from: IOMonIndForDisksIO + head: value + help: "Disk IO indicators and abnormal events" + type: "gauge" + - title: sysom_IOMonIndForSystemIO + from: IOMonIndForSystemIO + head: value + help: "System indicators and abnormal events about IO" + type: "gauge" + - title: sysom_IOMonDiagLog + from: IOMonDiagLog + head: value + help: "Diagnose log for IO exception" + type: "gauge" + - title: sched_moni_jitter + from: sched_moni_jitter + head: value + help: "nosched/irqoff:sys and irqoff hold cpu and didn't scheduling" + type: "gauge" + - title: sysom_cpu_dist + from: cpu_dist + head: value + help: "task cpu sched dist." + type: "gauge" + - title: sysom_net_health_hist + from: net_health_hist + head: value + help: "net_health_hist" + type: "gauge" + - title: sysom_net_health_count + from: net_health_count + head: value + help: "net_health_count" + type: "gauge" + - title: sysom_net_retrans_count + from: net_retrans_count + head: value + help: "net_retrans_count" + type: "gauge" + - title: sysom_gpuinfo + from: gpuinfo + head: value + help: "gpuinfo of system from nvidia-smi" + type: "gauge" + - title: sysom_uname + from: uname + head: value + help: "uname info" + type: "gauge" + - title: sysom_uptime + from: uptime + head: value + help: "uptime from /proc/uptime" + type: "gauge" + - title: sysom_system_release + from: system_release + head: value + help: "system_release from /etc/os-release" + type: "gauge" + - title: sysom_cgroups + from: cgroups + head: value + help: "cgroup number." + type: "gauge" + - title: sysom_per_sirqs + from: per_sirqs + head: value + help: "per_sirqs." + type: "gauge" + - title: sysom_softnets + from: softnets + head: value + help: "cgroup number." + type: "gauge" + - title: sysom_interrupts + from: interrupts + head: value + help: "interrupts." + type: "gauge" + - title: sysom_net_ip_count + from: net_ip_count + head: value + help: "net snmp net_ip_count" + type: "gauge" + - title: sysom_net_icmp_count + from: net_icmp_count + head: value + help: "net snmp net_icmp_count" + type: "gauge" + - title: sysom_net_udp_count + from: net_udp_count + head: value + help: "net snmp net_udp_count" + type: "gauge" + - title: sysom_net_tcp_count + from: net_tcp_count + head: value + help: "net snmp net_tcp_count" + type: "gauge" + - title: sysom_net_tcp_ext_count + from: net_tcp_ext_count + head: value + help: "net stat net_tcp_ext_count" + type: "gauge" + - title: sysom_podmem + from: podmem + head: value + help: "file cache for pod" + type: "gauge" + - title: sysom_alloc_page + from: pod_alloc + head: value + help: "pod tcp memory" + type: "gauge" + - title: sysom_cg_memfail_cnt + from: cg_memfail_cnt + head: value + help: "sysom_cg_memFail_cnt" + type: "gauge" + - title: sysom_cg_memUtil + from: cg_memory_util + head: value + help: "sysom_cg_memory_util" + type: "gauge" + - title: sysom_cg_memgdrcm_latency + from: cgGlbDrcmLatency + head: value + help: "sysom global memory latency" + type: "gauge" + + - title: sysom_cg_memdrcm_latency + from: cg_memdrcm_latency + head: value + help: "sysom_cg_memdrcm_latency" + type: "gauge" + - title: sysom_cg_memmcmp_latency + from: cg_memmcmp_latency + head: value + help: "sysom_cg_memmcmp_latency" + type: "gauge" + - title: sysom_cg_cpu_stat + from: cg_cpu_stat + head: value + help: "sysom_cg_cpu_stat" + type: "gauge" + - title: sysom_cg_cpuacct_stat + from: cg_cpuacct_stat + head: value + help: "cpuacct/cpuacct.stat" + type: "gauge" + - title: sysom_cg_cfs_quota + from: cgCpuQuota + head: value + help: "cfs quota" + type: "gauge" diff --git a/source/tools/monitor/unity/httplib/coCli.lua b/source/tools/monitor/unity/httplib/coCli.lua index 327c111df8961ac62ad55ca8f28ac2bc6c52b960..c6155e281deab6e55213940dd6664248ffd79fd0 100644 --- a/source/tools/monitor/unity/httplib/coCli.lua +++ b/source/tools/monitor/unity/httplib/coCli.lua @@ -143,9 +143,20 @@ function CcoCli:pushMsg(coOut, bytes) local lines = self._proto:decode(bytes) ok, msg = coroutine.resume(coOut, lines) + if not ok then + print(string.format("coOut run failed %s", msg)) + end + return ok +end + +function CcoCli:_newOut(cli) + local coOut = coroutine.create(self.coQueFunc) + local ok, msg = coroutine.resume(coOut, self, cli, self.cffi, self._efd, coOut) if not ok then error(string.format("coOut run failed %s", msg)) + return nil end + return coOut end function CcoCli:_pollFd(bfd, cli, nes, coIn, coOut) @@ -157,7 +168,11 @@ function CcoCli:_pollFd(bfd, cli, nes, coIn, coOut) ok, msg = coroutine.resume(coIn, e) if ok then if msg then - self:pushMsg(coOut, msg) + ok = self:pushMsg(coOut, msg) + if not ok then + coOut = self:_newOut(cli) + assert(coOut) + end end else error(string.format("coIn run failed %s", msg)) @@ -177,6 +192,7 @@ function CcoCli:_pollFd(bfd, cli, nes, coIn, coOut) print("bad fd " .. fd .. "use fd " .. cli.fd) end end + return coOut end function CcoCli:_poll(cli) @@ -185,11 +201,14 @@ function CcoCli:_poll(cli) local efd = self._efd local ffi, cffi = self.ffi, self.cffi - local coOut = coroutine.create(self.coQueFunc) - ok, msg = coroutine.resume(coOut, self, cli, cffi, efd, coOut) - if not ok then - error(string.format("coOut run failed %s", msg)) - end + --local coOut = coroutine.create(self.coQueFunc) + --ok, msg = coroutine.resume(coOut, self, cli, cffi, efd, coOut) + --if not ok then + -- error(string.format("coOut run failed %s", msg)) + --end + + local coOut = self:_newOut(cli) + assert(coOut) local coIn = coroutine.create(read_stream) ok, msg = coroutine.resume(coIn, bfd) @@ -197,7 +216,6 @@ function CcoCli:_poll(cli) error(string.format("coIn run failed %s", msg)) end - local c = 1 while true do local nes = ffi.new("native_events_t") local res = cffi.poll_fds(efd, 1, nes) @@ -206,7 +224,7 @@ function CcoCli:_poll(cli) return "end poll." end if nes.num > 0 then - self:_pollFd(bfd, cli, nes, coIn, coOut) + coOut = self:_pollFd(bfd, cli, nes, coIn, coOut) else self:checkOvertime(cli, coOut, ffi) end diff --git a/source/tools/monitor/unity/test/curl/postOSS.lua b/source/tools/monitor/unity/test/curl/postOSS.lua index 8d37e291ee5d97335d751b9170b9abc775b1e15c..dc1e78d1d2a7f10700a417319dd03df360239548 100644 --- a/source/tools/monitor/unity/test/curl/postOSS.lua +++ b/source/tools/monitor/unity/test/curl/postOSS.lua @@ -13,6 +13,10 @@ local url = "http://127.0.0.1:8400/api/oss" local file = io.open("test.bin", "rb") local content = file:read("*all") file:close() -local req = {stream = content, uuid = system:guid()} -local res = cli:postTable(url, req) +local header = { + uuid = system:guid(), + ['Content-Type'] = 'application/octet-stream', + ["Content-Length"] = #content +} +local res = cli:post(url, content, header) system:dumps(res) \ No newline at end of file diff --git a/source/tools/monitor/unity/test/curl/postOSS.py b/source/tools/monitor/unity/test/curl/postOSS.py new file mode 100644 index 0000000000000000000000000000000000000000..83074a31d0c86912791929d044e14b3c85881ca7 --- /dev/null +++ b/source/tools/monitor/unity/test/curl/postOSS.py @@ -0,0 +1,11 @@ + +import requests +import uuid +import json + +url = "http://127.0.0.1:8400/api/oss" +headers = {'Content-Type': 'application/octet-stream', 'uuid': str(uuid.uuid4())} +data = b'binary data' + +response = requests.post(url, headers=headers, data=data) +print(response) diff --git a/source/tools/monitor/unity/test/unix/pyunix.py b/source/tools/monitor/unity/test/unix/pyunix.py index c215808a01506738909909d95a1c808eb63b8bbf..2355837fd84f8d55180b06f78670bd908fc1e94a 100644 --- a/source/tools/monitor/unity/test/unix/pyunix.py +++ b/source/tools/monitor/unity/test/unix/pyunix.py @@ -23,6 +23,6 @@ if __name__ == "__main__": nf = CnfPut() i = 10 while True: - nf.puts('io_burst,disk=/dev/vda1 limit=10.0,max=%d,log="io log burst"' % i) + print(nf.puts('io_burst,disk=/dev/vda1 limit=10.0,max=%d,log="io log burst"' % i)) i += 1 time.sleep(5) \ No newline at end of file diff --git a/source/tools/monitor/unity/test/unix/uniServer.py b/source/tools/monitor/unity/test/unix/uniServer.py new file mode 100644 index 0000000000000000000000000000000000000000..38a5fc2d989adebb17726665e3ca2288f268e455 --- /dev/null +++ b/source/tools/monitor/unity/test/unix/uniServer.py @@ -0,0 +1,38 @@ +import os +import socket +import select + +class SocketServer(object): + def __init__(self, sFile): + super(SocketServer, self).__init__() + + server_address = sFile + socket_family = socket.AF_UNIX + socket_type = socket.SOCK_DGRAM + self._sock = socket.socket(socket_family, socket_type) + self._sock.bind(server_address) + + def loop(self, cb): + fd = self._sock.fileno() + with select.epoll() as poll: + poll.register(fd, select.EPOLLIN) + while True: + events = poll.poll(-1) + for fd, event in events: + if event & select.EPOLLIN: + s = os.read(fd, 128 * 1024).decode() + cb(s) + if event & (select.EPOLLHUP | select.EPOLLERR): + return -1 + + def __del__(self): + self._sock.close() + + +def cbTest(s): + print("recv: %s" % s) + + +if __name__ == "__main__": + s = SocketServer("/tmp/sysom") + s.loop(cbTest) \ No newline at end of file diff --git a/source/tools/monitor/unity/yamls/group.yaml b/source/tools/monitor/unity/yamls/group.yaml deleted file mode 100644 index ec7217b891a0ccc758e46b867cf0de87603984b9..0000000000000000000000000000000000000000 --- a/source/tools/monitor/unity/yamls/group.yaml +++ /dev/null @@ -1,73 +0,0 @@ -config: - freq: 20 # unit second - daemon: true - port: 8400 # bind port - bind_addr: 127.0.0.1 # bind ip - backlog: 32 # listen backlog - identity: # support hostip, curl(need url arg), hostname, file(need path arg), specify(need name arg), env(need name arg) - mode: hostip - proc_path: / # in container mode, like -v /:/mnt/host , should use /mnt/host/ - db: - rotate: 7 # tsdb file retention time, unit day - budget: 200 # max query buffer from tsdb. - limit: - cpu: 30 # unit % - mem: 50 # unit mb - tasks: 10 # monitor 10 pid max. - -outline: - - /var/sysom/outline - -pushTo: - to: "Influx" - host: "ld-8vb0s2ih252f53pv4-proxy-tsdb.lindorm.rds.aliyuncs.com" - port: 8242 - url: "/api/v2/write?db=sysom" - -luaPlugins: ["proc_buddyinfo", "proc_diskstats", "proc_meminfo", "proc_mounts", "proc_netdev", - "proc_snmp_stat", "proc_sockstat", "proc_stat", "proc_statm", "proc_vmstat", - "proc_uptime"] - -plugins: - - so: kmsg - description: "collect dmesg info." - - so: net_health - description: "tcp net health." - - so: net_retrans - description: "tcp retrans monitor." - - so: virtout - description: "virt status out put." - - so: sum_retrans - description: "summary retrans out put." - -metrics: - - title: sysak_proc_pkt_status - from: pkt_status - head: counter - help: "net status info from /proc/net/snmp and /proc/net/status." - type: "gauge" - - title: sysak_net_health_hist - from: net_health_hist - head: value - help: "net_health_hist" - type: "gauge" - - title: sysak_net_health_count - from: net_health_count - head: value - help: "net_health_count" - type: "gauge" - - title: sysak_net_retrans_count - from: net_retrans_count - head: value - help: "net_retrans_count" - type: "gauge" - - title: sysak_virtout_dist - from: virtout_dist - head: value - help: "sysak_virtout_dist" - type: "gauge" - - title: sysak_retrans - from: retrans - head: value - help: "sysak_retrans" - type: "gauge"