0

I am looking for a single line regular expression to match the word "Error" from the log file and i need to get the few lines above and below the lines that has the word "Error" for debugging purpose.

For example: I need to match for the word "TypeError" and get other few lines above and below this matched lines. atleast i need next 10 lines. Could anyone please help on this ?

Log File content below =>

**TypeError**: Parameter 'url' must be a string, not undefined
    at Url.parse (url.js:107:11)
    at urlParse (url.js:101:5)
    at Object.urlResolve [as resolve] (url.js:404:10)
    at parseMarkdown (/opt/controllers/api/userguide.js:53:19)
    at /opt/controllers/api/userguide.js:33:17
    at Object.<anonymous> (/opt/models/api.js:172:4)
    at /opt/lib/data/api.js:138:5
    at IncomingMessage.<anonymous> (/opt/node_modules/httpunch/lib/_wrap_request.js:100:9)
    at IncomingMessage.g (events.js:180:16)
    at IncomingMessage.emit (events.js:117:20)
Jack
  • 8,411
  • 2
  • 24
  • 38
  • You've not specified an environment -- in a unix-like environment with grep, http://stackoverflow.com/questions/9081/grep-a-file-but-show-several-surrounding-lines will do what you're looking for. – zebediah49 Mar 09 '15 at 20:59
  • yes its unix environment. i am using monit to monitor server logging. so i need to use this regular expression to get error and related lines check file Error-log-in-locutus with path /var/log/locutus/web.log if match "Error" then alert – muthukumar murugesan Mar 09 '15 at 21:04

2 Answers2

1

Try this (Fetches upto 10 preceding and succeeding lines)-

(?:(?:.*\n){0,10}).*?Error.*(?:(?:\n.*){0,10})

Demo

EDIT
Just read the comment about unix environment.
You can use Grep command using the same regex as above.
Like this -

$ grep -Pzo "(?:(?:.*\n){0,10}).*?Error.*(?:(?:\n.*){0,10})" <filename>
Kamehameha
  • 5,258
  • 1
  • 19
  • 26
  • It throws error like below /etc/monit/monitrc:276: Error: regex parsing error:Invalid preceding regular expression '"(?:(?:.*\n){1,10})?.*?Error.*(?:(?:\n.*){1,10})?"' – muthukumar murugesan Mar 09 '15 at 21:23
  • @muthukumarmurugesan Can you tell me, exactly how you are using the regex? – Kamehameha Mar 09 '15 at 21:24
  • Here is my code in Monitrc config file
    
    check file Error-log-in-locutus with path /var/log/locutus/web.log 
    if match "Error" then alert

    so it is throwing error as /etc/monit/monitrc:276: Error: regex parsing error:Invalid preceding regular expression '"(?:(?:.*\n){1,10})?.*?Error.*(?:(?:\n.*){1,10})?"'
    – muthukumar murugesan Mar 09 '15 at 21:27
  • Here is the actual code "**check file Error-log-in-borg with path /var/log/borg/web.log if match "(?:(?:.*\n){1,10})?.*?Error.*(?:(?:\n.*){1,10})?" then alert**" – muthukumar murugesan Mar 09 '15 at 21:30
  • @muthukumarmurugesan I looked up the regex that monit uses(I've not used this before, but google redirected me to [here](http://linux.die.net/man/1/monit) and [here](http://linux.die.net/man/7/regex) ). I do not think it will support `\n` like I've used. I don't think I can help you other than point out that you can try a simpler expression and see where it goes `"(.*\n){0,10}.*?Error.*(\n.*){0,10}`. Good luck :) – Kamehameha Mar 09 '15 at 22:01
0

All credits to Kamehameha for this answer, it's based on his regexp, but I went ahead and made it a little bit simpler to follow with an accompanying explanation. It is not as perfect as the original though, but works pretty well.

Full expression

(\n.*){0,10}(.*Error:.*)(\n.*){0,10}

View on regexr

Match the error line itself

.*Error:.*

This line is actually quite simple. The only thing you need to know is that .* matches any number of characters (but not line breaks). So this line means "Find anything followed by "Error:" followed by anything"

Match any line

\n.*

This is also pretty easy to understand: \n (newline) followed by anything.

Match up to 10 lines

(\n.*){0,10}

This takes the "full line" regex and applies it between 0 and 10 times, as many as possible (since regex is greedy by default).

Putting it all together

What we want is "10 lines + error line + 10 lines", so we just take what we made previously and put into one big statement.

(\n.*){0,10}(.*Error:.*)(\n.*){0,10}
Henrik Karlsson
  • 5,127
  • 4
  • 22
  • 40