Skip to content

Instantly share code, notes, and snippets.

@zeandrade
Created June 3, 2019 14:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zeandrade/cbf13a17b391be9e0936f4b15bedabe7 to your computer and use it in GitHub Desktop.
Save zeandrade/cbf13a17b391be9e0936f4b15bedabe7 to your computer and use it in GitHub Desktop.
Script to display squid's access log output in human-readable format.
#!/usr/bin/env python3
'''
Translate the squid access log output to an human friendly format.
- copy this script to some $PATH dir (ex. /usr/local/bin)
- set permission: chmod a+x tr_sal.py
usage: zcat /path/log/access.log.gz | tr_sal.py
cat /path/log/access.log | tr_sal.py -s > ~/myfile.txt
tail -F /path/log/access.log | tr_sal.py -s | less
'''
import random
import sys
import time
import argparse
from datetime import datetime, timedelta
parser = argparse.ArgumentParser()
parser.add_argument(
'-s', '--safe', help='safe output to redirect to a file',
action="store_true")
parser.add_argument('infile', nargs='?',
type=argparse.FileType('r'),
default=sys.stdin, help='read from stdin')
args = parser.parse_args()
def human_legible(num, iec=True):
"""
Human legible, IEC binary standard
"""
if not isinstance(num, int):
num = int(num)
ext_list = ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']
divisor = 1000.0
if iec:
ext_list = [item + 'i' for item in ext_list]
ext_list[0] = ''
divisor += 24.0
for unit in ext_list:
if abs(num) < divisor:
break
num /= divisor
return "%.1f %sB" % (num, unit)
def colors(style=None):
# style = random.choice(range(8))
if style == 0:
return 0, 36, 40
elif style == 1:
return 6, 32, 40
elif style == 'info':
return 1, 30, 40
elif style == 'error':
return 0, 31, 40
elif style == 'auth_error':
return 0, 35, 40
elif style == 'ok':
return 2, 30, 42
elif style == 'warn':
return 7, 30, 43
else:
style = random.choice([0, 1, 5, 6])
fg = random.choice(range(31, 38))
bg = 40 # dark
return style, fg, bg
def color_format(texto='?', style=None):
style, fg, bg = colors(style)
formato = ';'.join([str(style), str(fg), str(bg)])
return '\x1b[{}m{}\x1b[0m'.format(formato, texto)
try:
for line in args.infile:
date_t, time_spent, ip, status, size, method, url, user, *others = line.split()
obj_data = datetime.fromtimestamp(float(date_t))
date_t = obj_data.strftime('%Y-%m-%d %H:%M:%S.%f')
time_spent = timedelta(milliseconds=int(time_spent))
output = "{} [duration:{:>14}] {:^15} {:^12} {:^10} {} {} {} {} \n"
line_output = output.format(
date_t, str(time_spent), ip, status, human_legible(size),
method, url, user, "; ".join(others))
if args.safe:
sys.stdout.write(line_output)
elif '_DENIED' in status and '407' in status:
sys.stdout.write(color_format(line_output, 'auth_error'))
elif '404' in status:
sys.stdout.write(color_format(line_output, 'info'))
elif any(num_status in status for num_status in ['500', '502']):
sys.stdout.write(color_format(line_output, 'warn'))
elif '_DENIED' in status:
sys.stdout.write(color_format(line_output, 'error'))
else:
sys.stdout.write(line_output)
sys.stdout.flush()
except ValueError:
quit("ERROR: this lines can't be formatted")
except KeyboardInterrupt:
quit()
except BrokenPipeError:
quit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment