]> gitweb.michael.orlitzky.com - djbdns-logparse.git/blobdiff - bin/djbdns-logparse
doc/README: siphon the description and history from bin/djbdns-logparse.
[djbdns-logparse.git] / bin / djbdns-logparse
index 6cb702fc084ede27fd4271dc4226f0469fa5ea1b..2e184d814228a39d1992cd3eb581dba317dc74d7 100755 (executable)
@@ -1,30 +1,14 @@
 #!/usr/bin/python3
-#
-# Reads log files from tinydns and/or dnscache and prints them out in
-# human-readable form. Logs can be supplied on stdin, or listed on the
-# command line:
-#
-#   $ cat @*.s | djbdns-logparse
-#   $ djbdns-logparse @*.s
-#   $ tail -f current | djbdns-logparse
-#
-# Pipes each log file through tai64nlocal, which must be on your path.
-#
-# Acknowledgments:
-#
-# * The log format descriptions by Rob Mayoff were invaluable:
-#   ** http://dqd.com/~mayoff/notes/djbdns/tinydns-log.html
-#   ** http://dqd.com/~mayoff/notes/djbdns/dnscache-log.html
-#
-# * Faried Nawaz's dnscache log parser was the original inspiration:
-#   ** http://www.hungry.com/~fn/dnscache-log.pl.txt
-#
-
-import sys, re
+"""
+Convert tinydns and dnscache logs to human-readable form
+"""
+
+import re
 from struct import pack
 from time import strftime, gmtime
 from subprocess import Popen, PIPE
 
+
 # common components of line-matching regexes
 timestamp_pat = r'[\d-]+ [\d:\.]+'      # output of tai64nlocal
 hex4_pat = r'[0-9a-f]{4}'
@@ -62,9 +46,6 @@ query_drop_reason = {
     }
 
 
-def warn(filename, msg):
-    sys.stderr.write("warning: %s: %s\n" % (filename, msg))
-
 def convert_ip(ip):
     """Convert a hex string representing an IP address to conventional
     human-readable form, ie. dotted-quad decimal for IPv4, and
@@ -189,7 +170,7 @@ def handle_tinydns_log(line, match):
     type = int(type, 16)                # "001c" -> 28
     type = query_type.get(type, type)   # 28 -> "aaaa"
 
-    print(timestamp,)
+    print(timestamp, end=' ')
 
     if code == "+":
         print ("sent response to %s:%s (id %s): %s %s"
@@ -206,7 +187,7 @@ def handle_tinydns_log(line, match):
                % (code, ip, port, id, type, name))
 
 
-def parse_logfile(file, filename):
+def parse_logfile(file):
     # Open pipe to tai64nlocal: we will write lines of our input (the
     # raw log file) to it, and read log lines with readable timestamps
     # from it.
@@ -226,18 +207,28 @@ def parse_logfile(file, filename):
             handle_dnscache_log(line, match)
             continue
 
-        sys.stdout.write(line)
+        print(line)
 
 def main():
-    if len(sys.argv) > 1:
-        for filename in sys.argv[1:]:
-            if filename == "-":
-                parse_logfile(sys.stdin, "(stdin)")
-            else:
-                with open(filename) as file:
-                    parse_logfile(file, filename)
-    else:
-        parse_logfile(sys.stdin, "(stdin)")
+    # Create an argument parser using the file's docsctring as its
+    # description.
+    from argparse import ArgumentParser, FileType
+    parser = ArgumentParser(description = __doc__)
+
+    # Parse zero or more positional arguments into a list of
+    # "logfiles". If none are given, read from stdin instead.
+    from sys import stdin
+    parser.add_argument("logfiles",
+                        metavar="LOGFILE",
+                        type=FileType("r"),
+                        nargs="*",
+                        default=[stdin],
+                        help="djbdns logfile to process (default: stdin)")
+
+    args = parser.parse_args()
+    for f in args.logfiles:
+        parse_logfile(f)
+