Skip to content
Advertisement

How to log the live output of a running process

I want to run a game server inside my Ubuntu machine. I want to run it in the background and write the live output of that process inside a log file. I tried using nohup and running the game server using “&” at the end but I couldn’t make it work the way I wanted.

Then I started reading about named pipes and actually gave it a go. I made a simple script that in theory should work. But, of course I am missing something.

First, I made a pipe using the mkfifo command.

mkfifo testpipe

Then I created a small script:

#!/bin/bash
./mta-server64 > pipe &

pid=$!

echo $pid // so I know the pid of the process

cat < pipe > log.txt &

(Note: I wrote this code from memory.)

The code works only when there is an error and the process stops. It actually records the game console error. But when the game server is running I get no output in the log file.

I want to read the output (stdout and stderr if I am not mistaken) of a process running in background and record it those inside a log file.

I also thought about using screen as it logs everything inside a file but I would prefer not using it if there is a better solution.

EDIT:

First of all: thank you for the interest you had in helping me. In the same way, I have to apologize for only giving scarce details about what I intend to do with this small project and for my limited understanding of stdout and stderr.

Let’s go to the first base.

I want to run a game server named Multi Theft Auto (https://multitheftauto.com/). This is GTA San Andreas but multiplayer.

I can easily run this game server in my Ubuntu server by calling the executable ./mta-server-64. After calling it the game server console appears:

[|] MTA: San Andreas :: 0/32 players :: 196 resources :: 125 fps (25)
MTA:BLUE Server for MTA:SA
==================================================================
= Multi Theft Auto: San Andreas v1.5.6 [64 bit]
==================================================================
= Server name      : Default MTA Server
= Server IP address: auto
= Server port      : 22884
=
= Log file         : /root/mta/mods/deathmatch/logs/server.log
= Maximum players  : 32
= HTTP port        : 22564
= Voice Chat       : Disabled
= Bandwidth saving : Medium
==================================================================
[09:49:07] Resource 'mapmanager' requests some acl rights. Use the command 'aclrequest list mapmanager'
[09:49:07] Resources: 196 loaded, 0 failed
[09:49:07] Starting resources...
[09:49:07] Server minclientversion is now 1.5.6-9.16588.0
[09:49:07] INFO: MAPMANAGER: Some important ACL permissions are missing. To ensure the correct functioning of Mapmanager, please write: aclrequest allow mapmanager all
[09:49:07] Gamemode 'play' started.
[09:49:07] Authorized serial account protection is enabled for the ACL group(s): `Admin`  See http://mtasa.com/authserial
[09:49:07] WARNING: <owner_email_address> not set
[09:49:07] Server started and is ready to accept connections!
[09:49:07] To stop the server, type 'shutdown' or press Ctrl-C
[09:49:07] Type 'help' for a list of commands.
[09:49:07] Querying MTA master server... success! (Auto detected IP:xxx.xxx.xxx.xxx)

I am using the following script to run the process in the background and (try to) get the live output from:

#!/bin/bash

newport=$(shuf -i 22003-22900 -n 1)
newip=$(shuf -i 22003-22900 -n 1)

rm -rf ~/server/*

cp -r /home/user*/ftp/server/mtaserver/serverfiles/* ~/server

sed -i "s/<httpport>[0-9][0-9][0-9][0-9][0-9]</httpport>/<httpport>$newport</httpport>/g" ~/server/mods/deathmatch/mtaserver.conf
sed -i "s/<serverport>[0-9][0-9][0-9][0-9][0-9]</serverport>/<serverport>$newip</serverport>/g" ~/server/mods/deathmatch/mtaserver.conf

~/server/mta-server64 2>&1 | tee -a outfile &

mta_pid=$!

echo $mta_pid

sleep 6

pkill $mta_pid

(Note: Because of some technical problems I had to add the first few lines of script which automatically replace the game files with new ones and also replace the existing ports with random ones.)

This script starts the server and tries to log the output of the process. The process is automatically killed after few seconds so there is only one instance of the game server at any given time.

THE ISSUE:

This script only logs the output if there is an error. I still cannot get the live output of the process when it is still running. Maybe this is an issue with the game server but truly believe there should be a way to make it work the way I intend.

Advertisement

Answer

After 2 days I finally figured out a way to make it work (the way I intended to work, without taking in consideration any major security/performance risks).

Reading the comments made me realize I was attacking the wrong point. The stdout of the game server is buffered, thus making it impossible to log it into a log file using the methods I tried when I posted my question At least this is what I came to understand).

I did some research on how to run the application without having the stdout buffered: https://serverfault.com/questions/294218/is-there-a-way-to-redirect-output-to-a-file-without-buffering-on-unix-linux

My code now:

    stdbuf -o0 ~/server/mta-server64 >> pipe &

    cat < pipe | tee -a outfile &

After creating the named pipe it executes the game server inside that pipe and then appends the stdout into the log file.

The stdbug -o0 command disables the stdout buffering (as noted in the link above).

This works for me and I cannot guarantee it will work for anybody else. I am still not aware if disabling the buffering is a safe approach to my issue but for now it is what I need.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement