1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
from portage.const import EBUILD_PHASES
from portage.exception import PortageException
from portage.process import atexit_register
from portage.util import writemsg
from portage import listdir
import os
_elog_atexit_handlers = []
def elog_process(cpv, mysettings):
mylogfiles = listdir(mysettings["T"]+"/logging/")
# shortcut for packages without any messages
if len(mylogfiles) == 0:
return
# exploit listdir() file order so we process log entries in chronological order
mylogfiles.reverse()
all_logentries = {}
for f in mylogfiles:
msgfunction, msgtype = f.split(".")
if msgfunction not in EBUILD_PHASES:
writemsg("!!! can't process invalid log file: %s\n" % f,
noiselevel=-1)
continue
if not msgfunction in all_logentries:
all_logentries[msgfunction] = []
msgcontent = open(mysettings["T"]+"/logging/"+f, "r").readlines()
all_logentries[msgfunction].append((msgtype, msgcontent))
def filter_loglevels(logentries, loglevels):
# remove unwanted entries from all logentries
rValue = {}
loglevels = map(str.upper, loglevels)
for phase in logentries.keys():
for msgtype, msgcontent in logentries[phase]:
if msgtype.upper() in loglevels or "*" in loglevels:
if not rValue.has_key(phase):
rValue[phase] = []
rValue[phase].append((msgtype, msgcontent))
return rValue
my_elog_classes = set(mysettings.get("PORTAGE_ELOG_CLASSES", "").split())
default_logentries = filter_loglevels(all_logentries, my_elog_classes)
# in case the filters matched all messages and no module overrides exist
if len(default_logentries) == 0 and (not ":" in mysettings.get("PORTAGE_ELOG_SYSTEM", "")):
return
def combine_logentries(logentries):
# generate a single string with all log messages
rValue = ""
for phase in EBUILD_PHASES:
if not phase in logentries:
continue
for msgtype, msgcontent in logentries[phase]:
rValue += "%s: %s\n" % (msgtype, phase)
for line in msgcontent:
rValue += line
rValue += "\n"
return rValue
default_fulllog = combine_logentries(default_logentries)
# pass the processing to the individual modules
logsystems = mysettings["PORTAGE_ELOG_SYSTEM"].split()
for s in logsystems:
# allow per module overrides of PORTAGE_ELOG_CLASSES
if ":" in s:
s, levels = s.split(":", 1)
levels = levels.split(",")
mod_logentries = filter_loglevels(all_logentries, levels)
mod_fulllog = combine_logentries(mod_logentries)
else:
mod_logentries = default_logentries
mod_fulllog = default_fulllog
if len(mod_logentries) == 0:
continue
# - is nicer than _ for module names, so allow people to use it.
s = s.replace("-", "_")
try:
# FIXME: ugly ad.hoc import code
# TODO: implement a common portage module loader
name = "portage.elog.mod_" + s
m = __import__(name)
for comp in name.split(".")[1:]:
m = getattr(m, comp)
def timeout_handler(signum, frame):
raise PortageException("Timeout in elog_process for system '%s'" % s)
import signal
signal.signal(signal.SIGALRM, timeout_handler)
# Timeout after one minute (in case something like the mail
# module gets hung).
signal.alarm(60)
try:
m.process(mysettings, cpv, mod_logentries, mod_fulllog)
finally:
signal.alarm(0)
if hasattr(m, "finalize") and not m.finalize in _elog_atexit_handlers:
_elog_atexit_handlers.append(m.finalize)
atexit_register(m.finalize, mysettings)
except (ImportError, AttributeError), e:
writemsg("!!! Error while importing logging modules " + \
"while loading \"mod_%s\":\n" % str(s))
writemsg("%s\n" % str(e), noiselevel=-1)
except PortageException, e:
writemsg("%s\n" % str(e), noiselevel=-1)
# clean logfiles to avoid repetitions
for f in mylogfiles:
try:
os.unlink(os.path.join(mysettings["T"], "logging", f))
except OSError:
pass
|