147 lines
4.7 KiB
Python
147 lines
4.7 KiB
Python
#!/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])
|
|
|