-
Notifications
You must be signed in to change notification settings - Fork 7
/
log.py
171 lines (157 loc) · 4.7 KB
/
log.py
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
"""Easily set up logging."""
import os
import logging
from logging.handlers import (
RotatingFileHandler,
TimedRotatingFileHandler,
WatchedFileHandler,
)
FORMAT = "%(asctime)s %(levelname)s %(message)s"
def setup_log(
name=None,
path="logs",
rotating=True,
backups=3,
file_mode="a",
disk_level=logging.DEBUG,
screen_level=logging.INFO,
encoding="utf-8",
):
"""This logs to screen if ``screen_level`` is not None, and logs to
disk if ``disk_level`` is not None.
If you do not pass a log ``name``, the root log is configured and
returned.
If ``rotating`` is True, a RotatingFileHandler is configured on the
directory passed as ``path``.
If ``rotating`` is False, a single log file will be created at ``path``.
Its ``file_mode`` defaults to `a` (append), but you can set it to `w`.
"""
# If strings are passed in as levels, "decode" them first
levels = dict(
debug=logging.DEBUG, # 10
info=logging.INFO, # 20
warn=logging.WARN,
warning=logging.WARNING, # 30
error=logging.ERROR, # 40
critical=logging.CRITICAL,
fatal=logging.FATAL, # 50
)
if isinstance(disk_level, str):
disk_level = levels[disk_level.lower()]
if isinstance(screen_level, str):
screen_level = levels[screen_level.lower()]
# Set up logging
log = logging.getLogger(name)
if screen_level:
h1 = logging.StreamHandler()
h1.setLevel(screen_level)
log.addHandler(h1)
if disk_level:
if rotating:
try:
os.mkdir(path)
except OSError:
pass
h2 = RotatingFileHandler(
os.path.join(path, name or "root" + ".log.txt"),
encoding=encoding,
maxBytes=2 ** 22,
backupCount=backups,
)
else:
h2 = WatchedFileHandler(path, mode=file_mode, encoding=encoding)
h2.setLevel(disk_level)
log.setLevel(disk_level)
log.addHandler(h2)
return log
def setup_rotating_logger(
logger=None,
backups=4,
size=250000000,
level=logging.DEBUG,
encoding="utf-8",
format=FORMAT,
directory=".",
):
"""You may pass either a name or an existing logger as the first argument.
This attaches a RotatingFileHandler to the specified logger.
Returns the logger object.
"""
if isinstance(logger, str):
filename = ".".join((logger, encoding, "log"))
logger = logging.getLogger(logger)
else:
filename = ".".join((logger.name, encoding, "log"))
hr = RotatingFileHandler(
os.path.join(directory, filename),
maxBytes=size,
backupCount=backups,
encoding=encoding,
)
if format:
hr.setFormatter(logging.Formatter(format))
logger.addHandler(hr)
logger.setLevel(level)
return logger
def setup_timed_rotating_logger(
logger=None,
level=logging.DEBUG,
backups=14,
when="D",
interval=1,
utc=True,
delay=False,
encoding="utf-8",
format=FORMAT,
directory=".",
):
"""You may pass either a name or an existing logger as the first argument.
This attaches a TimedRotatingFileHandler to the specified logger.
Returns the logger object.
"""
if isinstance(logger, str):
filename = ".".join((logger, encoding, "log"))
logger = logging.getLogger(logger)
else:
filename = ".".join((logger.name, encoding, "log"))
hr = TimedRotatingFileHandler(
os.path.join(directory, filename),
utc=utc,
encoding=encoding,
when=when,
interval=interval,
backupCount=backups,
delay=delay,
)
if format:
hr.setFormatter(logging.Formatter(format))
logger.addHandler(hr)
logger.setLevel(level)
return logger
def setup_watched_file_handler(
logger=None,
level=logging.DEBUG,
format=FORMAT,
encoding="utf-8",
delay=False,
directory=".",
):
"""You may pass either a name or an existing logger as the first argument.
This attaches a WatchedFileHandler to the specified logger.
Returns the logger object.
The WatchedFileHandler detects when the log file is moved, so it is
compatible with the logrotate daemon.
"""
if isinstance(logger, str):
filename = ".".join((logger, encoding, "log"))
logger = logging.getLogger(logger)
else:
filename = ".".join((logger.name, encoding, "log"))
hr = WatchedFileHandler(
os.path.join(directory, filename), delay=delay, encoding=encoding
)
if format:
hr.setFormatter(logging.Formatter(format))
logger.addHandler(hr)
logger.setLevel(level)
return logger