10637.3.1
by Guilherme Salgado
Use the default python version instead of a hard-coded version |
1 |
#!/usr/bin/python
|
8452.3.3
by Karl Fogel
* utilities/: Add copyright header block to source files that were |
2 |
#
|
8687.15.2
by Karl Fogel
In files modified by r8688, change "<YEARS>" to "2009", as per |
3 |
# Copyright 2009 Canonical Ltd. This software is licensed under the
|
8687.15.3
by Karl Fogel
Shorten the copyright header block to two lines. |
4 |
# GNU Affero General Public License version 3 (see the file LICENSE).
|
8452.3.3
by Karl Fogel
* utilities/: Add copyright header block to source files that were |
5 |
#
|
1716.1.203
by Christian Reis
Add a utility that parses the launchpad server logs and returns a report of the top errors |
6 |
# parselogs.py
|
7 |
# Christian Reis <kiko@async.com.br>
|
|
8 |
#
|
|
9 |
# Parses Launchpad error logs and returns a list of most frequent errors
|
|
10 |
||
14612.2.6
by William Grant
utilities |
11 |
import datetime |
12 |
import pprint |
|
1716.1.203
by Christian Reis
Add a utility that parses the launchpad server logs and returns a report of the top errors |
13 |
import re |
14 |
import sys |
|
15 |
import time |
|
14612.2.6
by William Grant
utilities |
16 |
|
1716.1.203
by Christian Reis
Add a utility that parses the launchpad server logs and returns a report of the top errors |
17 |
|
18 |
COUNT = 10 |
|
19 |
LAST_DAYS = 7 |
|
20 |
||
21 |
def init_or_set(d, v): |
|
22 |
if d.has_key(v): |
|
23 |
d[v] += 1 |
|
24 |
else: |
|
25 |
d[v] = 1 |
|
26 |
||
27 |
def init_list_or_set(d, v, e): |
|
28 |
if d.has_key(v): |
|
29 |
d[v][e] = 1 |
|
30 |
else: |
|
31 |
d[v] = {e: 1} |
|
32 |
||
33 |
if len(sys.argv) == 1: |
|
34 |
lognames = ["launchpad1.log", "launchpad2.log"] |
|
35 |
else: |
|
36 |
lognames = sys.argv[1:] |
|
37 |
||
38 |
exceptions = {} |
|
39 |
expired = {} |
|
40 |
url_table = {} |
|
41 |
||
42 |
now = datetime.datetime.fromtimestamp(time.time()) |
|
43 |
for logname in lognames: |
|
44 |
text = open(logname).read() |
|
45 |
errors = text.split("------") |
|
46 |
for error in errors: |
|
47 |
error = error.strip() |
|
48 |
if not error: |
|
49 |
continue
|
|
50 |
||
51 |
fullerror = error |
|
52 |
error = error.split("\n")[-1].strip() |
|
53 |
first_line = fullerror.split("\n")[0] |
|
54 |
||
55 |
date = first_line.split(" ")[0] |
|
4664.1.1
by Curtis Hovey
Normalized comments for bug 3732. |
56 |
# XXX kiko 2005-10-17: handle timezone properly; it kinda sucks that
|
57 |
# we have no way of knowing what timezone the log originates from.
|
|
58 |
# For now I hack around this by assuming timezone is UTC.
|
|
1716.1.203
by Christian Reis
Add a utility that parses the launchpad server logs and returns a report of the top errors |
59 |
ts = time.strftime("%s", time.strptime(date, "%Y-%m-%dT%H:%M:%S")) |
60 |
then = datetime.datetime.fromtimestamp(float(ts)) |
|
61 |
if now - then > datetime.timedelta(days=LAST_DAYS): |
|
62 |
continue
|
|
63 |
||
64 |
if " WARNING " in error: |
|
65 |
continue
|
|
66 |
extra = " ".join(first_line.split()[3:]) |
|
67 |
if "RequestExpired:" in error: |
|
68 |
error = "RequestExpired: %s" % extra |
|
69 |
init_or_set(expired, error) |
|
70 |
continue
|
|
71 |
if re.search("0x[abcdef0-9]+", error): |
|
72 |
error = re.sub("0x[abcdef0-9]+", "INSTANCE-ID", error) |
|
73 |
init_or_set(exceptions, error) |
|
74 |
init_list_or_set(url_table, error, extra) |
|
75 |
||
76 |
values = exceptions.items() |
|
77 |
values.sort(key=lambda x: x[1], reverse=True) |
|
78 |
||
79 |
print
|
|
80 |
print "=== Top %d exceptions in the past %d days ===" % (COUNT, LAST_DAYS) |
|
81 |
print
|
|
82 |
for exc, count in values[:COUNT]: |
|
83 |
print count, "\t", exc |
|
84 |
print "\t\t", "\n\t\t".join(url_table[exc].keys()[:10]) |
|
85 |
||
86 |
values = expired.items() |
|
87 |
values.sort(key=lambda x: x[1], reverse=True) |
|
88 |
||
89 |
print
|
|
90 |
print
|
|
91 |
print "=== Top %d timed out pages in the past %d days ===" % (COUNT, LAST_DAYS) |
|
92 |
print
|
|
93 |
for url, count in values[:COUNT]: |
|
94 |
print count, "\t", url |
|
95 |
||
96 |