watchlog: minor indentation cleanup
[compresslog.git] / zcatfollow
blobc1f62a6dc3f9c5e0552d741637bc77e3c6363552
1 #!/usr/bin/python
3 # Will uncompress a gzipped file in "streaming" mode,
4 # like `tail -b +0 -f ` would do.
6 # If you pass -n <int> parameter it will try to act like
7 # a smart "tail" command: reads until the end of the current
8 # file, shows you the last <int> lines, then "follows" the file.
10 # If the writer is writing faster than we read, then it may never
11 # "detect" the "end of the file"...
13 # License: GPLv2
14 # Author: Martin Langhoff <martin.langhoff@gmail.com>
15 # Copyright: Remote Learner US - http://www.remote-learner.net/
17 import sys
18 import gzip
19 import zlib
20 import time
21 import getopt
22 from collections import deque
23 import signal
25 try:
26 optslist, args = getopt.getopt(sys.argv[1:], "tn:")
27 opts={}
28 for k,v in optslist:
29 opts[k] = v
31 except getopt.GetoptError as err:
32 # print help information and exit:
33 print(err) # will print something like "option -a not recognized"
34 #usage()
35 sys.exit(2)
37 # lookbehind buffer, defined as a list
38 lbbuf=deque([])
39 buffering=False
40 bufferfull=False
42 if '-n' in opts:
43 buffering=True
44 lbbufsize=int(opts['-n'])
46 # tidy up - no errors on ctrl-C, etc
47 def sig_exit(signum, frame):
48 # this will prompt fh cleanup, etc
49 sys.exit(0)
50 signal.signal(signal.SIGHUP, sig_exit)
51 signal.signal(signal.SIGINT, sig_exit)
52 signal.signal(signal.SIGTERM, sig_exit)
54 f = gzip.open(args[0], 'r')
56 # while / readline() sidesteps magic input buffering
57 while 1:
58 try:
59 line = f.readline()
60 except IOError:
61 ## we ignore IOError("CRC check failed")
62 ## because we are reading an "unfinished"
63 ## gzip stream...
64 # line won't get unset if this triggers
65 line = None
67 if not line:
68 try:
69 if f.closed:
70 break
71 except AttributeError:
72 # old gzip does not have "closed"
73 pass
74 if buffering:
75 # got to the current tail of it
76 # dump our lookbehind buffer, stop buffering
77 for buf_line in lbbuf:
78 sys.stdout.write(buf_line)
79 buffering=False
80 # internal gzip API use?
81 # f.decompress.flush()
82 time.sleep(0.1)
83 else:
84 if not buffering:
85 sys.stdout.write(line)
86 else:
87 if bufferfull:
88 lbbuf.popleft()
89 lbbuf.append(line)
90 else:
91 lbbuf.append(line)
92 if len(lbbuf) >= lbbufsize:
93 bufferfull=True