Skip to main content
Tweeted twitter.com/#!/StackCodeReview/status/606379081454788608
added 46 characters in body; edited tags
Source Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238

I've written a little command-line utility for filtering log files. It's like grep, except instead of operating on lines it operates on log4j-style messages, which may span multiple lines, with the first line always including the logging level (TRACE, DEBUG etc.).

Example usage on a file short.logshort.log with contents like this:

16:16:12 DEBUG - Something happened, here's a couple lines of info:
 debug line
 another debug line
16:16:14 - I'm being very verbose 'cause you've put me on TRACE
  trace info
16:16:15 TRACE - single line trace
16:16:16 DEBUG - single line debug
16:16:12 DEBUG - Something happened, here's a couple lines of info:
 debug line
 another debug line
16:16:14 - I'm being very verbose 'cause you've put me on TRACE
  trace info
16:16:15 TRACE - single line trace
16:16:16 DEBUG - single line debug

logrep -f short.log DEBUG produces:

16:16:12 DEBUG - Something happened, here's a couple lines of info:
 debug line
 another debug line
16:16:16 DEBUG - single line debug
16:16:12 DEBUG - Something happened, here's a couple lines of info:
 debug line
 another debug line
16:16:16 DEBUG - single line debug

I think the main loop of the program could probably be simplified with some sort of parse and filter. Here it is:

  file = fileinput.input(options.file)
  try:
    line = file.next()
    while True:
      if any(s in line for s in loglevels):
        if filter in line:
          sys.stdout.write(line)
          line = file.next()
          while not any(s in line for s in loglevels):
            sys.stdout.write(line)
            line = file.next()
          continue
      line = file.next()
  except StopIteration:
    return
  file = fileinput.input(options.file)
  try:
    line = file.next()
    while True:
      if any(s in line for s in loglevels):
        if filter in line:
          sys.stdout.write(line)
          line = file.next()
          while not any(s in line for s in loglevels):
            sys.stdout.write(line)
            line = file.next()
          continue
      line = file.next()
  except StopIteration:
    return

I've written a little command-line utility for filtering log files. It's like grep, except instead of operating on lines it operates on log4j-style messages, which may span multiple lines, with the first line always including the logging level (TRACE, DEBUG etc.)

Example usage on a file short.log with contents like this:

16:16:12 DEBUG - Something happened, here's a couple lines of info:
 debug line
 another debug line
16:16:14 - I'm being very verbose 'cause you've put me on TRACE
  trace info
16:16:15 TRACE - single line trace
16:16:16 DEBUG - single line debug

logrep -f short.log DEBUG produces

16:16:12 DEBUG - Something happened, here's a couple lines of info:
 debug line
 another debug line
16:16:16 DEBUG - single line debug

I think the main loop of the program could probably be simplified with some sort of parse and filter. Here it is:

  file = fileinput.input(options.file)
  try:
    line = file.next()
    while True:
      if any(s in line for s in loglevels):
        if filter in line:
          sys.stdout.write(line)
          line = file.next()
          while not any(s in line for s in loglevels):
            sys.stdout.write(line)
            line = file.next()
          continue
      line = file.next()
  except StopIteration:
    return

I've written a little command-line utility for filtering log files. It's like grep, except instead of operating on lines it operates on log4j-style messages, which may span multiple lines, with the first line always including the logging level (TRACE, DEBUG etc.).

Example usage on a file short.log with contents like this:

16:16:12 DEBUG - Something happened, here's a couple lines of info:
 debug line
 another debug line
16:16:14 - I'm being very verbose 'cause you've put me on TRACE
  trace info
16:16:15 TRACE - single line trace
16:16:16 DEBUG - single line debug

logrep -f short.log DEBUG produces:

16:16:12 DEBUG - Something happened, here's a couple lines of info:
 debug line
 another debug line
16:16:16 DEBUG - single line debug

I think the main loop of the program could probably be simplified with some sort of parse and filter.

  file = fileinput.input(options.file)
  try:
    line = file.next()
    while True:
      if any(s in line for s in loglevels):
        if filter in line:
          sys.stdout.write(line)
          line = file.next()
          while not any(s in line for s in loglevels):
            sys.stdout.write(line)
            line = file.next()
          continue
      line = file.next()
  except StopIteration:
    return
Post Reopened by Jamal
Post Closed as "Needs details or clarity" by Jamal
deleted 738 characters in body
Source Link
MikeFHay
  • 283
  • 2
  • 7
16:16:12 DEBUG - Something happened, here's a couple lines of info:
 debug line
 another debug line
16:16:13 DEBUG - more debug
16:16:14 - I'm being very verbose 'cause you've put me on TRACE
  trace info
16:16:15 TRACE - single line trace
16:16:16 DEBUG - single line debug
16:16:12 DEBUG - Something happened, here's a couple lines of info:
 debug line
 another debug line
16:16:13 DEBUG - more debug
16:16:16 DEBUG - single line debug

I think the main loop of the program could probably be simplified. Here's the whole program, as it's short with some sort of parse and filter. Here it is:

#!/usr/bin/env python
import optparse # using optparse to support python version < 2.7
import fileinput
import sys
description = "Search for FILTER in a log file or standard input"
usage = "Usage: %prog [OPTION]... FILTER"

def main():
  p = optparse.OptionParser(description=description, usage=usage)
  p.add_option('--file', '-f', default='-',
               help="take a file as input. Default is STDIN")
  options, arguments = p.parse_args()
  
  if len(arguments) < 1:
    p.print_help()
    return
  
  filter = ' '.join(arguments)
  loglevels = ["TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"]
  file = fileinput.input(options.file)
  try:
    line = file.next()
    while True:
      if any(s in line for s in loglevels):
        if filter in line:
          sys.stdout.write(line)
          line = file.next()
          while not any(s in line for s in loglevels):
            sys.stdout.write(line)
            line = file.next()
          continue
      line = file.next()
  except StopIteration:
    return

if __name__ == '__main__':
  main()
16:16:12 DEBUG - Something happened, here's a couple lines of info:
 debug line
 another debug line
16:16:13 DEBUG - more debug
16:16:14 - I'm being very verbose 'cause you've put me on TRACE
  trace info
16:16:15 TRACE - single line trace
16:16:16 DEBUG - single line debug
16:16:12 DEBUG - Something happened, here's a couple lines of info:
 debug line
 another debug line
16:16:13 DEBUG - more debug
16:16:16 DEBUG - single line debug

I think the main loop of the program could probably be simplified. Here's the whole program, as it's short.

#!/usr/bin/env python
import optparse # using optparse to support python version < 2.7
import fileinput
import sys
description = "Search for FILTER in a log file or standard input"
usage = "Usage: %prog [OPTION]... FILTER"

def main():
  p = optparse.OptionParser(description=description, usage=usage)
  p.add_option('--file', '-f', default='-',
               help="take a file as input. Default is STDIN")
  options, arguments = p.parse_args()
  
  if len(arguments) < 1:
    p.print_help()
    return
  
  filter = ' '.join(arguments)
  loglevels = ["TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"]
  file = fileinput.input(options.file)
  try:
    line = file.next()
    while True:
      if any(s in line for s in loglevels):
        if filter in line:
          sys.stdout.write(line)
          line = file.next()
          while not any(s in line for s in loglevels):
            sys.stdout.write(line)
            line = file.next()
          continue
      line = file.next()
  except StopIteration:
    return

if __name__ == '__main__':
  main()
16:16:12 DEBUG - Something happened, here's a couple lines of info:
 debug line
 another debug line
16:16:14 - I'm being very verbose 'cause you've put me on TRACE
  trace info
16:16:15 TRACE - single line trace
16:16:16 DEBUG - single line debug
16:16:12 DEBUG - Something happened, here's a couple lines of info:
 debug line
 another debug line
16:16:16 DEBUG - single line debug

I think the main loop of the program could probably be simplified with some sort of parse and filter. Here it is:

  file = fileinput.input(options.file)
  try:
    line = file.next()
    while True:
      if any(s in line for s in loglevels):
        if filter in line:
          sys.stdout.write(line)
          line = file.next()
          while not any(s in line for s in loglevels):
            sys.stdout.write(line)
            line = file.next()
          continue
      line = file.next()
  except StopIteration:
    return
Source Link
MikeFHay
  • 283
  • 2
  • 7

Filtering file for command line tool

I've written a little command-line utility for filtering log files. It's like grep, except instead of operating on lines it operates on log4j-style messages, which may span multiple lines, with the first line always including the logging level (TRACE, DEBUG etc.)

Example usage on a file short.log with contents like this:

16:16:12 DEBUG - Something happened, here's a couple lines of info:
 debug line
 another debug line
16:16:13 DEBUG - more debug
16:16:14 - I'm being very verbose 'cause you've put me on TRACE
  trace info
16:16:15 TRACE - single line trace
16:16:16 DEBUG - single line debug

logrep -f short.log DEBUG produces

16:16:12 DEBUG - Something happened, here's a couple lines of info:
 debug line
 another debug line
16:16:13 DEBUG - more debug
16:16:16 DEBUG - single line debug

I think the main loop of the program could probably be simplified. Here's the whole program, as it's short.

#!/usr/bin/env python
import optparse # using optparse to support python version < 2.7
import fileinput
import sys
description = "Search for FILTER in a log file or standard input"
usage = "Usage: %prog [OPTION]... FILTER"

def main():
  p = optparse.OptionParser(description=description, usage=usage)
  p.add_option('--file', '-f', default='-',
               help="take a file as input. Default is STDIN")
  options, arguments = p.parse_args()
  
  if len(arguments) < 1:
    p.print_help()
    return
  
  filter = ' '.join(arguments)
  loglevels = ["TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"]
  file = fileinput.input(options.file)
  try:
    line = file.next()
    while True:
      if any(s in line for s in loglevels):
        if filter in line:
          sys.stdout.write(line)
          line = file.next()
          while not any(s in line for s in loglevels):
            sys.stdout.write(line)
            line = file.next()
          continue
      line = file.next()
  except StopIteration:
    return

if __name__ == '__main__':
  main()