我正在尝试为 RHEL 系统上的 SystemD 编写自定义服务定义。
目前,输出进入 Journal,但我需要将其放在一个文件中,以便使用 Logstash 解析和转发它。 (注意:由于我无法控制的原因,Journalbeat 不是一个选择)。
为了使服务日志记录到文件中,我尝试了:
- 创建 /var/log/myservice 目录
StandardOutput=append:/var/log/myservice
在 SystemD 服务定义中设置指令
当我尝试启动该服务时,它失败并显示status=209/STDOUT
.经过一些调试,我发现是 SELinux 阻止了这种情况:
Additional Information:
Source Context system_u:system_r:init_t:s0
Target Context system_u:object_r:var_log_t:s0
Target Objects mylogfile.log [ file ]
Source (myservice)
Source Path /usr/lib/systemd/systemd
Port <Unknown>
Host myhost.mydomain.net
Source RPM Packages systemd-239-45.el8.x86_64
Target RPM Packages
SELinux Policy RPM selinux-policy-targeted-3.14.3-67.el8.noarch
Local Policy RPM selinux-policy-targeted-3.14.3-67.el8.noarch
Selinux Enabled True
Policy Type targeted
Enforcing Mode Enforcing
<... truncated ...>
Raw Audit Messages
type=AVC msg=audit(1628237958.525:23268): avc: denied { create } for pid=323316 comm="(myservice)" name="mylogfile" scontext=system_u:system_r:init_t:s0 tcontext=system_u:object_r:var_log_t:s0 tclass=file permissive=0
type=SYSCALL msg=audit(1628237958.525:23268): arch=x86_64 syscall=openat success=no exit=EACCES a0=ffffff9c a1=55e0d96f2230 a2=541 a3=1a4 items=0 ppid=1 pid=323316 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm=(myservice) exe=/usr/lib/systemd/systemd subj=system_u:system_r:init_t:s0 key=(null)
据我了解,它告诉我 SystemD(在上下文中运行system_u:system_r:init_t:s0
)无法在我的目录 ( ) 中创建文件system_u:object_r:var_log_t:s0
。
当前目录为空:
# ls -alZ /var/log/myservice/
total 12
drwxr-xr-x. 2 root root system_u:object_r:var_log_t:s0 6 Aug 6 09:11 .
drwxr-xr-x. 19 root root system_u:object_r:var_log_t:s0 8192 Aug 6 03:13 ..
问题:允许 SystemD 将日志写入 /var/log 的正确方法(策略)是什么?
我尝试了几种方法,semanage fcontext
但到目前为止没有成功。
答案1
当您可以更改自定义服务时,最简单的事情就是在服务的可执行文件中实现日志记录,因为它可能已经不受限制地运行。
(除非您为您的服务编写了一些 SELinux 策略)
这也将增加灵活性,例如支持日志文件轮换。我的意思是,我不知道StandardOutput=append:/
在文件变大的情况下如何支持切换到新文件。
或者,您可以让专门的日志记录工具(例如 Apache)将rotatelogs
您服务的标准输出写入/var/log/myservice
。
例子:
[Service]
Type=simple
ExecStart=/bin/bash -c 'exec /opt/bin/yourservice > >(exec /sbin/rotatelogs a_few_options /var/log/myservice/logfile rottime_or_size )'
这样您就不必更改服务可执行文件。但是,如果您的服务已经不受限制地运行,那么这样的日志记录助手也应该如此。
也可以看看另一个答案的一些替代品rotatelogs
。