시스템 서비스 출력을 파일로 리디렉션하는 방법


171

systemd서비스 출력을 파일 로 리디렉션하려고 하지만 작동하지 않는 것 같습니다.

[Unit]
Description=customprocess
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/bin/binary1 agent -config-dir /etc/sample.d/server
StandardOutput=/var/log1.log
StandardError=/var/log2.log
Restart=always

[Install]
WantedBy=multi-user.target

내 접근 방식을 수정하십시오.

답변:


234

문제를 해결하는 더 우아한 방법이 있다고 생각합니다. stdout / stderr을 식별자를 사용하여 syslog로 보내고 syslog 관리자에게 출력을 프로그램 이름으로 나누도록 지시하십시오.

시스템 서비스 단위 파일에서 다음 특성을 사용하십시오.

StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=<your program identifier> # without any quote

그런 다음 배포에서 rsyslog를 사용하여 syslog를 관리한다고 가정 /etc/rsyslog.d/<new_file>.conf하면 다음 내용으로 파일을 만듭니다 .

if $programname == '<your program identifier>' then /path/to/log/file.log
& stop

이제 syslog에서 로그 파일을 쓸 수있게 만드십시오 :

# ls -alth /var/log/syslog 
-rw-r----- 1 syslog adm 439K Mar  5 19:35 /var/log/syslog
# chown syslog:adm /path/to/log/file.log

rsyslog ( sudo systemctl restart rsyslog)를 다시 시작 하고 즐기십시오! 프로그램 stdout / stderr는 여전히 journalctl ( sudo journalctl -u <your program identifier>)을 통해 사용할 수 있지만 선택한 파일에서도 사용할 수 있습니다.

archive.org를 통한 출처


8
Ubuntu 16.04에서 작동하지 않습니다. journalctl -u여전히 작동하지만 지정된 파일로 아무것도 전송되지 않습니다.
Duncan Calvert 18.53.

1
이것은 데비안 스트레치에서 훌륭하게 작동하지만 ~더 이상 사용되지 않으며 stop대신 사용해야한다고 불평합니다 . 또한 두 줄이 & stop서로 이어지면 두 번째 줄을 줄일 수 있습니다 .
jlh

48
systemd 236 이상에서는 StandardOutput = file : / some / path github.com/systemd/systemd/pull/7198
leezu

5
나는 변경하여이 작업을 가지고 /etc/rsyslog.d/<newfile>.conf:에 내용을 :programname, isequal, "<your program identifier>" /var/log/somelog.log 위해 rsyslog 필터에 다음의 서류 : rsyslog.com/doc/v8-stable/configuration/filters.html 그리고 여기의 문서를 같은 속성 programname: rsyslog.com/doc/master/configuration/properties를 .html
mbil

1
rsyslog자체 사용자 syslog가 있고 로그 위치에 대한 쓰기 액세스 권한이 있어야 할 때까지이 구성을 사용하는 데 문제가있었습니다 . 따라서 chown적절하게 사용하십시오 . 이것이 누군가를 돕기를 바랍니다.
Imaskar

73

당신이 새와 새로운 배포판이있는 경우 systemd( systemd버전 236 이상을 ), 당신은의 값을 설정할 수 있습니다 StandardOutput또는 StandardError로를 file:YOUR_ABSPATH_FILENAME.


긴 이야기:

새로운 버전에서는 systemd비교적 새로운 옵션이 ( GitHub의 요청 2016에서 틱하고 향상 / 합병 2017 분에 폐쇄한다 ) 당신이의 값 설정할 수 StandardOutput또는 StandardError로를 file:YOUR_ABSPATH_FILENAME. 이 file:path옵션은 최신 systemd.exec매뉴얼 페이지에 설명되어 있습니다.

이 새로운 기능은 비교적 새로운 기능이므로 centos-7 (또는 그 이전의 centos)과 같은 오래된 배포판에서는 사용할 수 없습니다.


10
2018-03-20의 우분투 1604에서 작동하지 않습니다. 우분투 1604의 시스템 버전은 229입니다.
청동 남자

고마워, 당신은 매우 분명했다. 우분투 1604의 systemd는 config만으로 출력을 파일로 리디렉션 할 수 없다고 믿을 수 없습니다.이 문제를 해결하려면 sh 방법을 사용해야합니다.
청동 남자

@bronzeman 기능 요청은 2017 년까지 마감되지 않았으며, 2016 년 Ubuntu 16.04가 출시되었습니다. Ubuntu의 주요 릴리스 (예 : 16.04, 16.10, 17.04 등)에서 Ubuntu는 핵심 시스템 패키지에서 ABI 호환성을 유지합니다. 따라서 그들은 Ubuntu 버전이 처음 릴리스되었을 때와 동일한 ABI를 유지하지 않으면 systemd (또는 Linux 커널 또는 glibc 등)를 업그레이드하지 않습니다.
villapx

1
FWIW : 나는 조금을 수색했지만이 기능의 좋아하는을 사용할 필요 하나, 이러한 로그 파일을 다시하는 기능과 로그 회전에 대한 규정을 가지고 나타나지 않습니다 copytruncate에서 logrotate.
antak

49

이 오류가 발생할 수 있습니다.

Failed to parse output specifier, ignoring: /var/log1.log

로부터 systemd.exec(5)매뉴얼 페이지

StandardOutput=

실행 된 프로세스의 파일 디스크립터 1 (STDOUT)이 연결되는 위치를 제어합니다. 중 하나를 간다 inherit, null, tty, journal, syslog, kmsg, journal+console, syslog+console, kmsg+console또는 socket.

systemd.exec(5)매뉴얼 페이지 로깅 관련된 다른 옵션에 대해 설명합니다. systemd.service(5)systemd.unit(5)매뉴얼 페이지 도 참조하십시오 .

또는 다음과 같은 것을 시도해 볼 수 있습니다 (모두 한 줄에).

ExecStart=/bin/sh -c '/usr/local/bin/binary1 agent -config-dir /etc/sample.d/server 2>&1 > /var/log.log' 

7
옵션 중에서 시스템 저널에 로그인하는 것이 좋습니다. 을 사용하여 저널에서 프로세스의 로그 만 볼 수 있습니다 journalctl -u your-unit-name.
Mark Stosberg 2016 년

6
파일을 지정하기 위해 다음과 같이 문서에 표시된대로 더 깨끗한 옵션이 있습니다.The fd option connects the output stream to a single file descriptor provided by a socket unit. A custom named file descriptor can be specified as part of this option, after a ":" (e.g. "fd:foobar").
orion

5
대답은, 내 문제가 해결되었습니다. 현재 서비스를 다시 시작하여 이전 로그를 덮어 쓰면이 부분을 다음 2>&1 > /var/log.log과 같이 바꿔야하기 때문에 확장하고 싶습니다 2>&1 >> /var/log.log. 감사합니다
PumpkinSeed

10
솔직히, ExecStart에서 명령 문자열로 쉘을 호출하면 실제로 잘못하는 것처럼 들립니다.
David Tonhofer

1
"/ bin / sh"는 훌륭한 해결 방법이지만 "exec"를 사용해야합니다. 그렇지 않으면 SIGTERM이 하위 프로세스로 전달되지 않으므로 서비스가 제대로 다시 시작되지 않습니다. 참조 veithen.io/2014/11/16/sigterm-propagation.html
리치

33

systemd 파일 자체에 파일을 추가 stdout하고 제안하는 것이 좋습니다 .stderrservice

참조 : https://www.freedesktop.org/software/systemd/man/systemd.exec.html#StandardOutput=

구성 했으므로 다음을 좋아하지 않아야합니다.

StandardOutput=/home/user/log1.log
StandardError=/home/user/log2.log

그것은해야한다:

StandardOutput=file:/home/user/log1.log
StandardError=file:/home/user/log2.log

서비스를 다시 시작하고 싶지 않을 때 작동합니다 .

새 파일이 만들어지고 기존 파일에 추가되지 않습니다.

대신 사용하십시오 :

StandardOutput=append:/home/user/log1.log
StandardError=append:/home/user/log2.log

참고 : 디렉토리를 이미 작성했는지 확인하십시오. 디렉토리 생성을 지원하지 않는 것 같습니다.



9
생각보다 이해하기 쉬워졌습니다.
Rajat jain

1
나를 위해 file:경로는 서비스의 첫 번째로드에서 작동하지만 후속 재시작시 더 이상 파일에 쓰지 않습니다. 나는 append:문서에서 시도했지만 전혀 작동하지 않았습니다.
rb-

3
워드 프로세서 명확하게하는 참고하는 file:파일의 시작에 쓰기를 할 때마다, 그리고 잘라야 ... 더하지 않는 append:새로 추가합니다 (에 즉 존재하지 않는 것으로 보인다 man systemd.exec우분투 18.04에 페이지).
cole

19

어떤 이유로 rsyslog를 사용할 수없는 경우 다음을 수행합니다. ExecStart=/bin/bash -ce "exec /usr/local/bin/binary1 agent -config-dir /etc/sample.d/server >> /var/log/agent.log 2>&1"


bash의 -e 옵션은 무엇을합니까?
램프

3

로그가 이미 stdout / stderr 에 있고 시스템 장치의 로그인 이 있다고 가정합니다 ./var/log/syslog

journalctl -u unitxxx.service

Jun 30 13:51:46 host unitxxx[1437]: time="2018-06-30T11:51:46Z" level=info msg="127.0.0.1
Jun 30 15:02:15 host unitxxx[1437]: time="2018-06-30T13:02:15Z" level=info msg="127.0.0.1
Jun 30 15:33:02 host unitxxx[1437]: time="2018-06-30T13:33:02Z" level=info msg="127.0.0.1
Jun 30 15:56:31 host unitxxx[1437]: time="2018-06-30T13:56:31Z" level=info msg="127.0.0.1

rsyslog 구성 (시스템 로깅 서비스)

# Create directory for log file
mkdir /var/log/unitxxx

# Then add config file /etc/rsyslog.d/unitxxx.conf

if $programname == 'unitxxx' then /var/log/unitxxx/unitxxx.log
& stop

rsyslog를 다시 시작하십시오.

systemctl restart rsyslog.service

1

우리는 systemd와 함께 스프링 부트 어플리케이션 인 Centos7을 사용하고 있습니다. 나는 아래와 같이 자바를 실행했다. StandardOutput을 파일로 설정하는 것이 작동하지 않았습니다.

ExecStart=/bin/java -jar xxx.jar  -Xmx512-Xms32M

아래의 해결 방법은 StandardOutput을 설정하지 않고 작동합니다. 다음과 같이 sh를 통해 java를 실행하십시오.


ExecStart=/bin/sh -c 'exec /bin/java -jar xxx.jar -Xmx512M -Xms32M >> /data/logs/xxx.log 2>&1'

여기에 이미지 설명을 입력하십시오


jvm 매개 변수를 잘못된 순서로 정의하는 경우 -1입니다. -jar 전에 -Xmx512M을 정의해야합니다. 또한 당신이 경험하는 것이 기대됩니다. Systemd는 쉘을 사용하여 서비스를 호출하지 않습니다
Sami Korhonen

1
@ SamiKorhonen, 이것이 작동하는지 테스트 한 후에 의견을 추가했습니다. 심지어 -Xmx512M의 순서는 당신에게 약간의 생각입니다. 맹검을 추가하기 전에 테스트하십시오.
Santhosh Hirekerur

0

짧은 답변:

StandardOutput=file:/var/log1.log
StandardError=file:/var/log2.log

서비스가 실행될 때마다 파일을 지우지 않으려면 대신 append를 사용하십시오.

StandardOutput=append:/var/log1.log
StandardError=append:/var/log2.log

2
의 중복 이 대답 적은 세부 사항,
rustyx
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.