“최근 foo.service가 실행 된 시간”에서 journalctl show logs를 만드는 방법이 있습니까?


16

타이머에서 실행되는 oneshot 서비스의 출력을 보는 데 특히 관심이 있습니다. --unit플래그는 가까운이지만, 함께 서비스의 모든 실행을 연결합니다. 내가 생각할 수있는 가장 확실한 방법은 PID를 필터링하는 것이지만, 포크 재사용하는 PID 재사용 / 서비스에 대해 걱정하게 만들고 마지막 PID를 얻는 것은 매우 불편합니다. 로그를 필터링하는 데 사용할 수있는 단일 서비스 실행에 해당하는 다른 식별자가 있습니까?

편집 : 나는 그것이 정답이라면 권위있는 "아니오"를 행복하게 받아 들일 것입니다.

답변:


7

systemdversion 이후 232에는 호출 ID라는 개념이 있습니다. 장치가 실행될 때마다 고유 한 128 비트 호출 ID가 있습니다. MainPID재활용 ActiveEnterTimestamp할 수 있거나 해결에 문제가있는 것과는 달리 특정 시스템 장치 호출의 모든 로그를 가져 오는 안전한 방법입니다.

장치의 최신 호출 ID를 얻으려면

$ systemctl show --value -p InvocationID openipmi
bd3eb84c3aa74169a3dcad2af183885b

openipmi실패 여부 와 같은 최신 호출 저널을 얻으려면 하나의 라이너를 사용할 수 있습니다

$ journalctl _SYSTEMD_INVOCATION_ID=`systemctl show -p InvocationID --value openipmi.service`
-- Logs begin at Thu 2018-07-26 12:09:57 IDT, end at Mon 2019-07-08 01:32:50 IDT. --
Jun 21 13:03:13 build03.lbits openipmi[1552]:  * Starting ipmi drivers
Jun 21 13:03:13 build03.lbits openipmi[1552]:    ...fail!
Jun 21 13:03:13 build03.lbits openipmi[1552]:    ...done.

( 보다, 이전 --value부터 사용할 수 있습니다. )systemd 230InvocationID


1
누군가 이것을 조사하려고하면 journalctl --user -u UNITFILE -f -o json-pretty도움 이 될 수 있습니다. MESSAGE특히 필드를 찾고 있습니다. 또한 필요할 USER_INVOCATION_ID수도 있고 일부 메시지에는 첨부 된 호출 ID가 없으므로이 메커니즘을 통해 필터링 할 수 없다는 것을 알았습니다 . 왜 내 로깅이 잘못 구성되었는지 잘 모르겠습니다.
karlicoss

14

어떤 타임 스탬프가 가장 적합한 지 잘 모르겠지만 이것이 나에게 효과적입니다. systemctl showawk보다 타임 스탬프로 작업하는 더 좋은 방법이 있기를 바랍니다 . 타임 스탬프 형식을 제어하는 ​​방법을 알 수 없었습니다.

unit=foo.service

ts=$(systemctl show -p ActiveEnterTimestamp $unit)

echo $ts
ActiveEnterTimestamp=Fri 2016-11-11 12:30:01 MST

journalctl -u $unit --since "$(echo $ts | awk '{print $2 $3}')"

누군가가 하나의 라이너로 필요한 경우를 위해 : journalctl --since " systemctl show -p ActiveEnterTimestamp thermo.service | awk '{print $2 \" \" $3}'"-fu thermo.service | less
DimanNe

또한 사용할 수 systemctl show -p ActiveEnterTimestamp --value $unit있으므로 추가 awk가 필요하지 않습니다
karlicoss

4

부팅 플래그를 사용하여 해당 부팅에서 로그 만 가져올 수 있습니다. 예를 들어

journalctl _SYSTEMD_UNIT=avahi-daemon.service -b 5

2
이것은 내가 원하는 것과 비슷하지만 다음과 같은 상황에서는 작동하지 않습니다. 1) 마지막으로 서비스가 실행 된 이후에 컴퓨터가 재부팅 된 경우 또는 2) 마지막 부팅 이후에 서비스가 여러 번 실행 된 경우.
Jack O'Connor

왜 그것이 첫 번째 사례에서 작동하지 않는지 잘 모르겠습니다. 재부팅 된 경우에도 재부팅됩니다. 특정 부팅으로 가서 정보를 가져와야합니다. 두 번째에 관해서는 ... 당신이 맞습니다. 노이즈 로그는 서비스가 재부팅 된 횟수에 따라 다릅니다. 그러나 서비스 pid를 발견하면 _PID = XXX 인수를 사용하여 필터링 할 수 있습니다. 동일한 부팅주기에서 동일한 서비스에 대해 동일한 pid를 재사용 할 가능성은 ..... 전혀 모르지만 불가능에 가깝습니다.
Nikolaidis Fotis

타이머를 사용하거나 일회용 명령이기 때문에 부팅시 반드시 실행되는 서비스를 처리하는 데 관심이 있습니다.
Jack O'Connor

4

이들은 당신을 도울 수 있습니다 :

  • journalctl -u foo.service | 꼬리 -n 2

    또는 2 를 예상 줄 수로 바꿉니다.

  • journalctl -u foo.service --since = ' 2016-04-11 13:00:00 '

또한 마지막 런타임 타임 스탬프를 얻기 위해 이들을 결합한 다음 --since 스위치와 함께 해당 타임 스탬프를 사용할 수 있습니다.


이것은 PID 접근 방식과 비슷한 해결 방법처럼 느껴지지만 매우 수동적입니다. 내 서비스가 몇 초 동안 실행되고 많은 로그 라인을 뱉어 내면 시작 타임 스탬프가있는 첫 번째 라인을 검색해야합니다. 스크립트에서는 잘 작동하지 않습니다.
Jack O'Connor

3

Journalctl과 함께 필드 필터를 사용할 수 있습니다. 예 :

journalctl _PID=1234

다음을 사용하여 사용 가능한 모든 필드 목록을 가져옵니다.

journalctl --fields --unit kubelet

사용 가능한 필드는 _PID입니다.

당신은 사용하여 실행중인 프로세스의 PID를 얻을 수 있습니다 pidof또는systemctl show --property MainPID <SERVICE_NAME>

현재 Kubernetes kubelet 프로세스에서 로그를 얻는 방법은 다음과 같습니다.

# journalctl --unit kubelet _PID=$(systemctl show --property MainPID kubelet 2>/dev/null | cut -d= -f2) | head

이제 Kubernetes를 설치하기가 왜 어려운지 알려주세요 :-(


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.