내 서비스에서 시스템 서비스 로그를 더 빠르게 가져오기

내 서비스에서 시스템 서비스 로그를 더 빠르게 가져오기

내 시스템 서비스는 다음과 같이 정의되어 있으며 잘 작동합니다.

[Unit]
Description=my service
After=network.target

[Service]
User=myuser
Group=mygroup
WorkingDirectory=/home/myuser/myapp
Environment="PATH=/home/myuser/myapp/.venv/bin"
ExecStart=/home/myuser/myapp/.venv/bin/python3 /home/myuser/myapp/run.py
Restart=on-failure

[Install]
WantedBy=multi-user.target

이것은 Flask 프레임워크를 기반으로 하는 Python 웹 애플리케이션입니다. 일반적으로 애플리케이션의 표준 출력에서는 들어오는 요청을 "라이브"로 볼 수 있습니다. 즉, 애플리케이션을 실행할 때를 의미합니다 python run.py.

이제 서비스를 시작한 후 애플리케이션의 로그를 추적하고 싶습니다. 다음을 수행합니다.

sudo journalctl -f -u my_app.service

그리고 들어오는 로그는 매우 느립니다. 로그에 표시되는 데 몇 분 이상이 걸릴 때도 있습니다. 그런데 모두 정확한 타임 스탬프를 가지고 있어서 사라진 것이 아니라 오랫동안 사라진 것뿐입니다.

내가 시도한 것:

  • 시스템 서비스 출력을 파일로 리디렉션합니다.

    StandardOutput=file:/var/log/my_app/output.log

    StandardError=file:/var/log/my_app/error.log

    운이 좋지 않습니다. 저장은 잘되지만 그만큼 느립니다.

  • Journalctl 로그 덤프를 SyncIntervalSec기본값에서 5m오프라인 으로 더 빠른 설정으로 변경하려고 시도했지만 5s도움이 되지 않았습니다.

내 애플리케이션의 로그를 더 빠르게 로그로 가져올 수 있는 방법이 있습니까? 다른 서비스(시스템 인증 서비스 등) 이용에는 문제가 없습니다. - 바로 기록을 볼 수 있습니다. 내 journald.conf파일에는 위의 매개변수 외에도 기본 매개변수가 있고 시스템 버전은 237이며 Ubuntu 18.04를 실행하고 있습니다.

답변1

문제는 실제로 systemd 또는 Journald가 이러한 로그를 수집하는 방법이 아니라 Flask 애플리케이션의 버퍼링에 있습니다.

앞서 언급한 것처럼 python3 run.py명령줄에서 직접 실행하면 제대로 작동하고 로그가 올바르게 표시되며 로그에서 타임스탬프가 올바르게 표시되기 때문에 이는 직관에 어긋날 수 있습니다.

전자는 Unix/Linux가 일반적으로 터미널에 연결할 때(사용자 상호 작용을 기대하기 때문에) stdout을 버퍼링하지 않도록 설정하지만 파일(의 경우 StandardOutput=file:...) 또는 파이프(로그인할 경우) 에 연결할 때는 버퍼링되지 않도록 설정하기 때문에 발생합니다. 로그이며 기본값입니다.)

후자는 Python/Flask 로거가 타임스탬프를 추가하기 때문에 해당 출력을 버퍼링하더라도 최종적으로 로그로 보낼 때 모든 타임스탬프가 거기에 있습니다.

일부 응용 프로그램은 이것이 일반적으로 문제라는 것을 알고 로깅에 사용할 때 stdout에 버퍼링을 적절하게 설정하지만 사용 중인 특정 Python/Flask 설정에는 해당되지 않는 것 같습니다.

Python에서는 다음을 사용하여 stdout을 버퍼링되지 않은 모드로 전역적으로 변경하는 것이 매우 쉽습니다.

  1. 통해-u배너당신의 명령 에 따라 python3.
  2. 환경PYTHONUNBUFFERED=1귀하의 환경에서 ( Environment=PYTHONUNBUFFERED=1systemd 서비스 단위의 추가 라인을 사용하여 이 작업을 수행할 수 있습니다.)

귀하의 특정 사례에 이것이 효과가 있음을 확인하셨습니다. 훌륭합니다!

유사한 문제가 발생하는 비 Python 애플리케이션의 경우 동일한 문제를 해결할 수 있는 명령줄 도구(예: unbuffer및 ) 가 있습니다.stdbuf

솔루션은 애플리케이션 유형에 따라 달라지는 경우가 많습니다. 이는 다소 아쉽지만 Stack Exchange에서 검색하거나 다른 답변을 찾는 경우가 많습니다(한 번알다버퍼링이 문제임)은 일반적으로 유용한 조언을 제공합니다.

관련 정보