]> gitweb.michael.orlitzky.com - djbdns-logparse.git/blob - djbdns/io.py
1d68fac428ce534652ad50e81c56869121c33a0e
[djbdns-logparse.git] / djbdns / io.py
1 from subprocess import Popen, PIPE
2 from typing import TextIO
3 from djbdns.dnscache import handle_dnscache_log
4 from djbdns.tinydns import handle_tinydns_log
5
6 def parse_logfile(file : TextIO):
7 r"""
8 Process a single log ``file``.
9
10 Parameters
11 ----------
12
13 file : typing.TextIO
14 An open log file, or stdin.
15
16 Examples
17 --------
18
19 >>> line = "@4000000063227a320c4f3114 7f000001:9d61:be69 - 0001 www.example.com\n"
20 >>> from tempfile import NamedTemporaryFile
21 >>> with NamedTemporaryFile(mode="w", delete=False) as f:
22 ... _ = f.write(line)
23 >>> f = open(f.name, 'r')
24 >>> parse_logfile(f)
25 2022-09-14 21:04:40.206516500 dropped query (no authority) from 127.0.0.1:40289 (id 48745): a www.example.com
26 >>> f.close()
27 >>> from os import remove
28 >>> remove(f.name)
29
30 """
31 # Open a pipe to tai64nlocal. We'll write lines of our input file
32 # (the log file) to it, and read back the same lines but with
33 # friendly timestamps in them.
34 tai = Popen(["tai64nlocal"], stdin=PIPE, stdout=PIPE, text=True, bufsize=0)
35
36 for line in file:
37 tai.stdin.write(line)
38 line = tai.stdout.readline()
39
40 friendly_line = handle_tinydns_log(line)
41 if not friendly_line:
42 friendly_line = handle_dnscache_log(line)
43 if not friendly_line:
44 friendly_line = line
45
46 try:
47 print(friendly_line)
48 except BrokenPipeError:
49 # If our stdout is being piped to another process and if
50 # that process closes the pipe, this error will be raised
51 # the next time we try to write to stdout.
52 break
53
54 # Ensure that the pipe gets closed.
55 tai.communicate()