systemdサービスの出力をファイルにリダイレクトする方法


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

私のアプローチを修正してください。

回答:


233

私は問題を解決するよりエレガントな方法があると思います:stdout / stderrを識別子と共にsyslogに送信し、プログラム名で出力を分割するようにsyslogマネージャーに指示します。

systemdサービスユニットファイルで次のプロパティを使用します。

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

1
これはDebianストレッチでうまく機能しますが、~非推奨であり、stop代わりに使用する必要があることを訴えます。また、2番目の行は& stop、2つがお互いに続いている場合に短縮できることにも注意してください。
jlh 2017年

47
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そして、次のようなプロパティに関するドキュメントprogramnamersyslog.com/doc/master/configuration/properties .html
mbil 2018

1
rsyslog独自のユーザーがいsyslogて、ログの場所への書き込みアクセス権が必要であることがわかるまで、この構成の使用に問題がありました。それにchown応じて使用してください。これが誰かを助けることを願っています。
Imaskar 2018

73

あなたが新しいと新しいディストリビューションがある場合systemdsystemdバージョン236以降を)、あなたはの値に設定することができStandardOutputたりStandardErrorするしfile:YOUR_ABSPATH_FILENAME


長い話:

新しいバージョンではsystemd比較的新しいオプションがある(githubの要求は、2016 ishからであると強化がマージされる/ 2017っぽい閉じてあなたがの値を設定することができます)StandardOutputStandardErrorへをfile:YOUR_ABSPATH_FILENAMEfile:pathオプションはで文書化され、最新systemd.execのmanページ

この新機能は比較的新しいため、centos-7(またはそれ以前のcentos)などの古いディストリビューションでは使用できません。


10
2018-03-20のubuntu 1604では動作しません。Ubuntuの1604年にsystemd版のみ229です
ブロンズ男

ありがとう、あなたはとてもはっきり言った。私はちょうどubuntu 1604のsystemdがconfigだけで出力をファイルにリダイレクトできないとは信じられません。この問題を解決するにはshの方法を使用する必要があります。
ブロンズ男

@bronzeman機能リクエストは2017年まで閉鎖されませんでしたが、Ubuntu 16.04は2016年にリリースされました。Ubuntuの特定のメジャーリリース(16.04、16.10、17.04など)では、UbuntuはコアシステムパッケージでABI互換性を維持しています。そのため、Ubuntuバージョンが最初にリリースされたときと同じABIを維持しない限り、systemd(またはLinuxカーネル、glibc、またはその他)をアップグレードしません。
villapx 2018年

1
FWIW:私はしましたが少し探索したが、この機能は、1つのの同類を使用することで、ログファイルを再度開くためにこのような機能としてログローテーションのための規定を、持っていないようcopytruncateではlogrotate
アンタック

48

あなたはおそらくこのエラーを受け取ります:

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

systemd.exec(5)manページから:

StandardOutput=

実行されたプロセスのファイル記述子1(STDOUT)の接続先を制御します。一つを取りinheritnullttyjournalsyslogkmsgjournal+consolesyslog+consolekmsg+consoleまたはsocket

systemd.exec(5)manページには、ログに関連する他のオプションについて説明します。systemd.service(5)およびsystemd.unit(5)manページも参照してください。

または、次のようなものを試すことができます(すべて1行で)。

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

7
オプションの中では、systemdジャーナルにログインすることをお勧めします。を使用して、ジャーナルのプロセスのログのみを表示します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").
オリオン

5
すばらしい答えです。問題は解決しました。拡張したいのは、サービスを再起動すると古いログが上書きされる場合、この部分を次のように置き換える必要があるため2>&1 > /var/log.logです2>&1 >> /var/log.log。ありがとう
PumpkinSeed 2017

10
率直に言って、ExecStartでコマンド文字列を使用してシェルを呼び出すと、本当に間違った方法のように聞こえます。
David Tonhofer 2017

1
「/ bin / sh」は優れた回避策ですが、「exec」を使用する必要があります。そうしないと、SIGTERMが子プロセスに渡されないため、サービスが正しく再起動しません。veithen.io/2014/11/16/sigterm-propagation.htmlを
リッチ

33

systemd ファイル自体に追加stdoutしてstderrファイルすることをお勧めしserviceます。

参照: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

注:ディレクトリがすでに作成されていることを確認してください。ディレクトリの作成はサポートしていないと思います。


5
詳細が少ない、この回答の複製
Gert van den Berg

9
理解しやすくなったと思います。
Rajat jain

1
私にとって、file:ルートはサービスの最初のロードで機能しますが、その後の再起動ではファイルに書き込みません。私append:はドキュメントから試しましたが、それはまったく機能しませんでした。
rb-

3
file:毎回ファイルの先頭に書き込み、切り捨てられないことをドキュメントが明確に示していることに注意append:してman systemd.execください。
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に配置されていて、systemdユニットのログインがあると仮定します/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

私たちはCentos7、systemdを備えたスプリングブートアプリケーションを使用しています。以下のようにJavaを実行していた。また、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'

ここに画像の説明を入力してください


-1は、jvmパラメータを誤った順序で定義した場合。-Xmx512Mは-jarの前に定義する必要があります。また、あなたが体験することは期待されています。Systemdがシェルを使用してサービスを呼び出さない
Sami Korhonen

1
@SamiKorhonen、これが機能していることをテストした後、コメントを追加しました。-Xmx512Mの注文はあなたに似ています。ブラインドコメントを追加する前にテストしてください。
Santhosh Hirekerur

0

短い答え:

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

サービスが実行されるたびにファイルを消去したくない場合は、代わりに追加を使用します。

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

2
詳細が少ない、この回答の複製
rustyx
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.