04月03, 2019

Linux系统分析系统启动性能工具systemd-analyze

一、命令列表

systemd-analyze [OPTIONS...] [time]
systemd-analyze [OPTIONS...] blame
systemd-analyze [OPTIONS...] critical-chain [UNIT...]
systemd-analyze [OPTIONS...] plot [> file.svg]
systemd-analyze [OPTIONS...] dot [PATTERN...] [> file.dot]
systemd-analyze [OPTIONS...] dump
systemd-analyze [OPTIONS...] set-log-level LEVEL
systemd-analyze [OPTIONS...] set-log-target TARGET
systemd-analyze [OPTIONS...] get-log-level
systemd-analyze [OPTIONS...] get-log-target
systemd-analyze [OPTIONS...] syscall-filter [SET…]
systemd-analyze [OPTIONS...] verify [FILES...]

二、参数

systemd-analyze
    可以显示系统启动过程中的性能统计数据、 获取 systemd 系统管理器的状态与跟踪信息、 校验单元文件的正确性。

systemd-analyze time
    可以显示如下时间: (1)在启动第一个用户态进程(init)之前,内核运行了多长时间; (2)在切换进入实际的根文件系统之前,initrd(initial RAM disk)运行了多长时间; (3)进入实际的根文件系统之后,用户空间启动完成花了多长时间。 注意,上述时间只是简单的计算了系统启动过程中到达不同标记点的时间, 并没有计入各单元实际启动完成所花费的时间以及磁盘空闲的时间。

systemd-analyze blame
    按照每个单元花费的启动时间从多到少的顺序,列出所有当前正处于活动(active)状态的单元。 这些信息有助于用户优化系统启动速度。 不过需要注意的是,这些信息也可能具有误导性, 因为花费较长时间启动的单元,有可能只是在等待另一个依赖单元完成启动。

systemd-analyze critical-chain [UNIT…]
    为指定的单元(省略参数表示默认启动目标单元)以树状形式显示时间关键链(time-critical chain)。 "@"后面的时刻表示该单元的启动时刻; "+"后面的时长表示该单元总计花了多长时间才完成启动。 不过需要注意的是, 这些信息也可能具有误导性, 因为花费较长时间启动的单元, 有可能只是在等待另一个依赖单元完成启动。

systemd-analyze plot
    输出一个 SVG 图像,详细显示每个单元的启动时刻, 并高亮显示每个单元总计花了多长时间才完成启动。

systemd-analyze dot
    按照 GraphViz dot(1) 格式输出单元间的依赖关系图。 在实践中,通常使用 systemd-analyze dot | dot -Tsvg > systemd.svg 命令来最终生成描述单元间依赖关系的 SVG 图像。 除非使用了 --order 或 --require 选项限定仅显示特定类型的依赖关系, 否则将会显示所有的依赖关系。如果指定了至少一个 PATTERN 参数(例如 *.target 这样的 shell 匹配模式), 那么将会仅显示所有匹配这些模式的单元的直接依赖关系。

systemd-analyze dump
    按照人类易读的格式输出全部单元的状态(一般都有几千数万行)。 因为它的输出格式经常在未通知的情况下发生变化, 所以切勿将此输出用于程序分析。

systemd-analyze set-log-level LEVEL
    将 systemd 守护进程的日志等级更改为 LEVEL (可使用的值参见 systemd(1) 的 --log-level= 选项)

systemd-analyze set-log-target TARGET
    将 systemd 守护进程的日志目标更改为 TARGET (可使用的值参见 systemd(1) 的 --log-target= 选项)

systemd-analyze get-log-level
    打印出 systemd 守护进程当前的日志等级。

systemd-analyze get-log-target
    打印出 systemd 守护进程当前的日志目标。

systemd-analyze syscall-filter [SET…]
    如果指定了至少一个 SET 参数,那么仅显示指定的集合所包含的系统调用列表; 否则显示全部系统调用集合的详情。注意,必须在 SET 参数中包含 "@" 前缀。

systemd-analyze verify
    校验指定的单元文件以及被指定的单元文件引用的其他单元文件的正确性,并显示发现的错误。 FILES 参数可以是单元文件的精确路径(带有上级目录),也可以仅仅是单元文件的名称(没有目录前缀)。 对于那些仅给出了文件名(没有目录前缀)的单元,将会优先在其他已经给出精确路径的单元文件的所在目录中搜索, 如果没有找到,将会继续在常规的单元目录中搜索(详见 systemd.unit(5) 手册)。 可以使用 $SYSTEMD_UNIT_PATH 环境变量来更改默认的单元搜索目录。

如果没指定任何命令,那么等价于使用 systemd-analyze time 命令。


三、选项

可以识别的选项如下:

--user
    在 systemd 用户实例上操作。
--system
    在 systemd 系统实例上操作。 这是默认值。
--order, --require
    仅可与 dot 命令一起使用, 表示仅显示特定类型的依赖。 --order 表示仅显示 After= 与 Before= 依赖。 --require 表示仅显示 Requires=, Requisite=, Wants=, Conflicts= 依赖。 如果这两个选项都没有使用,那么表示显示所有依赖。
--from-pattern=, --to-pattern=
    仅可与 dot 命令一起使用, 用于筛选可以出现在依赖关系图中的单元。 这两个选项都接受一个符合 glob(7) 规范的 shell 匹配模式(例如 *.target), 用于匹配单元的名称。
    可以多次使用这两个选项, 以筛选最终允许出现在依赖关系图中的单元, 多个选项的组合规则如下: 先将多个"from"选项视为一组(内部用"OR"逻辑连接)、 再将多个"to"选项视为一组(内部用"OR"逻辑连接), 最后再将"from"组与"to"组之间用"AND"逻辑连接。 最终计算出可以出现在依赖关系图中的单元。
--fuzz=timespan
    仅可与 critical-chain 命令一起使用, 表示也显示那些比同一层次上最后一个单元完成启动的时间 提前了不足 timespan 时长的单元。 timespan 的默认单位是秒, 但是也可以明确的设置单位后缀(例如"50ms")。
--man=no
    不检查 Documentation= 中列出的手册页是否真实存在。
--generators
    调用单元生成器(参见 systemd.generator(7) 手册)。 如果以普通用户身份调用需要超级用户权限的单元生成器, 那么将会生成报错警告。
-H, --host=
    操作指定的远程主机。可以仅指定一个主机名(hostname), 也可以使用 "username@hostname" 格式。 hostname 后面还可以加上容器名(以冒号分隔), 也就是形如 "hostname:container" 的格式, 以表示直接连接到指定主机的指定容器内。 操作将通过SSH协议进行,以确保安全。 可以通过 machinectl -H HOST 命令列出远程主机上的所有容器名称。
-M, --machine=
    在本地容器内执行操作。 必须明确指定容器的名称。
-h, --help
    显示简短的帮助信息并退出。
--version
    显示简短的版本信息并退出。
--no-pager
    不将程序的输出内容管道(pipe)给分页程序。


四、退出状态

返回值为 0 表示成功, 非零返回值表示失败代码。


五、例子

1、dot 命令的例子

例 1. 把所有名称以"avahi-daemon"开头的单元的依赖关系绘制成一张图

$ systemd-analyze dot 'avahi-daemon.*' | dot -Tsvg > avahi.svg
$ eog avahi.svg

例 2. 把所有 target 单元之间的依赖关系绘制成一张图

$ systemd-analyze dot --to-pattern='*.target' --from-pattern='*.target' | dot -Tsvg > targets.svg
$ eog targets.svg


2、verify 命令的例子

目前可以检测如下错误:

未知的小节与配置指令(配置选项)

未找到必须依赖的单元

未找到 Documentation= 中列出的手册页

未找到在例如 ExecStart= 等可执行指令中设置的可执行文件(包括找到的文件不具备可执行权限)

例 3. 拼写错误的配置指令

$ cat ./user.slice
[Unit]
WhatIsThis=11
Documentation=man:nosuchfile(1)
Requires=different.service
[Service]
Description=x
$ systemd-analyze verify ./user.slice
[./user.slice:9] Unknown lvalue 'WhatIsThis' in section 'Unit'
[./user.slice:13] Unknown section 'Service'. Ignoring.
Error: org.freedesktop.systemd1.LoadFailed:
   Unit different.service failed to load:
   No such file or directory.
Failed to create user.slice/start: Invalid argument
user.slice: man nosuchfile(1) command failed with code 16

例 4. 丢失了 service 单元

$ tail ./a.socket ./b.socket
==> ./a.socket  ./b.socket <==
[Socket]
ListenStream=100
Accept=yes
$ systemd-analyze verify ./a.socket ./b.socket
Service a.service not loaded, a.socket cannot be started.
Service b@0.service not loaded, b.socket cannot be started.


六、环境变量

$SYSTEMD_PAGER
    指定分页程序。仅在未指定 --no-pager 选项时有意义。 此变量会覆盖 $PAGER 的值。如果 $SYSTEMD_PAGER 与 $PAGER 都未设置, 那么将会依次尝试如下常见的分页程序: less(1), more(1), 如果最终仍未找到分页程序,那么将不使用分页。 将此变量设为空字符串或 "cat" 等价于使用 --no-pager 选项。
$SYSTEMD_LESS
    用于覆盖默认传递给 less 程序的命令行选项("FRSXMK")。
$SYSTEMD_LESSCHARSET
    用于覆盖默认传递给 less 程序的字符集。 (如果终端兼容 UTF-8 ,那么默认值是 "utf-8" )


本文链接:https://lxyit.com/article/show/185.html

-- EOF --