{"id":38,"date":"2011-04-12T23:59:31","date_gmt":"2011-04-13T06:59:31","guid":{"rendered":"http:\/\/www.lorrin.org\/blog\/?p=38"},"modified":"2012-03-16T23:28:47","modified_gmt":"2012-03-17T06:28:47","slug":"snipping-log-files-by-time","status":"publish","type":"post","link":"https:\/\/www.lorrin.org\/blog\/2011\/04\/12\/snipping-log-files-by-time\/","title":{"rendered":"Snipping log files by time"},"content":{"rendered":"<p>Grepping through log files for lines that match a timestamp is fiddly. It&#8217;s hard to catch multi-line entries (e.g. stack traces) and to craft a regex that captures an exact time range. I wrote a little Python script to simpify the process.<\/p>\n<p>Usage:<\/p>\n<pre class=\"brush:shell\"> &lt;example.log| .\/by_time.py 9:40 9:44:15<\/pre>\n<p>Code below is <a href=\"https:\/\/github.com\/lorrin\/misc-tools-scripts\/blob\/master\/by_time.py\">maintained on GitHub<\/a>.<\/p>\n<pre class=\"brush:py\">#!\/usr\/bin\/env python\r\n\r\n# Selects time range from a log file. Lines with no time (e.g. stack traces)\r\n# are presumed to have occurred at the time of the preceding line.\r\n#\r\n# Assumes first time-like phrase on a line is the timestamp for that line.\r\n#\r\n# Assumes time format is pairs of digits separated by colons with optional , or\r\n# . initiated suffix. E.g. HH:mm:ss,SSS, HH:mm, etc.\r\n#\r\n# Does not strip blank lines; just use awk 'NF&gt;0' for that.\r\n\r\nimport sys,re\r\ntime_pattern = re.compile(\"(?:^|.*?\\D)(\\d{1,2}(?::\\d{2})+(?:[,.]\\d+)?)\")\r\nfields_pattern = re.compile(\"[:,.]\")\r\n\r\nif len(sys.argv) &lt; 3:\r\n  print &gt;&gt; sys.stderr, \"Please specify start and end times (e.g. %s 13:50 14:10:01,101).\" % sys.argv[0]\r\n  exit(1)\r\n\r\nfor item,index in [[\"start time\",1],[\"end time\",2]]:\r\n  if not time_pattern.match(sys.argv[index]):\r\n    raise ValueError(\"Cannot parse %s: %s\" % (item, sys.argv[index]))\r\n\r\nstart,end = [[int(x) for x in re.split(fields_pattern, s)] for s in sys.argv[1:3]]\r\ntoo_soon = True\r\n\r\ntry:\r\n  for line in sys.stdin:\r\n    line = line.strip()\r\n    m = time_pattern.match(line)\r\n    if m:\r\n      t = [int(x) for x in re.split(fields_pattern,m.group(1))]\r\n      if t &gt;= end:\r\n        break\r\n      elif too_soon and t &gt;= start:\r\n        too_soon = False\r\n\r\n    if not too_soon:\r\n      print line\r\nexcept IOError:\r\n  pass<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Grepping through log files for lines that match a timestamp is fiddly. It&#8217;s hard to catch multi-line entries (e.g. stack traces) and to craft a regex that captures an exact time range. I wrote a little Python script to simpify the process. Usage: &lt;example.log| .\/by_time.py 9:40 9:44:15 Code below is maintained on GitHub. #!\/usr\/bin\/env python <a href='https:\/\/www.lorrin.org\/blog\/2011\/04\/12\/snipping-log-files-by-time\/' class='excerpt-more'>[&#8230;]<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[48],"tags":[15,12,17,11],"_links":{"self":[{"href":"https:\/\/www.lorrin.org\/blog\/wp-json\/wp\/v2\/posts\/38"}],"collection":[{"href":"https:\/\/www.lorrin.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lorrin.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lorrin.org\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lorrin.org\/blog\/wp-json\/wp\/v2\/comments?post=38"}],"version-history":[{"count":7,"href":"https:\/\/www.lorrin.org\/blog\/wp-json\/wp\/v2\/posts\/38\/revisions"}],"predecessor-version":[{"id":161,"href":"https:\/\/www.lorrin.org\/blog\/wp-json\/wp\/v2\/posts\/38\/revisions\/161"}],"wp:attachment":[{"href":"https:\/\/www.lorrin.org\/blog\/wp-json\/wp\/v2\/media?parent=38"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lorrin.org\/blog\/wp-json\/wp\/v2\/categories?post=38"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lorrin.org\/blog\/wp-json\/wp\/v2\/tags?post=38"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}