Untitled

mail@pastecode.io avatar
unknown
plain_text
a month ago
5.8 kB
3
Indexable
Never
"""
logger.py
Ally Youngblood (ACY)
2023-06-12

This logging module was written to be used by other python scripts to handle both output to the terminal and writing to log files

Usage:

General logging

    logstream.{debug | info | warn | error | crit | log}(message, [logfile], [quiet], [debug])
        logstream   - the name of the logstream to write messages to
        severity    - the severity of the log message can be any of the following:
                      debug - suppressed by default
                              printed if debug = True is passed when calling the logger
                      info  - always printed to console and to logfile if one is defined
                      warn  - always printed to console and to logfile if one is defined
                      error - always printed to console and to logfile if one is defined
                      crit  - always printed to console and to logfile if one is defined
        message     - the message to be written to the log
        logfile     - the absolute or relative location of the logfile to append messages to
                      if not passed, no messages will be logged, only written to the terminal
        quiet       - an optional parameter to log quietly while printing no output to the terminal
                      pass 'quiet = True' to enable
        debug       - an optional parameter to enable debug logging
                      pass 'quiet = True' to enable

Logging secrets

    logstream.secret(message, secret, [logfile], [quiet], [debug])
        logstream   - same as general logging
        message     - same as general logging
                      this will be printed and logged in plaintext
        secret      - secret text
                      will be printed to terminal in plaintext (unless suppressed by 'quiet = True')
                      will be redacted when message is written to logfile if one is defined
        logfile     - same as general logging
        quiet       - same as general logging
        debug       - has no effect when logging severity is not debug

Logging with custom severities

    logstream.log(severity, message, [secret], [logfile], [quiet], [debug])
        logstream   - same as general logging
        severity    - the severity of the log message to be written
                      this can be any string
        message     - same as general logging
        secret      - same as secret logging, but not required with custom severities
        logfile     - same as general logging
        quiet       - same as general logging
        debug       - has no effect when logging severity is not debug

Using this library in your code:

    To use this library, you must first import it and define one or more logstreams you expect to write to.
        from logger import *
        LogA = logger(log_file = './log_a.txt', debug = True) # This logstream writes all messages including debug to both the terminal and log_a.txt
        LogB = logger(log_file = './log_b.txt', quiet = True) # This logstream writes nothing to the terminal and writes all other messages (except debug which is supressed) to log_b.txt
        LogC = logger(debug = True) # This logstream writes all messages only to the terminal and includes debug level messages
    You can define as many different logstreams as you would like, and they can be named anything.
    You may chose to do this to seperate messages for different tasks, send only specific severities to another log, etc.
"""

from datetime import datetime
import __main__

UNFORMATTED = '\033[0m'
FORMAT_MAP = {
    "debug": '\u001b[35m', # magenta
    "warn" : '\u001b[33m', # yellow
    "error": '\u001b[31m', # red, bolded
    "critical": '\u001b[31m',  # red, bolded
}

class logger():

    def __init__(self, log_file = False, quiet = False, debug = False, severity_length = 8, logger_name = __main__.__file__):
        self.log_file = log_file
        self.quiet_enabled = quiet
        self.debug_enabled = debug
        self.severity_length = severity_length
        self._logger_name = logger_name
        if self.log_file:
            self.file = open(log_file, 'a')
            self.info(f"Logging started ({self._logger_name})")

    def __del__(self):
        if self.log_file:
            self.info(f"Logging ended ({self._logger_name})")
            self.file.close()

    def debug(self, message):
        self.log("DEBUG", message)

    def info(self, message):
        self.log("INFO", message)

    def warn(self, message):
        self.log("WARN", message)

    def error(self, message):
        self.log("ERROR", message)
        self.flush()

    def crit(self, message):
        self.log("CRITICAL", message)
        self.flush()

    def secret(self, message, secret):
        self.log("SECRET", message, secret)
        self.flush()

    def flush(self):
        if self.log_file:
            self.file.flush()

    def log(self, severity, message, secret = ""):
        now = str(datetime.now())
        normalized_severity = severity.casefold()
        color = FORMAT_MAP.get(normalized_severity,UNFORMATTED)
        padded_severity = severity.upper().ljust(self.severity_length, ' ')
        if (normalized_severity != "debug" or self.debug_enabled) and not self.quiet_enabled:
            print(f'{now} - {color}{padded_severity} - {message} {secret}{UNFORMATTED}')
            if self.log_file:
                redacted_secret = '*' * len(secret)
                logged_message = f'{now} - {padded_severity} - {message} {redacted_secret}'
                self.file.write(logged_message + '\n')

if __name__ == '__main__':
    print("This library is intended to be imported by another Python program and cannot be called directly.")
    sys.exit(main())
Leave a Comment