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 |
||
11 |
import re |
|
12 |
import pprint |
|
13 |
import sys |
|
14 |
import time |
|
15 |
import datetime |
|
16 |
||
17 |
COUNT = 10 |
|
18 |
LAST_DAYS = 7 |
|
19 |
||
20 |
def init_or_set(d, v): |
|
21 |
if d.has_key(v): |
|
22 |
d[v] += 1 |
|
23 |
else: |
|
24 |
d[v] = 1 |
|
25 |
||
26 |
def init_list_or_set(d, v, e): |
|
27 |
if d.has_key(v): |
|
28 |
d[v][e] = 1 |
|
29 |
else: |
|
30 |
d[v] = {e: 1} |
|
31 |
||
32 |
if len(sys.argv) == 1: |
|
33 |
lognames = ["launchpad1.log", "launchpad2.log"] |
|
34 |
else: |
|
35 |
lognames = sys.argv[1:] |
|
36 |
||
37 |
exceptions = {} |
|
38 |
expired = {} |
|
39 |
url_table = {} |
|
40 |
||
41 |
now = datetime.datetime.fromtimestamp(time.time()) |
|
42 |
for logname in lognames: |
|
43 |
text = open(logname).read() |
|
44 |
errors = text.split("------") |
|
45 |
for error in errors: |
|
46 |
error = error.strip() |
|
47 |
if not error: |
|
48 |
continue
|
|
49 |
||
50 |
fullerror = error |
|
51 |
error = error.split("\n")[-1].strip() |
|
52 |
first_line = fullerror.split("\n")[0] |
|
53 |
||
54 |
date = first_line.split(" ")[0] |
|
4664.1.1
by Curtis Hovey
Normalized comments for bug 3732. |
55 |
# XXX kiko 2005-10-17: handle timezone properly; it kinda sucks that
|
56 |
# we have no way of knowing what timezone the log originates from.
|
|
57 |
# 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 |
58 |
ts = time.strftime("%s", time.strptime(date, "%Y-%m-%dT%H:%M:%S")) |
59 |
then = datetime.datetime.fromtimestamp(float(ts)) |
|
60 |
if now - then > datetime.timedelta(days=LAST_DAYS): |
|
61 |
continue
|
|
62 |
||
63 |
if " WARNING " in error: |
|
64 |
continue
|
|
65 |
extra = " ".join(first_line.split()[3:]) |
|
66 |
if "RequestExpired:" in error: |
|
67 |
error = "RequestExpired: %s" % extra |
|
68 |
init_or_set(expired, error) |
|
69 |
continue
|
|
70 |
if re.search("0x[abcdef0-9]+", error): |
|
71 |
error = re.sub("0x[abcdef0-9]+", "INSTANCE-ID", error) |
|
72 |
init_or_set(exceptions, error) |
|
73 |
init_list_or_set(url_table, error, extra) |
|
74 |
||
75 |
values = exceptions.items() |
|
76 |
values.sort(key=lambda x: x[1], reverse=True) |
|
77 |
||
78 |
print
|
|
79 |
print "=== Top %d exceptions in the past %d days ===" % (COUNT, LAST_DAYS) |
|
80 |
print
|
|
81 |
for exc, count in values[:COUNT]: |
|
82 |
print count, "\t", exc |
|
83 |
print "\t\t", "\n\t\t".join(url_table[exc].keys()[:10]) |
|
84 |
||
85 |
values = expired.items() |
|
86 |
values.sort(key=lambda x: x[1], reverse=True) |
|
87 |
||
88 |
print
|
|
89 |
print
|
|
90 |
print "=== Top %d timed out pages in the past %d days ===" % (COUNT, LAST_DAYS) |
|
91 |
print
|
|
92 |
for url, count in values[:COUNT]: |
|
93 |
print count, "\t", url |
|
94 |
||
95 |