How can I output logs to a file from the content of a service with systemd

17,288

I encountered a similar issue. As explained here, it turns out that you can't redirect output directly within ExecStartPre, ExecStart, or ExecStopPost commands - systemd will interpret the > or >> as arguments. The solution is to execute your command using sh -c.

There's also one other issue I ran into when trying to use the date command in my systemd script: %m is a special code referring to the machine ID of the current host. So in order to have it output the month you need to escape the percent sign by using two percent signs (%%). Putting it all together, the systemd version of the above pre and post-scripts is:

# Date format same as (new Date()).toISOString() for consistency
ExecStartPre = /bin/sh -c 'echo "[`date -u +%Y-%%m-%dT%T.%3NZ`] (sys) Starting" >> /var/log/yourapp.upstart.log'
ExecStopPost = /bin/sh -c 'rm /var/run/upstart-ghost.pid; echo "[`date -u +%Y-%%m-%dT%T.%3NZ`] (sys) Stopping" >> /var/log/yourapp.upstart.log'
Share:
17,288

Related videos on Youtube

robe007
Author by

robe007

Updated on September 18, 2022

Comments

  • robe007
    robe007 over 1 year

    Well, I have a service configured with systemctl. This is the config file:

    [Unit]
    Description=The description of the service (:
    After=network.target
    
    [Service]
    ExecStartPre=/bin/echo 'Starting Service' >> /var/log/node/myapp.log
    ExecStart=/root/.nvm/versions/node/v5.0.0/bin/node ./bin/www
    ExecStopPost=/bin/echo 'Stopping Service' >> /var/log/node/myapp.log
    Restart=always
    #StandardOutput=/var/log/node/myapp.log
    #StandardError=/var/log/node/myapp.log
    SyslogIdentifier=myapp
    Environment=NODE_ENV=production
    WorkingDirectory=/home/user/node-apps/theapp
    
    [Install]
    WantedBy=multi-user.target
    

    What I need?:

    1) The ExecStartPre and ExecStopPost could write the message 'starting service' or 'stopping service' to the file /var/log/node/myapp.log. With the above configuration, doesn't work, it only outputs 'Starting Service' >> /var/log/node/myapp.log and 'Stopping Service' >> /var/log/node/myapp.log to journalctl. (I checked with journalctl -u myapp)

    2) I need that instead of the all logs of the app, outputs to the journalctl, could output to a file. Ex: /var/log/node/myapp.log. I mean, if in my app, I have a console.log(), this could be there.

    With upstart, I can do it in this way:

    script
    
    exec start-stop-daemon --start --make-pidfile --pidfile /var/run/upstart-yourapp.pid --chdir /var/www/yourapp/--chuid user:usergroup --exec /usr/bin/node index.js >> /var/log/yourapp.upstart.log 2>&1
    
    end script
    
    pre-start script
        # Date format same as (new Date()).toISOString() for consistency
        echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Starting" >> /var/log/yourapp.upstart.log
    end script
    
    post-stop script
        rm /var/run/upstart-ghost.pid
        echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Stopping" >> /var/log/yourapp.upstart.log
    end script
    

    But, it is possible to do it with systemctl?