Skip to content

Instantly share code, notes, and snippets.

@binarybrat
Created December 22, 2023 03:23
Show Gist options
  • Save binarybrat/41da33c43a75d08ac5fe340479b670b6 to your computer and use it in GitHub Desktop.
Save binarybrat/41da33c43a75d08ac5fe340479b670b6 to your computer and use it in GitHub Desktop.
Current logging setup file
import cfg
import error
import dbsrc
# Each of these below hell everything in dbsrc also should be logged.
from dbsrc import cmmentmodel, colorinfomodel, modlgmodel, mentionmodel, postmodel, snapshotmodel
import filetils
iport fmtutils
import logutils
from logutils import rainbowlogger
import reddtutils
# Usually logName is 'all'
log = rainbowlogger.set_logger(fileutils.get_filePath(__file__, "all"))
import os
import sys
import traceback
import colorama
import logging
import logging.handlers
from logging.handlers import RotatingFileHandler
from random import choice as rc
from random import sample as rsamp
import cfg
from fmtutils import smlformat
from logutils import set_prettyLogger
from fileutils import get_pathFileName
plog = set_prettyLogger()
smlAnsiList = rsamp(cfg.ansiColorList, 20)
# Simple prin function that mocs certain log outtputs
#I want to be able to use this in other modules, but I don't want to have to pass the logger around
def set_logger(ldir=None, lname=None, silent=False):
"""
This function sets up the logger. It takes two optional arguments, ldir and lname.
I have other arguments but am right now running this bare bones.
:param ldir: This is the log directory. It is set in the cfg file, or manually passed in.
:param lname: This is the log name. It is set in the cfg file, or manually passed in.
:param silent: Whether or nt to give output to the terminal.
:return: logging.Lgger object
"""
# this looks at my cfg file (currently .py file until I work on my dataclasses config stuff
# and sets the log directory based on the cfg file
logDir = cfg.LOG_DIR + ldir if not cfg.TESTING else cfg.TEST_LOG_DIR + ldir
tlogDir = cfg.TEST_LOG_DIR
LOGDIR = logDir if not cfg.TESTING else tlogDir
if not os.path.isdir(LOGDIR):
# Ansi mocks the color class of the logger.
plog.Ansi(f"Log directory does not exist: {LOGDIR} - creating it now.")
os.mkdir(LOGDIR)
plog.Ansi(f"Created new log directory: {os.path.isdir}")
if lname is None:
lname = get_pathFileName(__file__) # this ensures that the name is the actual file name
# I hate having weird logfile names so if I am in the terminal I want it to go to a file called terminal
if lname == "<input>":
lname = "terminal"
logName = lname
logFile = os.path.join(LOGDIR, f"{logName}.log")
if not os.path.isfile(logFile):
# Is this the right way to do this? I was using `w` but then once I connected this project
# with hithub it stopped seeing the log file no matter what I dod so I switched to this.
with open(logFile, "x"):
pass
if cfg.TESTING:
plog.Ansi(f"Created new log file: {logFile}")
plog.Ansi(f"Log File Exists: {os.path.isfile(logFile)}")
logger = logging.getLogger(logName)
if logger.hasHandlers():
logger.handlers.clear()
logger.setLevel(logging.DEBUG)
# I snagged this from somewhere years ago and I don't remember where. I think it was from a 'colorful logging' tutorial.
class UpperThresholdFilter(logging.Filter):
def __init__(self, threshold, *args, **kwargs):
self._threshold = threshold
super(UpperThresholdFilter, self).__init__(*args, **kwargs)
def filter(self, rec):
return rec.levelno <= self._threshold
# This is the same as the above. I think I got it from the same place. Can I pull these out of this function or does it need to be written this way?
class ColorFormatter(logging.Formatter):
def __init__(self, colorfmt, *args, **kwargs):
self._colorfmt = colorfmt
super(ColorFormatter, self).__init__(*args, **kwargs)
def format(self, record):
if record.levelno == logging.INFO:
# This little bit changes the info from teal to random.
# The color ansi output is from a list of ansi colors I have in my cfg file from colors that are good on my eyes.
color = rc(smlAnsiList)
# color = colorama.Fore.CYAN
elif record.levelno == logging.WARNING:
color = colorama.Fore.YELLOW
elif record.levelno == logging.ERROR:
color = colorama.Fore.RED
elif record.levelno == logging.DEBUG:
color = colorama.Fore.LIGHTBLUE_EX
else:
color = ""
self._style._fmt = self._colorfmt.format(color, colorama.Style.RESET_ALL)
return logging.Formatter.format(self, record)
# My various log formats I have mo but even having these two would be helful
# There are 2 other formats I want to also add in here and add log level for - eventually.
logfmt = "[{}%(asctime)s %(levelname)s %(funcName)s{}] %(message)s"
issuefmt = '{}[%(asctime)s] [%(levelname)s] [%(color_term)s:%(funcName)s] [%(filename)s:%(lineno)d]{} %(message)s'
pthfmt = "%(asctime)s - %(levelname)s - %(message)s - %(pathname)s"
dtfmt = smlformat
dtfmt2 = "%Y-%m-%d %H:%M:%S"
formatter = ColorFormatter(logfmt, datefmt=dtfmt)
issueformatter = ColorFormatter(issuefmt, datefmt=dtfmt)
# Stdout handler
stdouthandler = logging.StreamHandler(sys.stdout)
stdouthandler.setLevel(logging.DEBUG)
stdouthandler.addFilter(UpperThresholdFilter(logging.INFO))
stdouthandler.setFormatter(formatter)
if stdouthandler not in logger.handlers:
logger.addHandler(stdouthandler)
# Stderr handler
stderrhandler = logging.StreamHandler(sys.stderr)
stderrhandler.setLevel(logging.WARNING)
stderrhandler.setFormatter(issueformatter)
if stderrhandler not in logger.handlers:
logger.addHandler(stderrhandler)
# Setup main filehandler
filehandler = RotatingFileHandler(logFile, maxBytes=1024 * 1024 * 100, backupCount=10)
filehandler.setLevel(logging.DEBUG)
filehandler.setFormatter(logging.Formatter(logfmt.format("", "")))
if filehandler not in logger.handlers:
logger.addHandler(filehandler)
# I usually have a warninghandler as well but it is removed right now.
# Setup error file handler
errorFile = os.path.join(LOGDIR, f"{logName}.error.log")
if not os.path.isfile(errorFile):
with open(errorFile, "x"):
pass
if not silent:
plog.Ansi(f"Created error file: {errorFile}")
plog.Ansi(f"Error File Exists: {os.path.isfile(errorFile)}")
eh = RotatingFileHandler(errorFile, maxBytes=1024 * 1024 * 100, backupCount=10)
eh.setLevel(logging.ERROR)
eh.setFormatter(logging.Formatter(issuefmt.format("", "")))
if eh not in logger.handlers:
logger.addHandler(eh)
return logger
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment