如何将 systemd 服务日志附加到日志

如何将 systemd 服务日志附加到日志

我正在尝试使用 systemd 控制工作站上连续运行的许可证服务器。服务本身是由 shell 脚本启动的,本质上是

Usage: ./rlm_control.sh {start|stop|restart|status}

由此我创建了一个 systemd 服务文件:

[Unit]
Description=RLM License Server
After=network.target

[Service]
Type=forking
ExecStart=/path/to/rlm_control.sh start
ExecStop=/path/to/rlm_control.sh stop
ExecReload=/path/to/rlm_control.sh restart
User=chris
Restart=on-failure

[Install]
WantedBy=multi-user.target

问题是这个控制脚本实际上派生出另一个进程并拥有自己的日志rlm。的日志rlm_control.sh可以被journald找到,但是 的日志rlm却找不到。

是否有可能以某种方式告诉journald将输出基本上附加tail -f /path/to/rlm.log到该服务的日志中?

编辑:我注意到在 [0] 之前有人问过这个问题,但该解决方案似乎建议使用命令附加日志,而不是调整服务文件以从另一个日志文件中读取。

[0]将日志从文件转发到日志

答案1

这里的问题是评论中已经说过的:您没有创建一个 systemd 单元,而是创建一个“systemd 进程生成器”。由于您正在谈论充分提供服务而不是将文件连接到日志,因此在将软件日志发送到 Journal 之前,您必须解决一些问题:

  • 真正的 systemd 单元应该有类似的东西ExecStart=/path/to/license_software_bin -d parameter1 -f parameter2 -c -whatever,并且不会调用一个脚本,该脚本会Type=forking调用fork()并杀死启动守护进程的父进程
  • 配置PIDFile=/run/path/to/pidfile.pid使进程识别更好。引用systemd.service联机帮助页:

PIDFile=

采用指向服务 PID 文件的路径。建议对Type=设置为 的服务使用此选项forking。指定的路径通常指向 下面的某个文件/run/。如果指定了相对路径,则应以 为前缀/run/PID服务启动后,服务管理器将从此文件读取服务主进程的 。服务管理器不会写入此处配置的文件,但在服务关闭后如果文件仍存在,它会将其删除。PID 文件不需要由特权用户拥有,但如果它由非特权用户拥有,则必须实施额外的安全限制:该文件不能是指向其他用户拥有的文件的符号链接(无论是直接还是间接),并且 PID 文件必须引用已经属于该服务的进程。

和:

如果设置为forking,则预计配置的进程 ExecStart=fork()作为其启动的一部分进行调用。当启动完成并且所有通信通道都建立后,父进程预计将退出。子进程继续作为主服务进程运行,当父进程退出时,服务管理器会认为该单元已启动。这是传统 UNIX 服务的行为。如果使用此设置,建议也使用该PIDFile=选项,以便systemd能够可靠地识别服务的主进程。一旦父进程退出,systemd 将继续启动后续单元。

看看httpd.serviceCentOS 7 的 systemd 单元的设计简单性:ExecStart=直接调用二进制文件,因此不需要PIDFile=,通过终止进程并给它一些时间来停止,SIGCONTTimeoutStopSec重新加载使用httpd -k gracefulApache 本身特有的东西。

[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=man:httpd(8)
Documentation=man:apachectl(8)

[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/httpd
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
ExecStop=/bin/kill -WINCH ${MAINPID}
# We want systemd to give httpd some time to finish gracefully, but still want
# it to kill httpd after TimeoutStopSec if something went wrong during the
# graceful stop. Normally, Systemd sends SIGTERM signal right after the
# ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
# httpd time to finish.
KillSignal=SIGCONT
PrivateTmp=true

[Install]
WantedBy=multi-user.target

相关内容