我正在尝试使用 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.service
CentOS 7 的 systemd 单元的设计简单性:ExecStart=
直接调用二进制文件,因此不需要PIDFile=
,通过终止进程并给它一些时间来停止,SIGCONT
并TimeoutStopSec
重新加载使用httpd -k graceful
Apache 本身特有的东西。
[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