Log Config¶
This config script sets up the logging and structlog modules for message logging to
console and file. It simply needs to be imported into any module where logging is needed.
In order to capture exceptions and crashes main() should be in a try/except block.
Usage:
if __name__ == '__main__':
from utils import log_config
log = log_config.log(log_level='INFO')
log.info(f"Example info text {[1, 2, 3]}", example_key=[1, 2, 3])
try:
main()
except Exception as err:
log.exception("Example crashed", exception=err)
- notes:
Setting up structlog is very tricky, but after it is done it should just work (or so they promise). Regardless, the comments herein should help explain how this works should we ever need to update it.
See documentation. https://docs.python.org/3/library/logging.handlers.html#timedrotatingfilehandler https://www.structlog.org/en/stable/standard-library.html https://www.structlog.org/en/stable/processors.html#chains
- class src.utils.log_config.VerboseLogger[source]¶
Bases:
BoundLoggerWrapper class that adds a new logging method
verbosebetweendebugandinfolevels.
- src.utils.log_config.add_logging_level(level_name, level_num, method_name=None)[source]¶
Modified from https://stackoverflow.com/a/35804945
Comprehensively adds a new logging level to the
loggingmodule and the currently configured logging class.levelNamebecomes an attribute of theloggingmodule with the valuelevelNum.methodNamebecomes a convenience method for bothloggingitself and the class returned bylogging.getLoggerClass()(usually justlogging.Logger). IfmethodNameis not specified,levelName.lower()is used.To avoid accidental clobberings of existing attributes, this method will raise an
AttributeErrorif the level name is already an attribute of theloggingmodule or if the method name is already presentExample¶
>>> add_logging_level('TRACE', logging.DEBUG - 5) >>> logging.getLogger(__name__).setLevel("TRACE") >>> logging.getLogger(__name__).trace('that worked') >>> logging.trace('so did this') >>> logging.TRACE 5
- src.utils.log_config.format_floats(_, __, event_dict)[source]¶
Truncate all floating-point fields to three decimal places.
This is done only for
ConsoleRendererto reduce the size of logs in the screen when running the radar.
- src.utils.log_config.log(
- console_log_level=None,
- logfile_log_level=None,
- aggregator_log_level=None,
- console=None,
- logfile=None,
- aggregator=None,
- json_to_console=False,
- Parameters:
console_log_level (str | int) – Logging threshold for console renderer [CRITICAL, ERROR, WARNING, INFO, VERBOSE, DEBUG, NOTSET]
logfile_log_level (str | int) – Logging threshold for logfile renderer [CRITICAL, ERROR, WARNING, INFO, VERBOSE, DEBUG, NOTSET]
aggregator_log_level (str | int) – Logging threshold for aggregator renderer [CRITICAL, ERROR, WARNING, VERBOSE, INFO, DEBUG, NOTSET]
console (bool) – Enable (True) or Disable (False) console logging override
logfile (bool) – Enable (True) or Disable (False) JSON file logging override
aggregator (bool) – Enable (True) or Disable (False) aggregator log forwarding override
json_to_console (bool) – Enable (True) or Disable (False) a logger that converts JSON logs to console-style
Note
There are three parts to logging:
processors,renderers, andhandlers.processors: modify, add, or clean up the log message dictrenderers: make the log message a string, json, dict, etc. with fancy stylinghandlers: print the rendered data to stdout, file, stream, etc.
- src.utils.log_config.swap_logger_name(_, __, event_dict)[source]¶
Swaps the kw
logger_namevalue with themodule_nameandfunc_namevalues then removes them fromevent_dict.This is done to hack
ConsoleRendererto somewhat match our past format. This is intended only to be used for console rendering and not JSON rendering (prints nice but does not appear in file).
- src.utils.log_config.VERBOSE = 15¶
New logging level, set between
DEBUGandINFO.