refs #1834 create additional json log
parent
5c2fbc36e3
commit
a7c5ae4d27
|
@ -34,6 +34,8 @@ import logging
|
||||||
import os
|
import os
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
from ..log_format import JsonFormatter
|
||||||
|
|
||||||
# Logging levels
|
# Logging levels
|
||||||
OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in range(6))
|
OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in range(6))
|
||||||
|
|
||||||
|
@ -48,15 +50,25 @@ class LocalLogger(object):
|
||||||
|
|
||||||
for logDir in ('/var/log', os.path.expanduser('~'), tempfile.gettempdir()):
|
for logDir in ('/var/log', os.path.expanduser('~'), tempfile.gettempdir()):
|
||||||
try:
|
try:
|
||||||
fname = os.path.join(logDir, 'opengnsys.log')
|
fname1 = os.path.join (logDir, 'opengnsys.log')
|
||||||
logging.basicConfig(
|
fmt1 = logging.Formatter (fmt='%(levelname)s %(asctime)s (%(threadName)s) (%(funcName)s) %(message)s')
|
||||||
filename=fname,
|
fh1 = logging.FileHandler (filename=fname1, mode='a')
|
||||||
filemode='a',
|
fh1.setFormatter (fmt1)
|
||||||
format='%(levelname)s %(asctime)s (%(threadName)s) (%(funcName)s) %(message)s',
|
fh1.setLevel (logging.DEBUG)
|
||||||
level=logging.DEBUG
|
|
||||||
)
|
fname2 = os.path.join (logDir, 'opengnsys.json.log')
|
||||||
|
fmt2 = JsonFormatter ({"timestamp": "asctime", "severity": "levelname", "threadName": "threadName", "function": "funcName", "message": "message"}, time_format='%Y-%m-%d %H:%M:%S', msec_format='')
|
||||||
|
fh2 = logging.FileHandler (filename=fname2, mode='a')
|
||||||
|
fh2.setFormatter (fmt2)
|
||||||
|
fh2.setLevel (logging.DEBUG)
|
||||||
|
|
||||||
self.logger = logging.getLogger ('opengnsys')
|
self.logger = logging.getLogger ('opengnsys')
|
||||||
os.chmod(fname, 0o0600)
|
self.logger.setLevel (logging.DEBUG)
|
||||||
|
self.logger.addHandler (fh1)
|
||||||
|
self.logger.addHandler (fh2)
|
||||||
|
|
||||||
|
os.chmod (fname1, 0o0600)
|
||||||
|
os.chmod (fname2, 0o0600)
|
||||||
return
|
return
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
|
||||||
|
class JsonFormatter(logging.Formatter):
|
||||||
|
"""
|
||||||
|
Formatter that outputs JSON strings after parsing the LogRecord.
|
||||||
|
|
||||||
|
@param dict fmt_dict: Key: logging format attribute pairs. Defaults to {"message": "message"}.
|
||||||
|
@param str time_format: time.strftime() format string. Default: "%Y-%m-%dT%H:%M:%S"
|
||||||
|
@param str msec_format: Microsecond formatting. Appended at the end. Default: "%s.%03dZ"
|
||||||
|
"""
|
||||||
|
def __init__(self, fmt_dict: dict = None, time_format: str = "%Y-%m-%dT%H:%M:%S", msec_format: str = "%s.%03dZ"):
|
||||||
|
self.fmt_dict = fmt_dict if fmt_dict is not None else {"message": "message"}
|
||||||
|
self.default_time_format = time_format
|
||||||
|
self.default_msec_format = msec_format
|
||||||
|
self.datefmt = None
|
||||||
|
|
||||||
|
def usesTime(self) -> bool:
|
||||||
|
"""
|
||||||
|
Overwritten to look for the attribute in the format dict values instead of the fmt string.
|
||||||
|
"""
|
||||||
|
return "asctime" in self.fmt_dict.values()
|
||||||
|
|
||||||
|
def formatMessage(self, record) -> dict:
|
||||||
|
"""
|
||||||
|
Overwritten to return a dictionary of the relevant LogRecord attributes instead of a string.
|
||||||
|
KeyError is raised if an unknown attribute is provided in the fmt_dict.
|
||||||
|
"""
|
||||||
|
return {fmt_key: record.__dict__[fmt_val] for fmt_key, fmt_val in self.fmt_dict.items()}
|
||||||
|
|
||||||
|
def format(self, record) -> str:
|
||||||
|
"""
|
||||||
|
Mostly the same as the parent's class method, the difference being that a dict is manipulated and dumped as JSON
|
||||||
|
instead of a string.
|
||||||
|
"""
|
||||||
|
record.message = record.getMessage()
|
||||||
|
|
||||||
|
if self.usesTime():
|
||||||
|
record.asctime = self.formatTime(record, self.datefmt)
|
||||||
|
|
||||||
|
message_dict = self.formatMessage(record)
|
||||||
|
|
||||||
|
if record.exc_info:
|
||||||
|
# Cache the traceback text to avoid converting it multiple times
|
||||||
|
# (it's constant anyway)
|
||||||
|
if not record.exc_text:
|
||||||
|
record.exc_text = self.formatException(record.exc_info)
|
||||||
|
|
||||||
|
if record.exc_text:
|
||||||
|
message_dict["exc_info"] = record.exc_text
|
||||||
|
|
||||||
|
if record.stack_info:
|
||||||
|
message_dict["stack_info"] = self.formatStack(record.stack_info)
|
||||||
|
|
||||||
|
return json.dumps(message_dict, default=str)
|
|
@ -36,6 +36,8 @@ import logging
|
||||||
import os
|
import os
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
from ..log_format import JsonFormatter
|
||||||
|
|
||||||
# Valid logging levels, from UDS Broker (uds.core.utils.log)
|
# Valid logging levels, from UDS Broker (uds.core.utils.log)
|
||||||
OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in range(6))
|
OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in range(6))
|
||||||
|
|
||||||
|
@ -44,13 +46,24 @@ class LocalLogger(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# tempdir is different for "user application" and "service"
|
# tempdir is different for "user application" and "service"
|
||||||
# service wil get c:\windows\temp, while user will get c:\users\XXX\appdata\local\temp
|
# service wil get c:\windows\temp, while user will get c:\users\XXX\appdata\local\temp
|
||||||
logging.basicConfig(
|
|
||||||
filename=os.path.join(tempfile.gettempdir(), 'opengnsys.log'),
|
fname1 = os.path.join (tempfile.gettempdir(), 'opengnsys.log')
|
||||||
filemode='a',
|
fmt1 = logging.Formatter (fmt='%(levelname)s %(asctime)s (%(threadName)s) (%(funcName)s) %(message)s')
|
||||||
format='%(levelname)s %(asctime)s (%(threadName)s) (%(funcName)s) %(message)s',
|
fh1 = logging.FileHandler (filename=fname1, mode='a')
|
||||||
level=logging.DEBUG
|
fh1.setFormatter (fmt1)
|
||||||
)
|
fh1.setLevel (logging.DEBUG)
|
||||||
|
|
||||||
|
fname2 = os.path.join (tempfile.gettempdir(), 'opengnsys.json.log')
|
||||||
|
fmt2 = JsonFormatter ({"timestamp": "asctime", "severity": "levelname", "threadName": "threadName", "function": "funcName", "message": "message"}, time_format='%Y-%m-%d %H:%M:%S', msec_format='')
|
||||||
|
fh2 = logging.FileHandler (filename=fname2, mode='a')
|
||||||
|
fh2.setFormatter (fmt2)
|
||||||
|
fh2.setLevel (logging.DEBUG)
|
||||||
|
|
||||||
self.logger = logging.getLogger('opengnsys')
|
self.logger = logging.getLogger('opengnsys')
|
||||||
|
self.logger.setLevel (logging.DEBUG)
|
||||||
|
self.logger.addHandler (fh1)
|
||||||
|
self.logger.addHandler (fh2)
|
||||||
|
|
||||||
self.serviceLogger = False
|
self.serviceLogger = False
|
||||||
|
|
||||||
def log(self, level, message):
|
def log(self, level, message):
|
||||||
|
|
Loading…
Reference in New Issue