Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Very elementary grep-like tool. Can look just for a simple string in standard input, has no other parameters, but handles multiline log entries.

About

Standard grep has one weakness regarding the log files - it doesn't handle multiline log entries well. For example logs of Java programs are famous to have many lines of stack traces in a single log item. It is possible to use -A grep parameter but this adds lines also for log items that doesn't have any other lines in them resulting in showing log entries which doesn't contain the search term which is very confusing.

I was so frustrated greping through a log file once that I tried a more exotic approach using Lex and it turned out it's extremely easy with it. I realized that it's in fact raison d’être of lex and that it's very dumb not to use it in the first place.

This tool is of course not general, it's tailored to one particular log format described by the first regexp. Having no parameters, it's a one-off tool, but I'm leaving it here as a template for any other use.

Prerequisites

sudo apt-get install flex

Build

make loggrep # implicit make rule works even for lex and yacc!

Usage

loggrep <search string> < some.log > filtered.log
%{
#include <stdio.h>
#include <string.h>
char *needle;
int match = 0;
%}
%%
^[0-9]{8}\ [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3}\ Provisioner\(0x[0-9a-z]{8}\).*\n {
if (strstr(yytext, needle) != NULL) {
ECHO;
match = 1;
} else {
match = 0;
}
}
. { if (match) ECHO; }
\n { if (match) ECHO; }
%%
int yywrap(void) {
return 1;
}
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("Usage: loggrep <needle>");
return 1;
}
needle = argv[1];
yylex();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment