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
|
#coding=utf-8
import datetime
import logging as log
from collections import OrderedDict
import tkinter as tk
from tkinter import ttk
import tkFileDialog as tkfd
class LogWindow(tk.Toplevel):
def __init__(self, *args, **kwargs):
tk.Toplevel.__init__(self, *args, **kwargs)
self.withdraw()
self.protocol('WM_DELETE_WINDOW', self.withdraw)
self.renderContents()
self._records = []
self._counter = -1
self._registerLogging()
def renderContents(self):
columns = [
('level', 'Poziom komunikatu', 150),
('category', 'Moduł', 150),
('message', 'Komunikat', None)]
self.logList = ttk.Treeview(
self, show='headings',
columns=[c[0] for c in columns],
selectmode='browse')
for column, heading, width in columns:
self.logList.heading(column, text=heading)
if width is not None:
self.logList.column(column, width=width, stretch=False)
else:
self.logList.column(column, stretch=True)
self.logList.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
btnFrame = tk.Frame(self)
btnFrame.pack(side=tk.BOTTOM)
(ttk.Button(
btnFrame, text='Zapisz dziennik...',
command=self.onRecordsSave)).pack(side=tk.LEFT)
(ttk.Button(
btnFrame, text='Wyczyść dziennik',
command=self.resetRecords)).pack(side=tk.LEFT)
def _getGUIHandler(self):
return LogHandler(log.INFO, window=self)
def _getConsoleHandler(self):
consoleHandler = log.StreamHandler()
consoleHandler.setFormatter(
log.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
return consoleHandler
def _registerLogging(self):
logger = log.getLogger()
logger.setLevel(log.INFO)
for handler in [self._getConsoleHandler, self._getGUIHandler]:
logger.addHandler(handler())
def addRecord(self, record):
self._counter += 1
self._records.append((record, datetime.datetime.now()))
if not isinstance(record.message, unicode):
record.message = unicode(record.message, errors='replace')
self.logList.insert(
'', tk.END, tag=self._counter, values=[
record.levelname, record.name, record.message
])
self.logList.yview_moveto(1)
def resetRecords(self):
self._records = []
self.logList.delete(*self.logList.get_children())
def onRecordsSave(self, *args):
filename = tkfd.asksaveasfilename(
title='Wybierz plik dziennika',
filetypes=(('Log files', '*.log'),))
if filename:
if not filename.lower().endswith('.log'):
filename = filename + '.log'
self._saveRecords(filename)
def _saveRecords(self, filename):
with open(filename, 'w') as fileObj:
for record, timestamp in self._records:
fileObj.write((
u'%s\t%s\t%s\t%s\n' % (
timestamp,
record.levelname, record.name, record.message)).encode(
'utf8'))
class LogHandler(log.Handler):
def __init__(self, *args, **kwargs):
self._window = kwargs['window']
del kwargs['window']
log.Handler.__init__(self, *args, **kwargs)
def handle(self, record):
self.format(record)
self._window.addRecord(record)
|