How to redirect output of systemd service to a file

LinuxCentos7SystemdRhelRhel7

Linux Problem Overview


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.

Linux Solutions


Solution 1 - Linux

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

Solution 2 - Linux

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).

Solution 3 - Linux

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.

Solution 4 - Linux

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' 

Solution 5 - Linux

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"

Solution 6 - Linux

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

Solution 7 - Linux

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

Solution 8 - Linux

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'

enter image description here

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmeallhourView Question on Stackoverflow
Solution 1 - LinuxValerio VersaceView Answer on Stackoverflow
Solution 2 - LinuxTrevor Boyd SmithView Answer on Stackoverflow
Solution 3 - LinuxRajat jainView Answer on Stackoverflow
Solution 4 - LinuxShuangistanView Answer on Stackoverflow
Solution 5 - LinuxTigraView Answer on Stackoverflow
Solution 6 - LinuxArnett RufinoView Answer on Stackoverflow
Solution 7 - LinuxHieu HuynhView Answer on Stackoverflow
Solution 8 - LinuxSanthosh HirekerurView Answer on Stackoverflow