なうびるどいんぐ

脳みそ常時-3dB

【systemd】StandardOutput=fileはログをファイルに出力できるけど追記されない

      2019/08/20    HimaJyun

systemdで作ったserviceのログ(標準出力)をファイルに出力したい!みたいな奴の、少し新しめなやり方。

(タイトルちょっと変わった、以前のタイトル: systemd 236からはStandardOutput=fileでログをファイルに出力できる)

スポンサーリンク

先に結論

僕は長話が好きなので、急ぎの人のために先に結論を。

systemdのバージョン236以上からはStandardInput、StandardOutput、StandardErrorにfileを指定可能。

StanderdOutput=file:/absolute/pathみたいに指定する。

しかしこれはファイルが追記されない。追記させるにはsystemd 240から追加されたappendが必要。

systemdのログをファイルに出力したい

みたいな要求、ありますよね?僕はあります。

もちろんsystemctl statusとかjournalctl使えばログ自体は見られるんですけど、ログ見るためにSSHログインしてコマンド打つのだるくない?

crontab時代に自分が何をやってるかも考えずに> /dev/nullとかしてたような悪い人にとってこの仕組みは素晴らしいのかもしれないが、僕はログファイルをSFTPでダウンロードしてエディタとかで読みたい派なのでファイルに出力してほしい。

やり方

こんな感じで、StandardOutputにfileというものが指定できるよ!

[Unit]
Description=test

[Service]
Type=oneshot
ExecStart=/bin/echo "test"
StandardOutput=file:/tmp/test.log
StandardError=file:/tmp/test.log

とっても簡単!せつめいふよう!!

ちなみに、StandardOutputでfileを指定すると逆にjournalには出力されなくなる。journal+consoleみたいな組み合わせはできるが、journal+fileは無理だった。

それと、当然ながらログローテーションなどはされないので、そこは自分で設定する必要がある。

でもこの方法追記されないぞ~w

最近気づいた(<-普段ログを見てない証拠)

StandardOutputにfileで指定したとき、ファイルは追記されない。(fopenで言うならモードがaになってない)

要するにサービスが再起動されるたびにログの内容が消える。アカンやんけ……

とまぁ当然そういうissueとか上がるわけで、プルリクが出ており、マージされている

使い方は次の通り。

[Unit]
Description=test

[Service]
Type=oneshot
ExecStart=/bin/echo "test"
StandardOutput=append:/tmp/test.log
StandardError=append:/tmp/test.log

ただし、これが使えるのはSystemd 240から。現段階(2019/08/03)ではほとんどのディストリで使えないはず。もう少し未来になるまで待つしかないな!

古い方法

これは古い方法。大人の事情で新しいsystemdが使えない人向け。

[Unit]
Description=test

[Service]
Type=oneshot
ExecStart=/bin/sh -c '/bin/echo "test" >> /tmp/test.log 2>&1'

コマンドを/bin/shとかで起動して、そのままリダイレクトでファイルに出力している。邪悪な気がする。やりたくない。

使えるか確かめる

systemd --versionをしてみれば分かる、fileはバージョンが236より新しければ、appendは240より新しければ使える。

参考までに、fileはUbuntu 18.04で対応しており、16.04は非対応。RHELは知らん、多分無理。

appendはUbuntu 18.04でもダメだった、19くらいなら行けるかもしれない。Raspbian Busterは行ける。ベースが同じだからDebian Busterも行ける?

今(2019/02/01)はあまり使える場面がないが、将来的にはバージョン気にせず使えるようになると思う。

参考

この記事は先人の情報を焼き直した邪悪な記事です。

 - サーバー