systemd的日志管理进程journald

Posted feng-land

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了systemd的日志管理进程journald相关的知识,希望对你有一定的参考价值。

使用Journalctl查看并操作Systemd日志

systemd拥有强大的处理与系统日志记录功能。在使用其它工具时,日志往往被分散在多套系统当中,由不同的守护进程负责处理。
Journal的实现归功于journald守护进程,其负责处理由内核、initrd以及服务等产生的信息。

总体思路

Systemd journal的的深层驱动力在于以集中方式管理对来自任意来源的信息。由于大部分进程都是由systemd进程处理的,因此可以以标准化方式实现日志的收集与访问。其中journald守护进程会收集全部来源的数据并将其以二进制格式加以存储,从而实现动态操作。
将日志数据以二进制形式存储意味着这些数据可以根据需求随时以二进制输出格式显示。例如,可以通过标准syslog格式查看日志以实现日志管理,并在需要使用图形服务时将各条目作为JSON对象交由图形化服务处理。由于数据不会以纯文本形式被写入磁盘,因此无需进行格式转换。
可以将systemd journal与现有syslog方案配置使用,也可利用其替代现有的syslog功能,具体取决于实际需求。尽管systemd journal足以涵盖大部分管理工作需求,但其同时也能够补充现有日志记录机制。例如,可以建立一套集中式syslog服务器,从而对来自多台服务器的数据进行编译,或者也能够利用systemd journal将来自多项服务的日志汇总在单一系统中。

设置系统时间

使用二进制journal的一大好处在于,它能够以UTC或本地时间显示日志记录。在默认情况下,systemd会以本地时间显示结果。
有鉴于此,在使用journal之前,首先要确保时区得到正确设置。Systemd套件中还提供一款timedatectl工具,专门用于解决此问题。
首先,利用list-timezones选项查看可用时区:

timedatectl list-timezones

结果将列出系统上可用的全部时区。而后选择与服务器所在地相匹配的项目,并使用set-timezone选项加以设置:

timedatectl set-timezone Asia/Shanghai

为了确保设置使用正确的时间,可单独使用timedatectl命令或者添加status选项。显示结果如下:

[email protected]:~# timedatectl status
                      Local time: 日 2019-01-06 20:05:20 CST
                  Universal time: 日 2019-01-06 12:05:20 UTC
                        RTC time: 日 2019-01-06 12:05:20
                       Time zone: Asia/Shanghai (CST, +0800)
       System clock synchronized: yes
systemd-timesyncd.service active: yes
                 RTC in local TZ: no

基础日志查看

要查看journald守护进程收集到的日志,可使用journalctl命令。
在单独使用时,系统中的每个journal条目都会被显示在单一pager中。条目时间越早,排列越靠前

[[email protected] ~]# journalctl
-- Logs begin at 六 2018-07-21 16:57:30 CST, end at 日 2019-01-06 20:09:20 CST. --
7月 21 16:57:30 localhost.localdomain systemd-journal[336]: Runtime journal is using 6.1M (max 48.9M, leaving 73.4M of free 483.6M, current limi
7月 21 16:57:30 localhost.localdomain systemd-journal[336]: Runtime journal is using 6.1M (max 48.9M, leaving 73.4M of free 483.6M, current limi
7月 21 16:57:30 localhost.localdomain kernel: Initializing cgroup subsys cpuset
7月 21 16:57:30 localhost.localdomain kernel: Initializing cgroup subsys cpu
7月 21 16:57:30 localhost.localdomain kernel: Initializing cgroup subsys cpuacct
7月 21 16:57:30 localhost.localdomain kernel: Linux version 3.10.0-229.el7.x86_64 ([email protected]) (gcc version 4.8.2 20140120 
7月 21 16:57:30 localhost.localdomain kernel: Command line: BOOT_IMAGE=/vmlinuz-3.10.0-229.el7.x86_64 root=/dev/mapper/centos-root ro rd.lvm.lv=
7月 21 16:57:30 localhost.localdomain kernel: Disabled fast string operations
7月 21 16:57:30 localhost.localdomain kernel: e820: Bios-provided physical RAM map:
7月 21 16:57:30 localhost.localdomain kernel: BIOS-e820: [mem 0x0000000000000000-0x000000000009ebff] usable
7月 21 16:57:30 localhost.localdomain kernel: BIOS-e820: [mem 0x000000000009ec00-0x000000000009ffff] reserved
7月 21 16:57:30 localhost.localdomain kernel: BIOS-e820: [mem 0x00000000000dc000-0x00000000000fffff] reserved
7月 21 16:57:30 localhost.localdomain kernel: BIOS-e820: [mem 0x0000000000100000-0x000000003fedffff] usable
7月 21 16:57:30 localhost.localdomain kernel: BIOS-e820: [mem 0x000000003fee0000-0x000000003fefefff] ACPI data
lines 1-15

可以进行翻页查看,如果系统运行时间较长,那么systemd中的日志将会非常多,这也证明了journal数据库中可观的数据量。
其格式与标准的syslog日志非常相似。然而,其收集数据的来源较syslog要丰富得多。其中包含有来自先前引导进程、内核、initrd以及应用程序标准错误与输出的日志。都可以在journal中查看。
全部时间戳都以本地时间为准。由于已经为系统正确设置了本地时间,所以显示的时间戳也都准确无误。

显示当前引导进程下的日志

最常用的是-b标记,其将显示全部最近一次重新引导后收集到的journal条目。

过往引导记录

Journal能够保存大量过往引导信息,从而允许journalctl轻松显示相关内容。
在些版本会在默认情况下保存过往引导信息,而在些则默认禁用这项功能。要启用此功能,使用以下功能用于存储journal信息的目录:

mkdir -p /var/log/journal

或者直接编辑journal配置文件:/etc/systemd/journald.conf
在[Journal]区段下将Storage=选项设定为"Persistent"以启用持久记录。
当启用保存过往引导信息功能后,journalctl会提供额外命令将各引导记录作为 独立操作单元。要查看journald中已经记录的引导信息,可使用--list-boots选项:

[[email protected]ocalhost ~]# journalctl --list-boots
 0 e88acc0fcfe34290ac8d0c28a6f8e8b8 Wed 2019-01-02 10:12:42 CST—Sun 2019-01-06 20:29:40 CST

CentOS Linux release 7.6.1810 (Core) 有此选项
CentOS Linux release 7.1.1503 (Core) 无此选项

这里每次引导都将显示为一行。第一列可用于在journalctl中引用该次引导。如果需要更为准确的引导方式,由可在第二列中找到引导ID。末尾的两次时间为当次引导的开始与结束时间。
要显示这些引导中的具体信息,则可使用第一列或第二列提供的信息。
例如,要查看上次引导的journal记录,则可使用-1相对指针配合-b标记:

journalctl -b -1

另外,也可以使用引导ID:

journalctl -b e88acc0fcfe34290ac8d0c28a6f8e8b8

时间窗

按照引导环境查看日志条目当然非常重要,但往往还需要使用与系统引导无关的时间窗作为浏览基准。这种情况在长期运行的服务器中较为常见。
可以利用--since与--until选项设定时间段,二者分别负责说明给定时间之前与之后的记录。
时间值可以多种格式输出。对于绝对时间值,可以使用以下格式:

YY-MM-DD HH:MM:SS

使用,可以通过以下命令查看全部2019年1月6日 下午5:15之后的条目:

journalctl --since "2019-01-06 17:15:00"

如果以上格式中的某些组成部分未进行填写,系统会直接进行默认填充。例如,如果日期部分未填写,则会直接显示当前日期。如果时间部分未填写,则缺少使用"00:00:00"(午夜)。第二字段亦可留空,默认为"00":

journalctl --since "2019-01-06" --until "2019-01-06 03:00"

另外,journal还能够理解部分相对值及命名简写。例如,大家可以使用"yesterday"、"today"、"tomorrow"或者"now"等表达。另外也可以使用"-"或者"+"设定相对值,或者使用"ago"之前的表达。
获取昨天数据的命令如下:

journalctl --since yesterday

按信息类型过滤

如何利用感兴趣的服务或者组件类型实现过滤。Systemd journal同样提供多种方式。

按单元

最常用的此类过滤方式当属按单元过滤了。可以使用-u选项实现这一效果。
例如,要查看系统上全部来自httpd单元的日志,可使用以下命令:

journalctl -u httpd.service

一般来诗刊是,可能需要同时按单元与时间进行信息过滤。例如,检查今天某项服务的运行状态:

journalctl -u httpd.service --since today

这种能力对于不同程序间交互及系统调试显然非常重要。

按进程、用户或者群组ID

由于某些服务当中包含多个子进程,因此我们希望通过进程ID实现查询,也可以使用相关过滤机制。
这里需要指定_PID字段。例如PID为1443,则可输入:

journalctl _PID=1443

有时候可能希望显示全部来自特定用户或者群组的日志条目,就需要使用_UID或者_GID。例如,web服务器运行在www-data用户下,则可以这样找到该用户ID:

id -u www-data
33

接下来,可以使用该ID返回过滤后的journal结果:

journalctl _UID=33 --since today

Systemd journal拥有多种可实现过滤功能的字段。其中一些来自被记录的进程,有些则由journald用于系统中收集特定时间段内的日志。
之前提到的_PID属于后一种。Journal会自动记录并检索进程PID,以备日后过滤之用。可以查看当前全部可用journal字段。

man systemd.journal-fields

下面来看针对这些字段的过滤机制,-F选项可用于显示特定journal字段内的全部可用值。
例如,要查看systemd journal拥有条目的群组ID,可使用以下命令:

[[email protected] ~]# journalctl -F _GID
998
81
996
0

其将显示全部journal已经存储至群组ID字段内的值,并可用于未来的过滤需求。

按组件路径

也可以提供路径位置以实现过滤。
如果该路径指向某个可执行文件,则journalctl会显示该可执行文件相关的全部条目。例如,要找到与bash可执行文件相关的条目:

journalctl /usr/bin/bash

一般来讲,如果某个单元可用于该可执行文件,那么此方法会更为明确且能够提供更好的相关信息(与子进程相关的条目等)。

显示内核信息

内核信息通常存在于dmesg输出结果中,journal同样可对其进行检索。要只显示此类信息,可添加-k或者-dmesg标记

journalctl -k

默认情况下,其会显示当前引导环境下的全部内核信息。也可以使用常规的引导选择标记对此前的引导记录进行查询。例如,要查询五次之前引导环境的信息:

journalctl -k -b -5

按优先级

可以使用journalctl配合-p选项显示特定优先级的信息,从而过滤掉优先级较低的信息。
例如,只显示错误级别或更高的日志条目:

journalctl -p err -b

这将只显示被传记为错误、严重、警告或者紧急级别的信息。journal的这种实现方式与标准syslog信息在级别上是一致的。可以使用优先级名称或者相关量化值。以下各数字为由最高到最低优先级:

  • 0:emerg
  • 1:alert
  • 2:crit
  • 3:err
  • 4:warning
  • 5:notice
  • 6:info
  • 7:debug

以上为可在-p选项中使用的数字或者名称。选定某一优先级会显示等级与之等同以及更高的信息。

输出格式

如果要对journal条目进行处理,可能需要使用更易使用的格式以简化数据解析工作。幸亏的是,journalctl能够以多种格式时行显示,只须添加-o选项即可。
例如,可以将journal条目输出为json格式:

[[email protected] ~]# journalctl -b -u sshd -o json
{ "__CURSOR" : "s=7ef025badca74f3f94affc2d6cd6c14b;i=837;b=39a34209e2aa400eb76ee65ef44ebd63;m=ee2886;t=57ec938c503d0;x=35f1a6c29bad20b1", "__REA
{ "__CURSOR" : "s=7ef025badca74f3f94affc2d6cd6c14b;i=838;b=39a34209e2aa400eb76ee65ef44ebd63;m=ee45bf;t=57ec938c52109;x=157396b74557694b", "__REA
{ "__CURSOR" : "s=7ef025badca74f3f94affc2d6cd6c14b;i=84e;b=39a34209e2aa400eb76ee65ef44ebd63;m=f45656;t=57ec938cb319f;x=8843692b414e8e1f", "__REA
{ "__CURSOR" : "s=7ef025badca74f3f94affc2d6cd6c14b;i=84f;b=39a34209e2aa400eb76ee65ef44ebd63;m=f4579d;t=57ec938cb32e6;x=bfaf4b232abbd818", "__REA
{ "__CURSOR" : "s=7ef025badca74f3f94affc2d6cd6c14b;i=86d;b=39a34209e2aa400eb76ee65ef44ebd63;m=3940194;t=57ec93b6adcdd;x=26b0b977cf73529", "__REA
{ "__CURSOR" : "s=7ef025badca74f3f94affc2d6cd6c14b;i=88d;b=39a34209e2aa400eb76ee65ef44ebd63;m=f81e8ac;t=57ec94758c3f5;x=bc1e102400873e87", "__RE

这种方式对于工具解析非常重要。也可以使用json-pretty格式以更好地处理数据结构:

[[email protected] ~]# journalctl -b -u sshd -o json-pretty
{
        "__CURSOR" : "s=7ef025badca74f3f94affc2d6cd6c14b;i=837;b=39a34209e2aa400eb76ee65ef44ebd63;m=ee2886;t=57ec938c503d0;x=35f1a6c29bad20b1",
        "__REALTIME_TIMESTAMP" : "1546777589515216",
        "__MONOTONIC_TIMESTAMP" : "15607942",
        "_BOOT_ID" : "39a34209e2aa400eb76ee65ef44ebd63",
        "PRIORITY" : "6",
        "_UID" : "0",
        "_GID" : "0",
        "_MACHINE_ID" : "5cb5c96afd104fa9990466a9c4faaf09",
        "SYSLOG_FACILITY" : "3",
        "SYSLOG_IDENTIFIER" : "systemd",
        "CODE_FILE" : "src/core/unit.c",
        "CODE_LINE" : "1115",
        "CODE_FUNCTION" : "unit_status_log_starting_stopping_reloading",
        "MESSAGE_ID" : "7d4958e842da4a758f6c1cdc7b36dcc5",
lines 1-15
        "_TRANSPORT" : "journal",
        "_PID" : "1",
        "_COMM" : "systemd",
        "_EXE" : "/usr/lib/systemd/systemd",
        "_CAP_EFFECTIVE" : "1fffffffff",
        "_SYSTEMD_CGROUP" : "/",
        "_HOSTNAME" : "ansible.magedu.com",
        "_CMDLINE" : "/usr/lib/systemd/systemd --switched-root --system --deserialize 24",
        "_SELINUX_CONTEXT" : "system_u:system_r:init_t:s0",
        "UNIT" : "sshd.service",
        "MESSAGE" : "Starting OpenSSH server daemon...",
        "_SOURCE_REALTIME_TIMESTAMP" : "1546777589511878"
}

以下为可用于显示的各类格式:

  • cat:只显示信息字段本身
  • export:适合传输或者备份的二进制格式
  • json:标准JSON,每行一个条目
  • json-pretty:JSON格式,适合人类阅读习惯
  • json-see:JSON格式,经过打包以兼容server-sent事件
  • short:默认syslog类输出格式
  • short-iso:默认格式,强调显示ISO 8601挂钟时间戳
  • short-monotonic:默认格式,提供普通时间戳
  • short-precise:默认格式,提供微秒级精度
  • verbose:显示该条目的全部可用journal字段,包括通常被内核隐藏的字段

活动进程监控

journalctl还能帮助管理员以类似于tail的方式监控活动或近期进程。这项功能内置于journalctl当中,鸡在无需借助于其他工具的前提下实现访问。

显示近期日志

要显示特定数量的记录,可以使用-n选项。
默认情况下,其会显示近十条记录:

journalctl -n

可以在-n 之后指定要查看的条目数量:

journalctl -n 20

追踪日志

要主动追踪当前正在编写的日志,可以使用-f标记。方式同tail -f:

journalctl -f

journal维护

存储了大量数据,还需要了解如何清理部分隐旧日志以释放存储空间。

了解现有磁盘使用量

可以利用--disk-usage标记查看journal的当前磁盘使用量:

[[email protected] ~]# journalctl --disk-usage
Journals take up 8.0M on disk.

手工写一个systemd的配置文件,让nginx服务可以开机启动

[unit]  
Description=Nginx  

[Service]  
Type=oneshot  
ExecStart=/usr/bin/nginx  
StandardOutput=syslog  
StandardError=inherit  

[Install]  
WantedBy=multi-user.target  
Requires=ssh.service  
After=ssh.service

SIG信号

名称 默认动作 说明
SIGHUP 终止进程 终端线路挂断
SIGQUIT 建立CORE文件 终止进程,并生成core文件
SIGTERM 终止进程 软件终止信号
SIGINTERRUPT

SIGHUP:本信号在用户终端连接(正常或非正常)结束时发出,通常是在终端的控制进程结束时,通知同一session内的各个作业,这里它们与控制终端不再关联
SIGQUIT:和SIGINT类似,但由QUIT字符(通常是Ctrl-)来控制,进程在收到SIGQUIT退出时会产生core文件,在这个意义上类似于一个程序错误信号
SIGTERM:程序结束(terminate)信号,与SIGKILL不同的是该信号可以被阻塞和处理,通常用来要求程序自己正常退出。shell命令kill缺省产生这个信号
SIGINTERRUPT:

用awk查看tcp连接处于各状态的连接个数

[[email protected] ~]# netstat -an | awk ‘/tcp>/ {s[$NF]++} END {for (a in s) {print a,s[a]}}‘
LISTEN 2
ESTABLISHED 1
[[email protected] ~]# netstat -an | awk ‘/tcp>/ {print $NF}‘ | sort | uniq -c
      1 ESTABLISHED
      2 LISTEN

参考链接:https://blog.csdn.net/zstack_org/article/details/56274966













































以上是关于systemd的日志管理进程journald的主要内容,如果未能解决你的问题,请参考以下文章

systemd的统一日志记录系统journalctl,助力问题定位

3-linux centos7中systemd-journald占用内存过高解决办法

Linux系统的日志管理

RH124-10

Systemd-journalctl日志管理

centos8.4中的journalctl使用