Skip to content

Instantly share code, notes, and snippets.

@victory-sokolov
Last active February 25, 2023 12:38
Show Gist options
  • Save victory-sokolov/349501793037c150f37f520b5cb2fe22 to your computer and use it in GitHub Desktop.
Save victory-sokolov/349501793037c150f37f520b5cb2fe22 to your computer and use it in GitHub Desktop.
Python logger class
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")
import yaml
from logging import config
with open("config.yaml", 'rt') as f:
config_data = yaml.safe_load(f.read())
config.dictConfig(config_data)
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")
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