-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathMultiprocessHandler.py
More file actions
105 lines (93 loc) · 3.18 KB
/
MultiprocessHandler.py
File metadata and controls
105 lines (93 loc) · 3.18 KB
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
# coding=utf-8
import datetime
import logging
import os
import re
try:
import codecs
except ImportError:
codecs = None
class MultiprocessHandler(logging.FileHandler):
def __init__(self, filename, when='D', backupCount=0, encoding=None, delay=False):
self.prefix = filename
self.backupCount = backupCount
self.when = when.upper()
self.extMath = r"^\d{4}-\d{2}-\d{2}"
self.when_dict = {
'S': "%Y-%m-%d-%H-%M-%S",
'M': "%Y-%m-%d-%H-%M",
'H': "%Y-%m-%d-%H",
'D': "%Y-%m-%d"
}
self.suffix = self.when_dict.get(when)
if not self.suffix:
raise ValueError("Invalid rollover interval specified: %s" % self.when)
self.filefmt = os.path.join("logs", "%s.%s" % (self.prefix, self.suffix))
self.filePath = datetime.datetime.now().strftime(self.filefmt)
_dir = os.path.dirname(self.filefmt)
try:
if not os.path.exists(_dir):
os.makedirs(_dir)
except Exception:
raise
if codecs is None:
encoding = None
logging.FileHandler.__init__(self, self.filePath, 'a+', encoding, delay)
def shouldChangeFileToWrite(self):
_filePath = datetime.datetime.now().strftime(self.filefmt)
if _filePath != self.filePath:
self.filePath = _filePath
return True
return False
def doChangeFile(self):
self.baseFilename = os.path.abspath(self.filePath)
if self.stream:
self.stream.close()
self.stream = None
if not self.delay:
self.stream = self._open()
if self.backupCount > 0:
for s in self.getFilesToDelete():
os.remove(s)
def _open(self):
if self.encoding is None:
stream = open(self.baseFilename, self.mode)
else:
stream = codecs.open(self.baseFilename, self.mode, self.encoding)
if os.path.exists(self.prefix):
try:
os.remove(self.prefix)
except OSError:
pass
try:
os.symlink(self.baseFilename, self.prefix)
except OSError:
pass
return stream
def getFilesToDelete(self):
dirName, _ = os.path.split(self.baseFilename)
fileNames = os.listdir(dirName)
result = []
prefix = self.prefix + '.'
plen = len(prefix)
for fileName in fileNames:
fileName = dirName + "/" + fileName
if fileName[:plen] == prefix:
suffix = fileName[plen:]
if re.compile(self.extMath).match(suffix):
result.append(os.path.join(dirName, fileName))
result.sort()
if len(result) < self.backupCount:
result = []
else:
result = result[:len(result) - self.backupCount]
return result
def emit(self, record):
try:
if self.shouldChangeFileToWrite():
self.doChangeFile()
logging.FileHandler.emit(self, record)
except (KeyboardInterrupt, SystemExit):
raise
except:
self.handleError(record)