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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
#!/usr/bin/python
import os
import sys
import tempfile
import log_picker.archiving as archiving
from log_picker.archiving import ArchivationError
from log_picker.archiving import NoFilesArchivationError
import log_picker.sending as sending
from log_picker.sending import SenderError
import log_picker.logmining as logmining
from log_picker.logmining import LogMinerError
class LogPickerError(Exception):
pass
class LogPicker(object):
def __init__(self, archive_obj=None, sender_obj=None, miners=[],
use_one_file=False):
self.sender_obj = sender_obj
self.archive_obj = archive_obj
self.miners = miners
self.archive = None
self.tmpdir = None
self.files = []
self.filename = self._get_tmp_file("completelog") if use_one_file else None
def _errprint(self, msg):
"""Print message on stderr."""
sys.stderr.write('%s\n' % msg)
def _get_tmp_file(self, name, suffix="", register=True):
"""Create temp file."""
if not self.tmpdir:
self.tmpdir = tempfile.mkdtemp(prefix="lp-logs-", dir="/tmp")
name += suffix
filename = os.path.join(self.tmpdir, name)
open(filename, 'w') # Create empty file
if register:
self.files.append(filename)
return filename
def create_archive(self, name=""):
"""Create archive (one file) containing multiple log files."""
name = name or self.tmpdir or "logs"
self.archive = self._get_tmp_file(name,
suffix=self.archive_obj.file_ext, register=False)
try:
self.archive_obj.create_archive(self.archive, self.files)
except (ArchivationError):
os.remove(self.archive)
raise
def send(self):
"""Send log/archive with logs via sender object."""
if not len(self.files):
return
if not self.archive and len(self.files) > 1:
raise LogPickerError('More than one file to send. ' + \
'You have to create archive. Use create_archive() method.')
file = self.files[0]
contenttype = "text/plain"
if self.archive:
file = self.archive
contenttype = self.archive_obj.mimetype
self.sender_obj.sendfile(file, contenttype)
def getlogs(self):
"""Collect logs generated by miners passed to the constructor."""
# self.filename != None means that we should put all logs into one file.
# self.filename == None means that every log should have its own file.
if self.filename:
f = open(self.filename, 'w')
for miner in self.miners:
if not self.filename:
tmpfilename = self._get_tmp_file(miner.get_filename())
f = open(tmpfilename, 'w')
desc = "%s\n\n" % (miner.get_description())
f.write(desc)
try:
miner.set_logfile(f)
miner.getlog()
except (LogMinerError) as e:
self._errprint("Warning: %s - %s" % (miner._name, e))
f.write("\n%s\n\n\n" % e)
if not self.filename:
f.close()
# XXX Cut our anaconda dump into pieces.
if isinstance(miner, logmining.AnacondaLogMiner):
self._cut_to_pieces(tmpfilename)
if self.filename:
f.close()
def _cut_to_pieces(self, filename):
"""Create multiple log files from Anaconda dump.
Attention: Anaconda dump file on input will be used and overwritten!
@filename file with Anaconda dump"""
actual_file = os.path.basename(filename)
files = {actual_file: []}
empty_lines = 0
# Split file into memmory
for line in open(filename):
striped = line.strip()
if not striped:
empty_lines += 1
elif empty_lines > 1 and striped.startswith('/') \
and striped.endswith(':') and len(line) > 2:
actual_file = striped[:-1].rsplit('/', 1)[-1]#.replace('.', '-')
files[actual_file] = []
empty_lines = 0
files[actual_file].append(line)
# Overwrite original file
actual_file = os.path.basename(filename)
open(filename, 'w').writelines(files[actual_file])
del files[actual_file]
# Write other individual files
for file in files:
open(self._get_tmp_file(file), 'w').writelines(files[file])
|