如何将 systemd 服务的输出重定向到文件
How to redirect output of systemd service to a file
我正在尝试将 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
请指正我的做法
您可能会遇到此错误:
Failed to parse output specifier, ignoring: /var/log1.log
来自 systemd.exec(5)
手册页:
StandardOutput=
Controls where file descriptor 1 (STDOUT) of the executed processes is connected to. Takes one of inherit
, null
, tty
, journal
, syslog
, kmsg
, journal+console
, syslog+console
, kmsg+console
or 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'
我认为有一个更优雅的方法来解决这个问题:将 stdout/stderr 发送到带有标识符的系统日志,并指示您的系统日志管理器按程序名称拆分其输出。
在您的 systemd 服务单元文件中使用以下属性:
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=<your program identifier> # without any quote
然后,假设您的发行版使用 rsyslog 来管理系统日志,请在 /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>
) 使用,但它们也将在您选择的文件中可用。
如果由于某种原因不能使用 rsyslog,可以这样做:
ExecStart=/bin/bash -ce "exec /usr/local/bin/binary1 agent -config-dir /etc/sample.d/server >> /var/log/agent.log 2>&1"
如果您的发行版更新 systemd
(),您可以将 StandardOutput
或 StandardError
的值设置为 file:YOUR_ABSPATH_FILENAME
.
长话短说:
在 systemd
的较新版本中有一个相对较新的选项 (the github request is from 2016 ish and the enhancement is merged/closed 2017 ish) where you can set the values of StandardOutput
or StandardError
to file:YOUR_ABSPATH_FILENAME
. The file:path
option is documented in the most recent systemd.exec
man page。
这项新功能相对较新,因此不适用于 centos-7(或之前的任何 centos)等较旧的发行版。
假设日志已经被放入 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
我建议在 systemd service
文件本身中添加 stdout
和 stderr
文件。
参考: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
注意:确保您已经创建了目录。估计是不支持创建目录吧
我们正在使用 Centos7,spring 使用 systemd 启动应用程序。我是 运行 java 如下。并将 StandardOutput 设置为文件对我不起作用。
ExecStart=/bin/java -jar xxx.jar -Xmx512-Xms32M
以下变通解决方案无需设置 StandardOutput 即可工作。 运行 java 通过 sh 如下。
ExecStart=/bin/sh -c 'exec /bin/java -jar xxx.jar -Xmx512M -Xms32M >> /data/logs/xxx.log 2>&1'
简答:
StandardOutput=file:/var/log1.log
StandardError=file:/var/log2.log
如果您不希望每次服务 运行 时都清除文件,请改用追加:
StandardOutput=append:/var/log1.log
StandardError=append:/var/log2.log
我正在尝试将 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
请指正我的做法
您可能会遇到此错误:
Failed to parse output specifier, ignoring: /var/log1.log
来自 systemd.exec(5)
手册页:
StandardOutput=
Controls where file descriptor 1 (STDOUT) of the executed processes is connected to. Takes one of
inherit
,null
,tty
,journal
,syslog
,kmsg
,journal+console
,syslog+console
,kmsg+console
orsocket
.
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'
我认为有一个更优雅的方法来解决这个问题:将 stdout/stderr 发送到带有标识符的系统日志,并指示您的系统日志管理器按程序名称拆分其输出。
在您的 systemd 服务单元文件中使用以下属性:
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=<your program identifier> # without any quote
然后,假设您的发行版使用 rsyslog 来管理系统日志,请在 /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>
) 使用,但它们也将在您选择的文件中可用。
如果由于某种原因不能使用 rsyslog,可以这样做:
ExecStart=/bin/bash -ce "exec /usr/local/bin/binary1 agent -config-dir /etc/sample.d/server >> /var/log/agent.log 2>&1"
如果您的发行版更新 systemd
(StandardOutput
或 StandardError
的值设置为 file:YOUR_ABSPATH_FILENAME
.
长话短说:
在 systemd
的较新版本中有一个相对较新的选项 (the github request is from 2016 ish and the enhancement is merged/closed 2017 ish) where you can set the values of StandardOutput
or StandardError
to file:YOUR_ABSPATH_FILENAME
. The file:path
option is documented in the most recent systemd.exec
man page。
这项新功能相对较新,因此不适用于 centos-7(或之前的任何 centos)等较旧的发行版。
假设日志已经被放入 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
我建议在 systemd service
文件本身中添加 stdout
和 stderr
文件。
参考: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
注意:确保您已经创建了目录。估计是不支持创建目录吧
我们正在使用 Centos7,spring 使用 systemd 启动应用程序。我是 运行 java 如下。并将 StandardOutput 设置为文件对我不起作用。
ExecStart=/bin/java -jar xxx.jar -Xmx512-Xms32M
以下变通解决方案无需设置 StandardOutput 即可工作。 运行 java 通过 sh 如下。
ExecStart=/bin/sh -c 'exec /bin/java -jar xxx.jar -Xmx512M -Xms32M >> /data/logs/xxx.log 2>&1'
简答:
StandardOutput=file:/var/log1.log
StandardError=file:/var/log2.log
如果您不希望每次服务 运行 时都清除文件,请改用追加:
StandardOutput=append:/var/log1.log
StandardError=append:/var/log2.log