]> gitweb.michael.orlitzky.com - djbdns-logparse.git/blob - djbdns/io.py
75422c01387032f0a0aab6e87e8f40fac411d010
[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 with Popen(["tai64nlocal"],
35 stdin=PIPE,
36 stdout=PIPE,
37 text=True,
38 bufsize=0) as tai:
39
40 for line in file:
41 tai.stdin.write(line)
42 line = tai.stdout.readline()
43
44 friendly_line = handle_tinydns_log(line)
45 if not friendly_line:
46 friendly_line = handle_dnscache_log(line)
47 if not friendly_line:
48 friendly_line = line
49
50 try:
51 print(friendly_line)
52 except BrokenPipeError:
53 # If our stdout is being piped to another process and if
54 # that process closes the pipe, this error will be raised
55 # the next time we try to write to stdout.
56 break