53 lines
2.1 KiB
Plaintext
53 lines
2.1 KiB
Plaintext
|
#!/usr/bin/python3
|
||
|
|
||
|
import argparse
|
||
|
import re
|
||
|
|
||
|
ap = argparse.ArgumentParser()
|
||
|
ap.add_argument("files", nargs="+")
|
||
|
|
||
|
args = ap.parse_args()
|
||
|
|
||
|
sessions = {}
|
||
|
summary = {}
|
||
|
for fn in args.files:
|
||
|
with open(fn) as fh:
|
||
|
for ln in fh:
|
||
|
if m := re.match(r".*user=\[unknown\],db=\[unknown\],pid=(\d+) LOG: connection received: host=(\S+)", ln):
|
||
|
pid = int(m.group(1))
|
||
|
host = m.group(2)
|
||
|
sessions[pid] = { "host": host }
|
||
|
elif m := re.match(r".*user=(.*?),db=(.*?),pid=(\d+) LOG: connection authorized:", ln):
|
||
|
user = m.group(1)
|
||
|
db = m.group(2)
|
||
|
pid = int(m.group(3))
|
||
|
sessions[pid]["user"] = user
|
||
|
sessions[pid]["db"] = db
|
||
|
if m := re.match(r".*application_name=(\S+)", ln):
|
||
|
sessions[pid]["application_name"] = m.group(1)
|
||
|
else:
|
||
|
sessions[pid]["application_name"] = "-"
|
||
|
elif m := re.match(r".*user=(.*?),db=(.*?),pid=(\d+) LOG: disconnection: session time: ([0-9:.]+) user=\S+ database=\S+ host=(\S+)", ln):
|
||
|
user = m.group(1)
|
||
|
db = m.group(2)
|
||
|
pid = int(m.group(3))
|
||
|
time_str = m.group(4)
|
||
|
host = m.group(5)
|
||
|
m = re.match("(\d+):(\d{2}):(\d{2})\.(\d{3})", time_str)
|
||
|
time = int(m.group(1)) * 3600 + int(m.group(2)) * 60 + int(m.group(3)) * 1 + int(m.group(4)) * 0.001
|
||
|
|
||
|
assert user == sessions[pid]["user"]
|
||
|
assert db == sessions[pid]["db"]
|
||
|
assert host == sessions[pid]["host"]
|
||
|
|
||
|
s = summary.setdefault((db, user, host, sessions[pid]["application_name"]), { "n_sessions": 0, "session_time": 0 })
|
||
|
s["n_sessions"] += 1
|
||
|
s["session_time"] += time
|
||
|
del sessions[pid]
|
||
|
|
||
|
print("Database", "User", "Client", "Application", "#Sessions", "Session time (s)", sep="\t")
|
||
|
for k, v in summary.items():
|
||
|
print(k[0], k[1], k[2], k[3], v["n_sessions"], v["session_time"], sep="\t")
|
||
|
|
||
|
# vim: tw=0
|