Last active
February 25, 2023 12:38
-
-
Save victory-sokolov/349501793037c150f37f520b5cb2fe22 to your computer and use it in GitHub Desktop.
Python logger class
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from functools import wraps, partial | |
import logging | |
def attach_wrapper(obj, func=None): # Helper function that attaches function as attribute of an object | |
if func is None: | |
return partial(attach_wrapper, obj) | |
setattr(obj, func.__name__, func) | |
return func | |
def log(level, message): # Actual decorator | |
def decorate(func): | |
logger = logging.getLogger(func.__module__) # Setup logger | |
formatter = logging.Formatter( | |
'%(asctime)s - %(name)s - %(levelname)s - %(message)s') | |
handler = logging.StreamHandler() | |
handler.setFormatter(formatter) | |
logger.addHandler(handler) | |
log_message = f"{func.__name__} - {message}" | |
@wraps(func) | |
def wrapper(*args, **kwargs): # Logs the message and before executing the decorated function | |
logger.log(level, log_message) | |
return func(*args, **kwargs) | |
@attach_wrapper(wrapper) # Attaches "set_level" to "wrapper" as attribute | |
def set_level(new_level): # Function that allows us to set log level | |
nonlocal level | |
level = new_level | |
@attach_wrapper(wrapper) # Attaches "set_message" to "wrapper" as attribute | |
def set_message(new_message): # Function that allows us to set message | |
nonlocal log_message | |
log_message = f"{func.__name__} - {new_message}" | |
return wrapper | |
return decorate | |
# Example Usage | |
@log(logging.WARN, "example-param") | |
def somefunc(args): | |
return args | |
somefunc("some args") | |
somefunc.set_level(logging.CRITICAL) # Change log level by accessing internal decorator function | |
somefunc.set_message("new-message") # Change log message by accessing internal decorator function | |
somefunc("some args") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import yaml | |
from logging import config | |
with open("config.yaml", 'rt') as f: | |
config_data = yaml.safe_load(f.read()) | |
config.dictConfig(config_data) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import logging | |
class CustomFormatter(logging.Formatter): | |
grey = "\x1b[38;20m" | |
yellow = "\x1b[33;20m" | |
red = "\x1b[31;20m" | |
bold_red = "\x1b[31;1m" | |
reset = "\x1b[0m" | |
format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" | |
FORMATS = { | |
logging.DEBUG: grey + format + reset, | |
logging.INFO: grey + format + reset, | |
logging.WARNING: yellow + format + reset, | |
logging.ERROR: red + format + reset, | |
logging.CRITICAL: bold_red + format + reset | |
} | |
def format(self, record): | |
log_fmt = self.FORMATS.get(record.levelno) | |
formatter = logging.Formatter(log_fmt) | |
return formatter.format(record) | |
class Logger: | |
LOG_FORMAT = "%(levelname)s[%(asctime)s][%(pathname)s][%(threadName)s][%(processName)s][%(funcName)s:%(lineno)d]\n%(message)s" | |
def get_logger_config(self, filename): | |
logging.basicConfig( | |
filename=filename, | |
level=logging.DEBUG, | |
format=self.LOG_FORMAT | |
) | |
ch = logging.StreamHandler() | |
ch.setLevel(logging.DEBUG) | |
ch.setFormatter(CustomFormatter()) | |
logger = logging.getLogger() | |
logger.addHandler(ch) | |
return logger | |
log = Logger().get_logger_config("loggs.log") | |
log.info("New Message") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
version: 1 | |
disable_existing_loggers: true | |
formatters: | |
standard: | |
format: "[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s" | |
datefmt: '%H:%M:%S' | |
handlers: | |
console: # handler which will log into stdout | |
class: logging.StreamHandler | |
level: DEBUG | |
formatter: standard # Use formatter defined above | |
stream: ext://sys.stdout | |
file: # handler which will log into file | |
class: logging.handlers.RotatingFileHandler | |
level: WARNING | |
formatter: standard # Use formatter defined above | |
filename: /tmp/warnings.log | |
maxBytes: 10485760 # 10MB | |
backupCount: 10 | |
encoding: utf8 | |
root: # Loggers are organized in hierarchy - this is the root logger config | |
level: ERROR | |
handlers: [console, file] # Attaches both handler defined above | |
loggers: # Defines descendants of root logger | |
mymodule: # Logger for "mymodule" | |
level: INFO | |
handlers: [file] # Will only use "file" handler defined above | |
propagate: no # Will not propagate logs to "root" logger |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment