如何将 systemd 服务的输出重定向到文件
- 2024-10-12 10:28:00
- admin 原创
- 77
问题描述:
我正在尝试将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
请纠正我的方法。
解决方案 1:
我认为有一种更优雅的方法来解决这个问题:使用标识符将 stdout/stderr 发送到 syslog,并指示您的 syslog 管理器按程序名称拆分其输出。
在您的 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>
) 获得,但它们也将在您选择的文件中可用。
来源:archive.org
解决方案 2:
我建议在 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
注意:请确保您已经创建了目录。我猜它不支持创建目录。此功能是在systemd
240 中引入的,但已移植到早期版本,例如 RHEL8。
解决方案 3:
如果您拥有具有较新版本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)。
解决方案 4:
您可能会收到此错误:
Failed to parse output specifier, ignoring: /var/log1.log
从systemd.exec(5)
手册页中:
StandardOutput=
控制执行进程的文件描述符 1 ( STDOUT ) 连接到的位置。可采用
inherit
、null
、tty
、journal
、syslog
、kmsg
、或之一。journal+console
`syslog+consolekmsg+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'
解决方案 5:
简短回答:
StandardOutput=file:/var/log1.log
StandardError=file:/var/log2.log
如果你不想每次运行服务时都清除文件,请改用 append:
StandardOutput=append:/var/log1.log
StandardError=append:/var/log2.log
解决方案 6:
如果由于某种原因无法使用 rsyslog,可以这样做:ExecStart=/bin/bash -ce "exec /usr/local/bin/binary1 agent -config-dir /etc/sample.d/server >> /var/log/agent.log 2>&1"
解决方案 7:
我们正在使用 Centos7,带有 systemd 的 spring boot 应用程序。我正在运行如下所示的 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'
解决方案 8:
假设日志已经放到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
解决方案 9:
让您的服务文件调用 shell 脚本,而不是直接运行应用程序。这样您就可以获得额外的控制权。例如,您可以制作类似于 /var/log/ 中的输出文件
创建一个 shell 脚本,例如 /opt/myapp/myapp.sh
#!/bin/sh
/usr/sbin/logrotate --force /opt/myapp/myapp.conf --state /opt/myapp/state.tmp
logger "[myapp] Run" # send a marker to syslog
myapp > /opt/myapp/myapp.log 2>&1 &
并且您的服务文件 myapp.service 包含:
...
[Service]
Type=forking
ExecStart=/bin/sh -c /opt/myapp/myapp.sh
...
日志配置文件 /opt/myapp/myapp.conf 的示例
/opt/myapp/myapp.log {
daily
rotate 20
missingok
compress
}
然后,您将获得 myapp.log 和压缩的 myapp.log.1.gz ...,每次服务启动时以及之前的压缩文件。
解决方案 10:
在我的例子中
2>&1
(stdout 和 stderr 文件描述符符号)必须正确放置,然后日志重定向才能按我预期的方式工作
[Unit]
Description=events-server
[Service]
User=manjunath
Type=simple
ExecStart=/bin/bash -c '/opt/events-server/bin/start.sh my-conf 2>&1 >> /var/log/events-server/events.log'
[Install]
WantedBy=multi-user.target
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件