3

There is a service running as multiple processes and the logs of all come to one huge log (don't ask me why). It looks like this:

process1: bla bla bla
process2: ha ha ha
process3: tarara **error_has_happened**
process3: details of the error here
process1: bla bla bla
process3: more details of the error here
process2: ha ha ha

The error can happen in any of the processes so I want my greps to find this for all processes:

process3: tarara **error_has_happened**
process3: details of the error here
process3: more details of the error here

so basically detect the error_has_happened and the process in which it happened and print the next N lines only from that process. This should happen for all the processes that had this error, assuming the logs of details of the error from different processes are not interleaved

Is it possible to do this using grep alone? how?

3

You can do it with:

grep "error_has_happened" -A3 logfile.log

Where 3, is the number of lines after error_has_happened appearence that will be shown. However, this will also show other process outputs not only the outputs of the process which sends the error.

A more elaborated command that worked for me in a quick test is:

grep "error_has_happened" logfile.log | cut -d : -f1 | sort -u |
  while IFS= read -r process; do
    grep "^$process:" logfile.log |
      grep -A3 "error_has_happened"
  done
  • That would potentially also show output from any other process other than the one sending the error to the log. – Kusalananda Jan 12 '17 at 12:52
  • @Kusalananda You're right, just edited with another proposal. – Zumo de Vidrio Jan 12 '17 at 14:14
  • 1
    Note that using options after arguments like the -A3 in your first example only works with GNU tools (or tools using the GNU getopt_long API with an optstring not starting with +), and even with those, if POSIXLY_CORRECT is in the environment, that would no longer work. I would advise against doing it. – Stéphane Chazelas Jan 13 '17 at 13:04
2

With awk, to print the error line and the 10 lines from that process after it:

awk -F : -v N=10 '/error_has_happened/ {n[$1] = N+1}
                  n[$1]-- > 0' logfile.log
  • Thanks, upvoted! Unfortunately we can't use awk on our prod machines :( that's why I was asking for grep only. But I will keep this one in mind! – fersarr Jan 13 '17 at 12:20
  • @fersarr, out of curiosity, why can't you use awk on your prod machines? – Stéphane Chazelas Jan 13 '17 at 12:42
  • we can only execute a list of 'read-only' commands with the normal access. Awk is blocked because its a full programming language and can even allow you to execute other binaries so they blocked it. Im not saying its the best way to protect the system, its just how it works here for some reason. Of course we can execute actions that modify the state of the machines but only using an approval system that runs them after approved. – fersarr Jan 13 '17 at 12:50

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.