0

I want to monitor a log file in real time, and execute some commands when some sentences appear in the log.

I searched this site (and many other sites) and these are what I tried:

tail -f /var/log/omxlog | awk '/player_new/ { "echo hello" }'

or

stdbuf -o0 tail -F /var/log/omxlog | awk '/player_new/ { "echo hello" }'

But they don't work. Whenever I run these commands, it begins to wait, but although I'm sure the log file changes, it doesn't print echo hello; actually it doesn't do anything. Just waiting :D

So, what should I do!?

(System: Raspberry Pi. OS: Raspbian)

1

Archemar has the correct solution for your exact question in his answer.

However it's clear that you probably want to execute regular commands, like you would in bash, since you used "echo hello".

In that case, it will be much easier if you stay within bash, and then you have its full power at your disposal (Instead of having to learn how to do that within awk), I think you will find this much more flexible and easy to work with.

bash method, in a one liner:

tail .... | while read ; do [[ "{REPLY}" =~ player_new ]] && echo hello ; done

You can do something like this:

#!/bin/bash

tail_log()
{
    tail -f "${1}"
    # or use stdbuf here instead
}

do_player_new()
{
  local log_line="${1}"
  echo "hello"
}

do_something_else()
{
  local log_line="${1}"
  echo "example: line was ${1}"
}

process_match()
{
  local full_line="${1}"

  case "${BASH_REMATCH[1]}"  #this bash_rematch array holds the part of the line that matched the () in the pattern 
  in
    player_new)      do_player_new "${full_line}";;
    something_else)  do_something_else "${full_line}";;
    another_example) do_another_example "${full_line}";;
  esac

  #or you could actually just execute this:
  # "do_${BASH_REMATCH[1]}" "${full_line}"
}

process_log()
{
  local logfile="${1}"
  local matcher="${2}"

  tail_log "${logfile}" | while read line
  do 
    # this checks the line against the regular expression
    # and the result of the match (parts between ()) will
    # be stored in the BASH_REMATCH array
    [[ "${line}" =~ ${matcher} ]] && process_match "${line}"
  done
}

process_log /var/log/omxlog '(player_new|something_else)' &

process_log /some/other/log '(another_example)' &

Example text from running a test on my android phone

$> while sleep 5 ; do echo player_new >> test.txt ; done &
[2] 3110
$> tail -f test.txt | while read ; do [[ "${REPLY}" =~ player_new ]] && echo $(date) hello; done
Wed Feb 15 01:39:12 ACDT 2017 hello
Wed Feb 15 01:39:12 ACDT 2017 hello
Wed Feb 15 01:39:12 ACDT 2017 hello
Wed Feb 15 01:39:15 ACDT 2017 hello
Wed Feb 15 01:39:20 ACDT 2017 hello
^C
$>

This works on my phone, so I suspect the reason it's not working for you may be something to do with the raspberry pi which I can't help with sorry

  • I tried the first inline method, but unfortunately it doesn't work again. Just waiting. Maybe the problem is that I'm using putty to SSH into RPi !!? Any suggestions? – Omid1989 Feb 14 '17 at 14:34
  • I think it must be something to do with the raspberry pi yeah. I've added sample output above so you can see it working and compare to what you've got – Chunko Feb 14 '17 at 15:16
  • This is a really long shot, but you might try running the command "sync" in another terminal and see if this causes the kernel to flush any IO buffers, maybe it is still buffered and not written to your log file yet I don't know – Chunko Feb 14 '17 at 15:19
0

Use print to print statements in awk. for more refer this solution.

For matching the string player_new use :

awk '$1 ~ /player_new/ {print $1}' /var/log/omxlog

To monitor continuously :

tail -f /var/log/omxlog | awk '$1 ~ /player_new/ {print $1}'

More of this here.

  • 1
    first solution won't "follow" the file. – Archemar Feb 14 '17 at 12:19
  • The first solution doesn't follow. The second solution doesn't work. Same thing that happens with my own tries. – Omid1989 Feb 14 '17 at 14:31
  • 1. The $1 argument shown is just an example, in your logs please check the number and use same with '$' while running the command. You can change print to whatever you want. – sai sasanka Feb 14 '17 at 14:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.