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

2024-10-12 10:28:00
admin
原创
78
摘要:问题描述:我正在尝试将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
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用