Xachuous
Xachuous

Reputation: 19

Calling "top" command from systemd service

I've written a bash script that outputs date, time, CPU, and MEM usage of a specific process into a file. I made a "topLogger.service" service that runs and outputs the date and time into the file but the top output (CPU and MEM) isn't showing up in the output file.

When I just run the bash script from the bash shell it works just fine!

sudo ./topLoggerScript.sh 

I believe this line may be the culprit, but I am not sure how to troubleshoot this.

/usr/bin/top -n 1 | grep service_to_monitor

Here is the whole script:

#!/bin/bash

cpu=10
mem=11
cur_date=$(date +"%Y-%m-%d")
echo "starting date is $cur_date"

# Create starting file if todays file does not exist
if [ ! -e  /file/location/$cur_date.txt ] ; then
  echo "DATE  TIME  CPU  MEM" > /file/location/$cur_date.txt
fi

    while true
               do
                  STRING=$(/usr/bin/top -n 1 | grep service_to_monitor)
                  arr=($STRING)

                  next_date=$(date +"%Y-%m-%d")

                  if [ "$cur_date" != "$next_date" ];then
                     # Day changed. Create a new file using cur_date.
                     echo "DAY CHANGE"
                     echo "DATE TIME CPU MEM" > /file/location/$cur_date.txt

                     # And change prev_date to cur_date
                     cur_date=$next_date
                  fi

                  sudo echo $(date +"%Y-%m-%d  %H-%M-%S")  ${arr[cpu-1]}  ${arr[mem-1]}>>/file/location/$cur_date.txt
                  sleep 5
    done

Here are my service file's permissions:

-rw-rw-r--  1 root root  121 Oct 25 15:54 topLogger.service

And here is the topLogger.service file itself:

    [Unit]
    Description=Resource monitor for a specific process

    [Service]
    ExecStart=/path/to/script/logResourceUsage.sh

Upvotes: 1

Views: 793

Answers (2)

Bri4n
Bri4n

Reputation: 641

I had a similar problem. Top output changes according to the COLUMNS env variable. When running with systemd or nohup the output changes so it breaks your code.

In order to solve it you can pass the number of columns to the top command using the -w option.

/usr/bin/top -n 1 -w 1000 | grep service_to_monitor

This way your top command is going to be independent of the environment where it's running.

Upvotes: 1

Christian Grabowski
Christian Grabowski

Reputation: 2892

The issue is top -n 1 doesn't exit after printing its output like say echo does. The way you wrote your script would require a process to print these values as plain text, then exit so that it is then piped to grep. top -l 1 -n 1 is probably more ideal, this will print and exit appropriately.

Upvotes: 1

Related Questions