rub*_*cks 0 linux systemd systemd-journald
我有一个用于 sshd 的 systemd 服务单元:
$ systemctl status sshd
* ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2020-09-30 18:54:10 UTC; 6s ago
Process: 13923 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
Process: 13918 ExecReload=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
Process: 6287 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
Main PID: 6296 (sshd)
Tasks: 1 (limit: 4915)
CGroup: /system.slice/ssh.service
`-6296 /usr/sbin/sshd -D
Sep 30 18:54:10 machine systemd[1]: Starting OpenBSD Secure Shell server...
Sep 30 18:54:10 machine sshd[6296]: Server listening on 0.0.0.0 port 22.
Sep 30 18:54:10 machine sshd[6296]: Server listening on :: port 22.
Sep 30 18:54:10 machine systemd[1]: Started OpenBSD Secure Shell server.
Run Code Online (Sandbox Code Playgroud)
我有一些*.journal
它写的文件:
$ find /var/log/journal -type f -name 'system@*.journal' -exec grep -l 'OpenBSD' {} +
/var/log/journal/0123456789abcdef0123456789abcdef/system@0123456789abcdef0123456789abcdef-000000000100bfdd-0005ac0c092a655f.journal
/var/log/journal/0123456789abcdef0123456789abcdef/system@0123456789abcdef0123456789abcdef-000000000102d6c3-0005ac2251abe7d9.journal
/var/log/journal/0123456789abcdef0123456789abcdef/system@0123456789abcdef0123456789abcdef-00000000010fc6d5-0005ac9be551a106.journal
/var/log/journal/0123456789abcdef0123456789abcdef/system@0123456789abcdef0123456789abcdef-0000000000e043b9-0005aad981c2d167.journal
/var/log/journal/0123456789abcdef0123456789abcdef/system@0123456789abcdef0123456789abcdef-00000000010d9bf1-0005ac875e1241e7.journal
Run Code Online (Sandbox Code Playgroud)
鉴于前者,我如何找到后者?
日志文件不按单位排序。发布日志条目的单位只是与条目关联的元数据。日志文件也不总是在/var
. /run
如果配置为非持久性,也可以在其中找到它们。
提取特定单元的日记帐分录的正确方法是使用journalctl -u <unit_name>
或使用sd-journal
API。此外,日志是一个二进制文件,所以它的格式并不完全是解析友好的。我什至不确定期刊的内部格式是否遵循稳定的规范。 journalctl
或者 API 绝对是读取这些文件的方式。
如果您问这个问题是为了备份(或发送以进行故障排除)特定文件,则需要将所有这些文件视为一个单元。
由于您专门询问了这些日志文件的文件命名约定,因此我花了一些时间对此进行了调查。重新启动后,唯一的文件/run/log/journal
是/run/log/journal/c13e4a2f54334a95891a6a471db3b7e0/system@edd0c14e44a240038601194807d5c28e-0000000000000001-0005b08ccb2c37b3.journal
.
我将其分解为以下内容以尝试理解命名约定:
/run/ <-- run/var
log/journal/ <-- standard location
c13e4a2f54334a95891a6a471db3b7e0/ <-- _MACHINE_ID
system@ <-- system/user
edd0c14e44a240038601194807d5c28e- <-- Some bus/boot/session ID?
0000000000000001- <-- Sequence number (also looks like offsets as 4-KB blocks in hex)
0005b08ccb2c37b3 <-- Timestamp (time since epoch in hex)
.journal <-- Extension
Run Code Online (Sandbox Code Playgroud)
当我查看运行了一段时间的机器时,所有system@*.journal
文件都是80M,而所有user@*.journal
文件都是8.0M。有了如此一致的大小,它确实表明文件拆分只是日志轮换。我还可以通过查看修改日期来确认这一点(随着我们按顺序前进,我看到日期在增加)。
为了弄清楚其中的一些事情(例如_MACHINE_ID
),我必须查看与日记条目相关的原始元数据。有比你能得到的更多的元数据journalctl
。我用 sd-journal API 编写了一个快速程序,并"Hello"
从服务中打印出来。我在日记中找到了它,有以下数据。令人惊讶的是,每个printf
.
_UID=0
_GID=0
_CAP_EFFECTIVE=3fffffffff
_TRANSPORT=stdout
_STREAM_ID=2ee82c395817429b975770acb1306d11
SYSLOG_IDENTIFIER=counter
_PID=6523
_COMM=counter
_EXE=/usr/local/bin/counter
_CMDLINE=/usr/local/bin/counter
_SYSTEMD_CGROUP=/system.slice/counter.service
_SYSTEMD_UNIT=counter.service
_SYSTEMD_INVOCATION_ID=711962f5d7bf487b9a262b824c297a42
MESSAGE=Hello
PRIORITY=6
SYSLOG_FACILITY=3
_BOOT_ID=bf0d96cbab2144e3a8544b0e8a0eacc6
_MACHINE_ID=c13e4a2f54334a95891a6a471db3b7e0
_HOSTNAME=simswe24
_TRANSPORT=journal
_SELINUX_CONTEXT=unconfined
Run Code Online (Sandbox Code Playgroud)
如果您对我编写的用于调查此问题的 sd-journal 程序感兴趣,请看这里:
// Compile with `gcc journalctl.c -lsystemd`
#include <systemd/sd-journal.h>
#include <stdio.h>
int main()
{
// Open the log
sd_journal* journal;
if ( sd_journal_open(&journal, SD_JOURNAL_LOCAL_ONLY) < 0 )
{
return 1; // Couldn't open journal
}
// Subscribe to specific logs:
// Messages from the service itself
int r = sd_journal_add_match(journal, "_SYSTEMD_UNIT=counter.service", 0);
r = r ? r : sd_journal_add_disjunction(journal);
// Messages from PID 1 (systemd) about this service
r = r ? r : sd_journal_add_match(journal, "_PID=1", 0);
r = r ? r : sd_journal_add_match(journal, "UNIT=counter.service", 0);
r = r ? r : sd_journal_add_disjunction(journal);
if ( r < 0 )
{
return 1; // Could not subscribe to all journal entries
}
r = sd_journal_seek_head(journal);
if ( r < 0 )
{
return 1; // Problem finding the head of the log
}
// Read the log
int skip_seek=1;
while( skip_seek || (sd_journal_next(journal) > 0 ) )
{
const void* data = 0;
size_t length;
skip_seek = 0;
sd_journal_restart_data(journal);
SD_JOURNAL_FOREACH_DATA(journal, data, length)
{
printf("%s\n", data);
};
}
sd_journal_close(journal);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
39 次 |
最近记录: |