SSHD에 대한 시스템 서비스 단위가 있습니다.
$ 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.
나는 *.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
전자가 주어지면 후자를 어떻게 찾을 수 있나요?
답변1
로그 파일은 단위별로 정렬되지 않습니다. 분개 항목을 게시하는 조직에는 항목과 연결된 메타데이터만 있습니다. 로그 파일이 항상 존재하는 것은 아닙니다 /var
. /run
비영구적으로 구성된 경우 로그 파일도 찾을 수 있습니다.
특정 단위에 대한 분개 항목을 추출하는 올바른 방법은 다음을 사용하거나 journalctl -u <unit_name>
사용하는 것 입니다.sd-journal
응용 프로그래밍 인터페이스. 또한 로그는 바이너리 파일이므로 정확하게 구문 분석하기 쉬운 형식은 아닙니다. 저널의 내부 형식이 안정적인 사양을 따르는지조차 확신할 수 없습니다. 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
한동안 구동해본 머신을 보면 모든 system@*.journal
파일이 80M이고 모든 user@*.journal
파일이 8.0M 입니다. 이러한 일관된 크기 조정을 통해 파일 분할은 단지 로그 회전일 뿐이라는 것을 암시합니다. 수정 날짜를 보면 이를 확인할 수도 있습니다(시퀀스를 진행하면서 날짜가 늘어나는 것을 볼 수 있습니다).
이러한 것 중 일부(예 _MACHINE_ID
: )를 파악하기 위해 일기 항목과 관련된 원시 메타데이터를 조사해야 했습니다. 얻을 수 있는 것보다 더 많은 메타데이터가 있습니다 journalctl
. sd-journal API를 사용하여 빠른 프로그램을 작성하고 "Hello"
서비스에서 인쇄했습니다. 내 일기에서 다음과 같은 데이터를 발견했습니다. 각 .xml 파일과 얼마나 많은 메타데이터가 연관되어 있는지 놀랍습니다 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
이 문제를 조사하기 위해 제가 작성한 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;
}