-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlogger.py
More file actions
executable file
·194 lines (165 loc) · 7.23 KB
/
logger.py
File metadata and controls
executable file
·194 lines (165 loc) · 7.23 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
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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#!/usr/bin/python3
# -*- coding: utf-8 -*-
""""
This module makes logging easy and fun! If no arguments are given to
startLog it will create a log in the working directory ('.') and
name it using the main script name ('mainScript.log')
This has been updated to an object for multiprocessing support
loggerLegacy still exists for legacy support
Useage:
to start your log: from logger import log # makes the logs global
log.setLevel('INFO') # Set the logging level
use a log in a sub: from logger import log
log.out.info('Starting a log for Kenny Loggins.')
to release logs: log.stopLog()
to make another global log, such as for a data ouput:
dataLog = logger.logObject(fileName = "data_density.csv",
header = "messageOnly", onConsole = False)
@author: Brad Beechler (brad.beechler@uptake.com)
# Last Modification: 01/27/2017 (Brad Beechler)
"""
import logging
import os
import sys
import errno
from shutil import copyfile
import __main__
class LogObject:
out = None
filePath = None
fileName = None
fileFullName = None
header = None
onConsole = None
onFile = None
def __init__(self, filePath=None, fileName=None, header=None, onConsole=True, onFile=True):
"""
Initialize log object.
"""
self.out = None
self.fileFullName = None
self.filePath = filePath
self.fileName = fileName
self.header = header
self.onConsole = onConsole
self.onFile = onFile
self.startLog(filePath=self.filePath, fileName=self.fileName, header=self.header, \
onConsole=self.onConsole, onFile=self.onFile)
def startLog(self, filePath=None, fileName=None, header=None, onConsole=True, onFile=True):
"""
Initialize log file with optional path and optional file name.
Parameters:
filePath - where you want the log file
fileName - what you want it called
header - to specify the header style options are:
"" - <time><level><functionName><message>
"simple" - <level><message>
"message_only" - just the message
"no_time" - remove time
"<custom header>" - enter your own format
onConsole - set true for console output
"""
self.header = header
self.onConsole = onConsole
self.onFile = onFile
# Create Global Logger
self.out = logging.getLogger(str(__main__.__file__)+'_globalLogger')
# Set Logger Level
self.out.setLevel(logging.DEBUG)
# Establish Logger
self.out.handlers = [] # clear old handlers
# create formatter and add to handlers
if self.header is None:
formatter = logging.Formatter("%(asctime)s;%(levelname)s;%(funcName)20s();%(message)s")
elif self.header == "message_only":
formatter = logging.Formatter("%(message)s")
elif self.header == "simple":
formatter = logging.Formatter("%(levelname)s;%(message)s")
elif self.header == "no_time":
formatter = logging.Formatter("%(levelname)s;%(funcName)20s();%(message)s")
else:
formatter = self.header
if self.onFile:
if filePath is None:
self.filePath = os.getcwd()
else:
self.filePath = filePath
mainFileName = os.path.splitext(os.path.basename(__main__.__file__))[0]
if fileName is None:
# If not provided, the fileName is set to the top level file calling the global logger.
self.fileName = mainFileName + '.log'
else:
self.fileName = fileName
if os.access(self.filePath, os.W_OK):
self.fileFullName = os.path.join(self.filePath,self.fileName)
flags = os.O_CREAT | os.O_EXCL | os.O_WRONLY
try: #checks if a file is there, if not initialize it (from StackO)
os.open(self.fileFullName, flags)
except OSError as e:
if e.errno == errno.EEXIST: # Failed as the file already exists.
pass
else: # Something unexpected went wrong so reraise the exception.
raise
else: # No exception, so the file must have been created successfully.
with open(self.fileFullName, 'w') as file_obj:
file_obj.write(mainFileName + ' Log File\n')
else:
sys.exit('ERROR! Path specified not able to be written to!')
# create console and file handler and set level to debug
file_handle = logging.FileHandler(self.fileFullName)
file_handle.setLevel(logging.DEBUG)
file_handle.setFormatter(formatter)
self.out.addHandler(file_handle)
if self.onConsole:
# Make a handler to deal with warnings and above --> stderr
error_handle = logging.StreamHandler(sys.stderr)
error_handle.setLevel(logging.WARNING)
error_handle.setFormatter(formatter)
self.out.addHandler(error_handle)
# Make a handler to deal with all --> stdout
standard_handle = logging.StreamHandler(sys.stdout)
standard_handle.setLevel(logging.DEBUG)
standard_handle.setFormatter(formatter)
self.out.addHandler(standard_handle)
def stopLog(self):
"""
Release logging handlers.
"""
self.out.handlers = []
def setLevel(self,level_tag):
"""
Sets the logging level
levelStr (str) - a string describing the desired logging level
'INFO', 'DEBUG', 'WARNING', also 'NOTSET'
"""
self.out.setLevel(logging.getLevelName(level_tag))
def changeFileName(self, new_name, header=None, onConsole=True, onFile=True):
"""
Change the name of the log
new_name
header (str) - A string describing the type of header information you
want with the logs passed to startLog: 'simple',
'message_only', 'no_time', <custom header>
(see startLog for more details on formatting)
onConsole (bool) - True if you want logs written to the console
onFile (bool) - True if you want the log written to the file
"""
# Get rid of tildas
new_name = os.path.expanduser(new_name)
# Check if name is okay
# Copy old log to new name
new_path, new_filename = os.path.split(new_name)
if new_path == '':
new_path = self.filePath
new_fileFullName = os.path.join(new_path, new_filename)
if os.access(new_path, os.W_OK):
self.out.handlers = [] # clear old handlers
if self.onFile:
copyfile(self.fileFullName, new_fileFullName)
os.remove(self.fileFullName)
self.startLog(filePath=new_path, fileName=new_filename, header=header,
onConsole=onConsole, onFile=onFile)
else:
log.out.warning("No permissions to write new log name")
# Make a global log object to share
log = LogObject()