简体   繁体   中英

How to redirect output of systemd service to a file

I am trying to redirect output of a systemd service to a file but it doesn't seem to work:

[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

Please correct my approach.

I think there's a more elegant way to solve the problem: send the stdout/stderr to syslog with an identifier and instruct your syslog manager to split its output by program name.

Use the following properties in your systemd service unit file:

 StandardOutput=syslog StandardError=syslog SyslogIdentifier=<your program identifier> # without any quote

Then, assuming your distribution is using rsyslog to manage syslogs, create a file in /etc/rsyslog.d/<new_file>.conf with the following content:

 if $programname == '<your program identifier>' then /path/to/log/file.log & stop

Now make the log file writable by 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

Restart rsyslog ( sudo systemctl restart rsyslog ) and enjoy Your program stdout/stderr will still be available through journalctl ( sudo journalctl -u <your program identifier> ) but they will also be available in your file of choice.

Source via archive.org

If you have a newer distro with a newer systemd ( systemd version 236 or newer ), you can set the values of StandardOutput or StandardError to file:YOUR_ABSPATH_FILENAME .


Long story:

In newer versions of systemd there is a relatively new option ( the github request is from 2016 ish and the enhancement is merged/closed 2017 ish ) where you can set the values of StandardOutput or StandardError to file:YOUR_ABSPATH_FILENAME . The file:path option is documented in the most recent systemd.exec man page .

This new feature is relatively new and so is not available for older distros like centos-7 (or any centos before that).

I would suggest adding stdout and stderr file in systemd service file itself.

Referring: https://www.freedesktop.org/software/systemd/man/systemd.exec.html#StandardOutput=

As you have configured it should not like:

 StandardOutput=/home/user/log1.log StandardError=/home/user/log2.log

It should be:

 StandardOutput=file:/home/user/log1.log StandardError=file:/home/user/log2.log

This works when you don't want to restart the service again and again .

This will create a new file and does not append to the existing file.

Use Instead:

 StandardOutput=append:/home/user/log1.log StandardError=append:/home/user/log2.log

NOTE: Make sure you create the directory already. I guess it does not support to create a directory.

You possibly get this error:

 Failed to parse output specifier, ignoring: /var/log1.log

From the systemd.exec(5) man page:

StandardOutput=

Controls where file descriptor 1 (STDOUT) of the executed processes is connected to. Takes one of inherit , null , tty , journal , syslog , kmsg , journal+console , syslog+console , kmsg+console or socket .

The systemd.exec(5) man page explains other options related to logging. See also the systemd.service(5) and systemd.unit(5) man pages.

Or maybe you can try things like this (all on one line):

 ExecStart=/bin/sh -c '/usr/local/bin/binary1 agent -config-dir /etc/sample.d/server 2>&1 > /var/log.log'

If for a some reason can't use rsyslog, this will do: ExecStart=/bin/bash -ce "exec /usr/local/bin/binary1 agent -config-dir /etc/sample.d/server >> /var/log/agent.log 2>&1"

Short answer:

 StandardOutput=file:/var/log1.log StandardError=file:/var/log2.log

If you don't want the files to be cleared every time the service is run, use append instead:

 StandardOutput=append:/var/log1.log StandardError=append:/var/log2.log

We are using Centos7, spring boot application with systemd. I was running java as below. and setting StandardOutput to file was not working for me.

 ExecStart=/bin/java -jar xxx.jar -Xmx512-Xms32M

Below workaround solution working without setting StandardOutput. running java through sh as below.

 ExecStart=/bin/sh -c 'exec /bin/java -jar xxx.jar -Xmx512M -Xms32M >> /data/logs/xxx.log 2>&1'

在此处输入图像描述

Assume logs are already put to stdout/stderr , and have systemd unit's log in /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

Config rsyslog (System Logging Service)

 # 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

Restart rsyslog

 systemctl restart rsyslog.service
  • In my case 2>&1 (stdout and stderr file descriptor symbol) had to be placed correctly,then log redirection worked as I expected
[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

Make your service file call a shell script instead of running the app directly. This way you have extra control. For example, you can make output files like those in /var/log/

Make a shell script like /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 &

And your service file myapp.service contains:

...
[Service]
Type=forking
ExecStart=/bin/sh -c /opt/myapp/myapp.sh
...

A sample of log config file /opt/myapp/myapp.conf

/opt/myapp/myapp.log {
    daily
    rotate 20
    missingok
    compress
}

Then you will get myapp.log, and zipped myapp.log.1.gz... for each time the service was started, and previous zipped.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM