2022年5月

介绍与安装

atop是一个轻巧高效的系统资源与进程监控工具,其默认会以10s一次的频率来刷新数据,以10min一次的频率输出监控数据到日志文件

源码

https://github.com/Atoptool/atop

安装

yum install epel-release

yum install -y atop

基础页面

使用atop命令就能进入监控界面,整个页面被分隔成上下两块,上面显示的是系统资源相关的数据,下面显示的则是实时的进程信息

上界面

PRC | sys:过去10s所有进程在内核台运行的时间之和|usr:过去10所有进程在用户态运行的时间之和|#proc:进程总数 | #trun:过去10s转换的进程数|#tslpi:中断状态的睡眠进程|#tslpu:不可中断的睡眠进程|#zombie:过去10秒的僵尸进程数|clones:10s内clonde()被调用的次数|#exit 过去10秒退出的进程数量

CPU | sys:过去10s所有进程在内核台运行的时间占比|usr:过去10所有进程在用户态运行的时间占比| irq :CPU被用于处理中断的时间比例|idle:CPU空闲的时间比例 |wait: CPU处在进程等待磁盘IO,导致CPU空闲的时间比例 |steal: 为虚拟机准备的监控项,显示被运行在同一硬件上的其他虚拟机窃取的cpu时间的百分比 |guest: 为物理机准备的监控项,显示了虚拟机使用的cpu时间的百分比。 注意,这个百分比 与用户的百分比重合! |curf:当前频率

CPL | avg: 表示过去1分钟,5分钟,15分钟内运行队列中的平均进程数量 |csw: 指上下文交换次数 |intr: 指中断发生次数 |numcpu: 可用cpu数量 |

MEN | tot: 物理内存的总量 |free: 当前空闲的内存量 |cache: 用于页缓存的内存大小 |dirty: 页缓存中需要刷新到磁盘的内存量 |buff: 用于文件缓存的内存大小 |slab: 系统内核占用的内存大小|slrec: 可回收的slab内存量 |shmem: 包括tmpfs在内的共享内存的常驻大小 |shrss: 共享内存的常驻大小 |shswp: 当前交换的共享内存的数量 |numnode: 系统中NUMA节点的数量 |

SWP:|tot: 交换区总量 |free: 空闲交换空间大小 |swcac: 交换缓存的大小 |vmcom: 承诺的虚拟内存空间 |vmlim: 承诺空间的最大限制,默认情况下是交换大小加上50%的内存大小

LVM/MDD/DSK:逻辑卷/多设备/磁盘利用率 |busy: 磁盘忙时比例|write: 写请求 |read: 读请求 |discrd: 发出的丢弃请求的数量 |KiB/r: 每次读取的KiBytes数量 |kiB/w: 每次写入的KiBytes数量 |KiB/d: 每次丢弃的KiBytes数量 |Mbrs/w: 每秒读取的MiBytes吞吐量 |MBw/s: 每秒写入的MiBytes吞吐量 |avq: 平均队列深度|avio:一个请求所需的平均毫秒数

以上各项不是一直都会显示,如果内核不支持其中一些数据的话将不会被列出

NET 网络利用率| transport | tcpi :接收到的TCP段的数量,包括那些接收到的错误段| tcpo:传输的TCP段的数量,不包括那些只包含重传的八位字节 | udpi :收到的UDP数据包的数量 | udpo:传输的UDP数据包的数量 | tcpao:活动的TCP打开的数量 | tcppo :被动TCP打开次数 | tcprs :TCP输出重传次数 | tcpie:TCP输入错误次数 | tcpor:TCP输出复位次数 | udpnp:UDP无端口数 | udpie:UDP输入错误数 |

NET传输层(TCP和UDP)的活动显示一行,IP层显示一行,每个活动接口显示一行。
如果屏幕宽度不允许所有这些计数器,则只显示相关子集。

下界面

下界面显示的项会根据当前的选项发生变化,有时可能会因为屏幕大小显示不全,因可选项过多,此处只列出默认展示项的含义,更多可以使用man atop查询,当进程过多一页无法完全展示,可以用方向键上下来滚动

PID :进程PID
SYSCPU:内核态占用时间
USRCPU:用户态占用时间      
RDELAY :运行队列延迟,即在运行队列中等待的时间。
VGROW:过去10s增长的虚拟空间的大小   
RGROW:过去10s增长的内存的大小      
RDDSK:过去10s读磁盘的数据量  
WRDSK :过去10s写磁盘的数据量   
RUID :进程执行时的真实用户ID    
EUID:该进程执行的有效用户ID

ST       EXC:EXC 终止进程的退出代码(`ST'列的第二个位置是E)或致命信号的编号(`ST'列的第二个位置是S或C)        
THR :进程的线程总数
S:主线程当前状态,`R'表示运行(当前正在处理或在运行队列中),`S'表示可中断睡眠(等待事件发生),`D'表示可中断睡眠,`Z'表示不可中断。可中断,`Z'表示僵尸(等待与父进程同步),`T'表示停止(暂停或跟踪),`W'表示交换,`E'(退出)表示在最后一个间隔期间完成的进程。E'(exit)表示在最后的时间间隔内完成的进程。
      
CPUNR :该(主)线程正在运行或最近运行的CPU的标识       
CPU :这个进程的占用率与系统层面上这个资源的可用容量有关
CMD:进程的名称 ,进程的完整命令行(包括参数)。如果命令行的长度超过了屏幕行的长度,可以用方向键->和<-进行水平滚动。      

指令

显示正在活动的数字:
        'g' - 通用信息(默认)
        'm' - 显示内存信息
        'd' - 磁盘详细信息
        'n' - 网络详情
        's' - 调度和线程组信息
        'v' - 各种信息(ppid,用户/组,日期/时间,状态,exitcode)
        'c' - 每个进程的完整命令行
        'o' - 使用自己的输出行定义

按以下顺序对进程列表排序:
        'C' -  cpu活动
        'M' - 内存消耗
        'D' - 磁盘活动
        'N' - 网络活动
        'A' - 最活跃的系统资源(自动模式)

累计数字:
        'u' - 每个用户的总资源消耗
        'p' - 每个程序的总资源消耗(即相同的进程名称)

选择:
        'U' - 专注于特定用户名(正则表达式)
        'P' - 专注于特定的进程名称(正则表达式)

屏幕处理:
        ^ L  - 重绘屏幕
        ^ F  - 显示进程列表中的下一页(转发)
        ^ B  - 显示进程列表中的上一页(向后)

演示文稿(这些键显示在标题行中):
        'a' - 显示所有进程(默认:活动进程)(切换)
        'f' - 固定标题行的静态范围(切换)
        '1' - 显示平均每秒i.s.o.总值(切换)

原始文件查看:
        't' - 在原始文件中显示下一个样本
        'T' - 显示原始文件中的上一个示例
        'b' - 在原始文件中分支到特定时间)
        'r' - 回退到原始文件的开头)

其他命令:
        'i' - 更改间隔计时器(0 =仅手动触发器)
        't' - 手动触发强制下一个样本
        'r' - 将计数器重置为启动时间值
        'z' - 暂停按钮以冻结当前样本(切换)

        'l' - 每个CPU,磁盘和接口资源的限制行
        'k' - 杀死进程(即发送信号)

        'V' - 版本信息
        '?' - 帮助信息
        'h' - 帮助信息
        'q' - 退出这个程序

日志

atop会保存日志,我们可以通过 atop -r 文件名来查看日志

日志的配置文件在/usr/share/atop/atop.daily

LOGOPTS=""                              # default options
LOGINTERVAL=600                         # default interval in seconds
LOGGENERATIONS=28                       # default number of days
LOGPATH=/var/log/atop                   # default log location

接手一个py2的zabbix报警脚本,邮件中中文全部变成乱码,查了下跟py2默认ascii编码有关,看网上的教程改了环境变量、encode, 全部没用,最后根据一片博客修改了MIMEText()

参考博客:

https://blog.csdn.net/weixin_44135827/article/details/121208657

解决方案

MIMEText("""%s"""%(content), "plain", "utf-8")
#一开始改成MIMEText(body,format,'utf-8'),结果邮件正文变成了附件

下次写脚本请用python3

bcc是一套用于基于BPF的Linux IO分析、网络、监控等的工具,本目录将介绍其中常用的几种工具

编译安装的bcc-tools一般目录在/usr/share/bcc/tools

如果遇到目录下有该命令却无法执行,检查自己是否是root用户或者sudo

缓存分析/内存

cachestat

追踪页缓存命中率/失误率

语法:./cachestat 间隔秒数 输出组数

示例

./cachestat 1 3
HITS   MISSES  DIRTIES HITRATIO   BUFFERS_MB  CACHED_MB
0        0        0    0.00%            2        835
1        0        0  100.00%            2        835
0        0        0    0.00%            2        835


MISSES ,表示缓存未命中的次数;

HITS ,表示缓存命中的次数;

DIRTIES, 表示新增到缓存中的脏页数;

HITRATIO,命中率

BUFFERS_MB 表示 Buffers 的大小,以 MB 为单位;

CACHED_MB 表示 Cache 的大小,以 MB 为单位。

cachetop

追踪各进程的页缓存命中率/失误率

./cachetop

输出类似top,默认5s一刷新,字段含义与cachestat相同,READ_HIT% WRITE_HIT%表示读写缓存命中率

示例

05:40:04 Buffers MB: 2 / Cached MB: 835 / Sort: HITS / Order: descending
PID      UID      CMD              HITS     MISSES   DIRTIES  READ_HIT%  WRITE_HIT%
   15086 root     crond                1050        0        0     100.0%       0.0%
   15088 root     sa1                   719        0        0     100.0%       0.0%
   15088 root     sh                    709        0        0     100.0%       0.0%
   15088 root     sadc                  616        1        0       99.8%       0.0%
   15087 root     unix_chkpwd           498        0        0     100.0%       0.0%
   15089 root     sa1                   483        0        0     100.0%       0.0%
   15090 root     sa1                   483        0        0     100.0%       0.0%
   15090 root     date                  465        0        0     100.0%       0.0%
   15089 root     date                  462        0        0     100.0%       0.0%
   15092 root     systemd-cgroups    433        0        0     100.0%       0.0%
   15091 root     systemd-cgroups    427        0        0     100.0%       0.0%
   15088 root     crond                 310        0        0     100.0%       0.0%
   15087 root     crond                 130        0        0     100.0%       0.0%
       1 root     systemd                44        0        0     100.0%       0.0%
     556 root     systemd-journal         9        0        0     100.0%       0.0%
   15091 root     kworker/u8:2            6        0        0     100.0%       0.0%
   15092 root     kworker/u8:2            6        0        0     100.0%       0.0%
     791 dbus     dbus-daemon             5        0        0     100.0%       0.0%
   15070 root     cachetop                2        0        0     100.0%       0.0%
    1505 root     crond                   1        0        0     100.0%       0.0%
     781 root     systemd-logind          1        0        0     100.0%       0.0%
    1069 root     rs:main Q:Reg           0        2        0       0.0%       0.0%
     757 root     auditd                  0        1        0       0.0%       0.0%
     
05:41:24 Buffers MB: 2 / Cached MB: 835 / Sort: HITS / Order: descending
PID      UID      CMD              HITS     MISSES   DIRTIES  READ_HIT%  WRITE_HIT%
   15070 root     cachetop                1        0        0     100.0%       0.0%

memleak

memleak用于追踪和查找内存分配和释放配对,需要Linux Kernel 4.7以上版本支持

参数

usage: memleak [-h] [-p PID] [-t] [-a] [-o OLDER] [-c COMMAND]
               [--combined-only] [--wa-missing-free] [-s SAMPLE_RATE] [-T TOP]
               [-z MIN_SIZE] [-Z MAX_SIZE] [-O OBJ] [--percpu]
               [interval] [count]
               
-h:查看帮助信息

-p PID:指定进程PID

-t:追踪所有内存分配和释放请求和结果

-a:输出未释放内存的列表

-z MIN_SIZE:捕获分配内存的最小值

-Z MAX_SIZE:捕获分配内存的最大值

示例

./memleak -z 16 -Z 32   #只捕获分析分配大小未16字节至32字节间的内存分配
Attaching to kernel allocators, Ctrl+C to quit.
[22:22:22] Top 10 stacks with outstanding allocations:
    64 bytes in 4 allocations from stack
        kmem_cache_alloc+0x14c [kernel]
        selinux_file_alloc_security+0x37 [kernel]
        security_file_alloc+0x27 [kernel]
        __alloc_file+0x5b [kernel]
        alloc_empty_file+0x4a [kernel]
        alloc_file+0x2d [kernel]
        alloc_file_pseudo+0xa8 [kernel]
        anon_inode_getfile+0x84 [kernel]
        __do_sys_perf_event_open+0x642 [kernel]
        __x64_sys_perf_event_open+0x20 [kernel]
        do_syscall_64+0x60 [kernel]
        entry_SYSCALL_64_after_hwframe+0x44 [kernel]

内核

funccount

计算内核函数调用

参数

usage: funccount [-h] [-p PID] [-i INTERVAL] [-d DURATION] [-T] [-r] [-D]
                 [-c CPU]
                 pattern
                 
  -h, --help 显示此帮助信息并退出
  -p PID, --pid PID 只跟踪这个PID
  -i INTERVAL, --interval INTERVAL
                        摘要时间间隔,秒
  -d DURATION, --duration DURATION
                        追踪的总时间,秒
  -T, --timestamp 在输出中包含时间戳
  -r, --regexp 使用正则表达式。默认为 "*"通配符
                        仅供参考。
  -D, --debug 在启动前打印BPF程序(用于调试
                        目的)。
  -c CPU, --cpu CPU只跟踪这个CPU

示例

./funccount -d 10 'vfs_*'
Tracing 56 functions for "b'vfs_*'"... Hit Ctrl-C to end.

FUNC                                    COUNT
b'vfs_statx'                                2
b'vfs_write'                                7
b'vfs_statx_fd'                            12
b'vfs_getattr'                             13
b'vfs_getattr_nosec'                       16
b'vfs_open'                                54
b'vfs_read'                                87

trace

追踪某个函数调用并打印函数参数或返回值

语法

usage: trace [-h] [-b BUFFER_PAGES] [-p PID] [-L TID] [--uid UID] [-v]
             [-Z STRING_SIZE] [-S] [-M MAX_EVENTS] [-t] [-u] [-T] [-C]
             [-c CGROUP_PATH] [-n NAME] [-f MSG_FILTER] [-B]
             [-s SYM_FILE_LIST] [-K] [-U] [-a] [-I header] [-A]
             probe [probe ...]
             
             
             
-h:查看帮助信息 

-p PID:只追踪PID进程

-L TID:只追踪TID线程

-v:显示生成的BPF程序,调试使用 

-z STRING_SIZE:收集字符串参数的长度

-s SYM_FILE_LIST:收集栈大小

-M MAX_EVENTS:打印追踪消息的最大数量

-t:打印时间,单位为秒。

-u:打印时间戳 

-T:打印时间列

-C:打印CPU ID

-K:打印每个事件的内核栈

-U:打印每个事件的用户栈

-a:打印序内核栈和用户栈的虚拟地址

-I header:增加header文件到BPF程序

probe [probe ...]:附加到函数的探针

示例

./trace 'do_sys_open "%s", arg2'
PID     TID     COMM            FUNC             -
782     782     irqbalance      do_sys_open      b'/proc/interrupts'
782     782     irqbalance      do_sys_open      b'/proc/stat'
782     782     irqbalance      do_sys_open      b'/proc/irq/36/smp_affinity'
782     782     irqbalance      do_sys_open      b'/proc/irq/37/smp_affinity'
782     782     irqbalance      do_sys_open      b'/proc/irq/0/smp_affinity'
782     782     irqbalance      do_sys_open      b'/proc/irq/1/smp_affinity'
782     782     irqbalance      do_sys_open      b'/proc/irq/6/smp_affinity'
782     782     irqbalance      do_sys_open      b'/proc/irq/8/smp_affinity'
782     782     irqbalance      do_sys_open      b'/proc/irq/12/smp_affinity'
782     782     irqbalance      do_sys_open      b'/proc/irq/14/smp_affinity'
782     782     irqbalance      do_sys_open      b'/proc/irq/15/smp_affinity'

追踪open syscall的所有调用方式

系统

execsnoop

追踪exec系统调用追踪新进程,对于使用fork而不是exec产生的进程不会包括在显示结果中

语法

usage: execsnoop [-h] [-T] [-t] [-x] [--cgroupmap CGROUPMAP]
                 [--mntnsmap MNTNSMAP] [-u USER] [-q] [-n NAME] [-l LINE] [-U]
                 [--max-args MAX_ARGS]
                 
  -h, --help            显示帮助信息并退出
  -T, --time            在输出中包括时间栏(HH:MM:SS)
  -t, --timestamp       在输出中包括时间戳
  -x, --fails           包括失败的exec()
  --cgroupmap CGROUPMAP
                        只跟踪该BPF map中的cgroup
  --mntnsmap MNTNSMAP   只跟踪该BPF map中的挂载命名空间
  -u USER, --uid USER   只跟踪这个UID
  -q, --quote           在参数周围添加引号(")
  -n NAME, --name NAME  只打印与此名称(regex)匹配的命令
  -l LINE, --line LINE  只打印参数包含此行的命令
  -U, --print-uid       打印UID列
  --max-args MAX_ARGS   被解析和显示的参数的最大数量。默认为20

ext4slower

ext4slower通过跟踪ext4文件系统的read、write、open、sync操作,并测量相应操作所耗时间,打印超过阈值的详细信息。默认阈值最小值是10ms,如果阈值为0,则打印所有事件

参数

ext4slower [-h] [-j] [-p PID] [min_ms]

-h, --help:查看帮助信息 

-j, --csv:使用csv格式打印字段

-p PID, --pid PID:只追踪PID进程

min_ms:追踪IO的阈值,默认为10

deadlock

查找正在运行进程潜在的死锁

参数

usage: deadlock [-h] [--binary BINARY] [--dump-graph DUMP_GRAPH] [--verbose]
               [--lock-symbols LOCK_SYMBOLS]
               [--unlock-symbols UNLOCK_SYMBOLS] [-t THREADS] [-e EDGES]
               pid
               
-h, --help:查看帮助信息

--binary BINARY:指定线程库,对于动态链接程序必须指定。

--dump-graph DUMP_GRAPH:导出mutex图到指定文件

--verbose:打印mutex统计信息

--lock-symbols LOCK_SYMBOLS:要追踪的锁的列表,使用逗号分隔,默认为pthread_mutex_lock。

--unlock-symbols UNLOCK_SYMBOLS:要追踪的解锁的列表,使用逗号分隔,默认为pthread_mutex_unlock。

示例

deadlock 181 --binary /lib/x86_64-linux-gnu/libpthread.so.0

查找进程181中的潜在死锁,并指定线程库/lib/x86_64-linux-gnu/libpthread.so.0

磁盘

biolatency

追踪块设备IO,记录IO延迟分布,并以直方图显示。

参数

./biolatency -h
usage: biolatency [-h] [-T] [-Q] [-m] [-D] [-F] [-e] [-j] [输出间隔] [输出次数]

-h:帮助手册

-T:输出包含时间戳

-m:输出ms级直方图

-D:打印每个磁盘设备的直方图

-F:打印每个IO集的直方图

示例

./biolatency 1 3
Tracing block device I/O... Hit Ctrl-C to end.

     usecs               : count     distribution
         0 -> 1          : 0        |                                        |
         2 -> 3          : 0        |                                        |
         4 -> 7          : 0        |                                        |
         8 -> 15         : 0        |                                        |
        16 -> 31         : 0        |                                        |
        32 -> 63         : 0        |                                        |
        64 -> 127        : 0        |                                        |
       128 -> 255        : 2        |****************************************|
       256 -> 511        : 1        |********************                    |


     usecs               : count     distribution
         0 -> 1          : 0        |                                        |
         2 -> 3          : 0        |                                        |
         4 -> 7          : 0        |                                        |
         8 -> 15         : 0        |                                        |
        16 -> 31         : 0        |                                        |
        32 -> 63         : 0        |                                        |
        64 -> 127        : 0        |                                        |
       128 -> 255        : 3        |****************************************|

biosnoop

追踪磁盘IO

语法

biosnoop [-h] [-Q]

-h: 帮助手册
-Q:包括操作系统的排队时间

示例

./biosnoop -Q
TIME(s)     COMM           PID    DISK    T SECTOR     BYTES  QUE(ms) LAT(ms)
0.000000    ?              0              R 0          8         0.00    0.36
0.063768    ?              0              R 0          8         0.00    0.18
0.063932    ?              0              R 0          8         0.00    0.16
2.047809    ?              0              R 0          8         0.00    0.19

网络

tcpconnect

tcpconnect用于追踪TCP活跃连接数量,通过动态追踪内核tcp_v4_connect和tcp_v6_connect函数,并记录函数内的任何变化。

语法

tcpconnect [-h] [-c] [-t] [-x] [-p PID] [-P PORT]

-h:查看帮助信息

-t:打印时间戳 

-c:统计每个源IP和目的IP/端口的连接数

-p PID:只追踪PID进程

-P PORT:要追踪的目的端口列表,使用逗号分隔

## 数据库

dbstat

将 MySQL/PostgreSQL 的查询延迟汇总为直方图

语法

usage: dbstat [-h] [-v] [-p [PID [PID ...]]] [-m THRESHOLD] [-u] [-i INTERVAL]
              {mysql,postgres}

positional arguments:
  {mysql,postgres}      the database engine to use
  
  -h, --help 显示此帮助信息并退出
  -v, --verbose 打印BPF程序
  -p [PID [PID ...]], --pid [PID [PID ...]]
                        追踪的PID(s)。
  -m THRESHOLD, --threshold THRESHOLD
                        追踪比该阈值慢的查询(ms)
  -u, --microseconds 显示以微秒为单位的查询延迟(默认。
                        毫秒)。
  -i INTERVAL, --interval INTERVAL
                        打印这个时间间隔的摘要(秒)。

示例

    dbstat postgres     # display a histogram of PostgreSQL query latencies
    dbstat mysql -v     # display MySQL latencies and print the BPF program
    dbstat mysql -u     # display query latencies in microseconds (default: ms)
    dbstat mysql -m 5   # trace only queries slower than 5ms
    dbstat mysql -p 408 # trace queries in a specific process

dbslower

跟踪 MySQL/PostgreSQL 的查询时间高于阈值

语法

usage: dbslower [-h] [-v] [-p [PID [PID ...]]] [-x PATH] [-m THRESHOLD]
                {mysql,postgres}

positional arguments:
  {mysql,postgres}      the database engine to use
  
  -h, --help 显示此帮助信息并退出
  -v, --verbose 打印BPF程序
  -p [PID [PID ...]], --pid [PID [PID ...]]
                        追踪的PID(s)。
  -x PATH, --exe 二进制文件的PATH路径
  -m THRESHOLD, --threshold THRESHOLD
                        追踪比该阈值慢的查询(ms)

示例

    dbslower postgres            # trace PostgreSQL queries slower than 1ms
    dbslower postgres -p 188 322 # trace specific PostgreSQL processes
    dbslower mysql -p 480 -m 30  # trace MySQL queries slower than 30ms
    dbslower mysql -p 480 -v     # trace MySQL queries & print the BPF program
    dbslower mysql -x $(which mysqld)  # trace MySQL queries with uprobes

编译llvm,报错

CMake Error at tools/clang/cmake/modules/CMakeLists.txt:1 (include):
  include could not find requested file:

    ExtendPath


CMake Error at tools/clang/cmake/modules/CMakeLists.txt:3 (include):
  include could not find requested file:

    FindPrefixFromConfig


CMake Error at tools/clang/cmake/modules/CMakeLists.txt:42 (find_prefix_from_config):
  Unknown CMake command "find_prefix_from_config".

解决方案

谷歌一下,发现上面也有人在吐槽这事,用工地英语辨识了一会,大概意思是我用的这个版本的llvm(14),打包的时候漏打包了这几个文件,从github上获取文件后手动添加到llvm/cmake下面就行

吐槽贴网址

漏打包的文件的网址

bcc需要py3,于是把python软连接对应版本改到3上面去,结果导致yum等依赖py2的程序无法正常运行

修改方式

# yum install rpm-build -y
  File "/bin/yum", line 30
    except KeyboardInterrupt, e:
                            ^
SyntaxError: invalid syntax

 vi /usr/bin/yum
#!/usr/bin/python2.7 #根据实际的版本来


  File "/usr/libexec/urlgrabber-ext-down", line 28
    except OSError, e:
                  ^
SyntaxError: invalid syntax


Exiting on user cancel
# vi /usr/libexec/urlgrabber-ext-down