如何将 systemd 服务的输出重定向到文件

2024-10-12 10:28:00
admin
原创
316
摘要:问题描述:我正在尝试将systemd服务的输出重定向到文件,但似乎不起作用:[Unit] Description=customprocess After=network.target [Service] Type=forking ExecStart=/usr/local/bin/binary1 agent ...

问题描述:

我正在尝试将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

注意:请确保您已经创建了目录。我猜它不支持创建目录。此功能是在systemd240 中引入的,但已移植到早期版本,例如 RHEL8。

解决方案 3:

如果您拥有具有较新版本systemdsystemd236 或更新版本StandardOutput)的较新发行版,则可以将或的值设置StandardErrorfile:YOUR_ABSPATH_FILENAME


长话短说:

在较新版本中,systemd有一个相对较新的选项(github 请求来自 2016 年左右,增强功能已于 2017 年合并/关闭StandardOutput),您可以在其中将或的值设置StandardErrorfile: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 ) 连接到的位置。可采用inheritnullttyjournalsyslogkmsg、或之一。journal+console`syslog+consolekmsg+consolesocket`

手册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
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1325  
  IPD(Integrated Product Development)流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。它涵盖了从产品概念产生到产品退市的整个生命周期,通过整合跨部门团队、优化流程等方式,显著提升产品开发的效率和质量,进而为项目的成功奠定坚实基础。深入探究IPD流程的五个阶段与项目成功之间...
IPD流程分为几个阶段   4  
  华为作为全球知名的科技企业,其成功背后的管理体系备受关注。IPD(集成产品开发)流程作为华为核心的产品开发管理模式,其中的创新管理与实践更是蕴含着丰富的经验和深刻的智慧,对众多企业具有重要的借鉴意义。IPD流程的核心架构IPD流程旨在打破部门墙,实现跨部门的高效协作,将产品开发视为一个整体的流程。它涵盖了从市场需求分析...
华为IPD是什么   3  
  IPD(Integrated Product Development)研发管理体系作为一种先进的产品开发模式,在众多企业的发展历程中发挥了至关重要的作用。它不仅仅是一套流程,更是一种理念,一种能够全方位提升企业竞争力,推动企业持续发展的有效工具。深入探究IPD研发管理体系如何助力企业持续发展,对于众多渴望在市场中立足并...
IPD管理流程   3  
  IPD(Integrated Product Development)流程管理旨在通过整合产品开发流程、团队和资源,实现产品的快速、高质量交付。在这一过程中,有效降低成本是企业提升竞争力的关键。通过优化IPD流程管理中的各个环节,可以在不牺牲产品质量和性能的前提下,实现成本的显著降低,为企业创造更大的价值。优化产品规划...
IPD流程分为几个阶段   4  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用