cornsnake.util_log

Functions for logging exceptions and setting up logging configurations.

Documentation

  1"""
  2Functions for logging exceptions and setting up logging configurations.
  3
  4[Documentation](http://docs.mrseanryan.cornsnake.s3-website-eu-west-1.amazonaws.com/cornsnake/util_log.html)
  5"""
  6
  7import logging
  8import os
  9import re
 10
 11from . import config
 12from . import util_color
 13
 14# Define the format for log entries
 15# ref https://realpython.com/python-logging/
 16log_format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
 17
 18
 19def set_log_dir_and_get_path_to_logfile(log_dir):
 20    """
 21    Set the log directory and get the path to the log file.
 22
 23    Args:
 24    log_dir (str): The directory where the log file will be stored.
 25
 26    Returns:
 27    str: The path to the log file.
 28    """
 29    path_to_logfile = os.path.join(log_dir, config.LOG_FILENAME)
 30    logging.basicConfig(
 31        filename=path_to_logfile,
 32        filemode="w",
 33        format=log_format,
 34        level=config.LOGGING_LEVEL,
 35    )
 36    return path_to_logfile
 37
 38
 39def log_exception(e):
 40    """
 41    Log an exception.
 42    -  Call from inside a Try..Except
 43
 44    Args:
 45    e (Exception): The exception to be logged.
 46    """
 47    # do NOT call util_print here (could be infinite loop)
 48    print(util_color.ERROR_COLOR + "!EXCEPTION!", e, util_color.END_COLORS)
 49    logging.exception("Exception occurred")
 50
 51
 52def getLogger(name_of_module):
 53    """
 54    Get a logger with the specified name.
 55
 56    - Call like this: getLogger(__name__) - then we know where did those log entries come from.
 57
 58    Args:
 59    name_of_module (str): The name of the module to create the logger for.
 60
 61    Returns:
 62    Logger: A logger object for the specified module.
 63    """
 64    return logging.getLogger(name_of_module)
 65
 66
 67MASKED = "<masked>"
 68pat = re.compile(r".*[/|\\]Users[/|\\]([A-Za-z.]*)[/|\\]{1}.*", re.M)
 69
 70WINDOWS_SEP = "\\"
 71MAC_SEP = "/"
 72
 73
 74def mask_sensitive_text(text):
 75    """
 76    Mask text that contains a user name.
 77
 78    Examples:
 79    - Windows: C:\\Users\\Bob.Jones\\my-file.txt -> C:\\Users\\<masked>\\my-file.txt
 80    - Mac: /Users/Bob.Jones/my-file.txt -> /Users/<masked>\my-file.txt
 81    """
 82    try:
 83        sensitive_win = WINDOWS_SEP + "Users" + WINDOWS_SEP
 84        sensitive_mac = MAC_SEP + "Users" + MAC_SEP
 85
 86        if (
 87            sensitive_win in text or sensitive_mac in text
 88        ):  # Both can occur with git on Windows
 89            matches = set(pat.findall(text))
 90
 91            while matches:
 92                for m in matches:
 93                    text = text.replace(m, "<masked>")
 94                matches = set(pat.findall(text))
 95    except ValueError:
 96        pass  # logging code needs to be robust
 97    except RuntimeError:
 98        pass  # logging code needs to be robust
 99
100    return text
101
102
103def log_sensitive_info(text, logger):
104    """
105    Log at info level, masking out any user name in the text.
106    """
107    logger.info(mask_sensitive_text(text))
108
109
110def log_sensitive_warn(text, logger):
111    """
112    Log at warn level, masking out any user name in the text.
113    """
114    logger.warn(mask_sensitive_text(text))
log_format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
def set_log_dir_and_get_path_to_logfile(log_dir):
20def set_log_dir_and_get_path_to_logfile(log_dir):
21    """
22    Set the log directory and get the path to the log file.
23
24    Args:
25    log_dir (str): The directory where the log file will be stored.
26
27    Returns:
28    str: The path to the log file.
29    """
30    path_to_logfile = os.path.join(log_dir, config.LOG_FILENAME)
31    logging.basicConfig(
32        filename=path_to_logfile,
33        filemode="w",
34        format=log_format,
35        level=config.LOGGING_LEVEL,
36    )
37    return path_to_logfile

Set the log directory and get the path to the log file.

Args: log_dir (str): The directory where the log file will be stored.

Returns: str: The path to the log file.

def log_exception(e):
40def log_exception(e):
41    """
42    Log an exception.
43    -  Call from inside a Try..Except
44
45    Args:
46    e (Exception): The exception to be logged.
47    """
48    # do NOT call util_print here (could be infinite loop)
49    print(util_color.ERROR_COLOR + "!EXCEPTION!", e, util_color.END_COLORS)
50    logging.exception("Exception occurred")

Log an exception.

  • Call from inside a Try..Except

Args: e (Exception): The exception to be logged.

def getLogger(name_of_module):
53def getLogger(name_of_module):
54    """
55    Get a logger with the specified name.
56
57    - Call like this: getLogger(__name__) - then we know where did those log entries come from.
58
59    Args:
60    name_of_module (str): The name of the module to create the logger for.
61
62    Returns:
63    Logger: A logger object for the specified module.
64    """
65    return logging.getLogger(name_of_module)

Get a logger with the specified name.

  • Call like this: getLogger(__name__) - then we know where did those log entries come from.

Args: name_of_module (str): The name of the module to create the logger for.

Returns: Logger: A logger object for the specified module.

MASKED = '<masked>'
pat = re.compile('.*[/|\\\\]Users[/|\\\\]([A-Za-z.]*)[/|\\\\]{1}.*', re.MULTILINE)
WINDOWS_SEP = '\\'
MAC_SEP = '/'
def mask_sensitive_text(text):
 75def mask_sensitive_text(text):
 76    """
 77    Mask text that contains a user name.
 78
 79    Examples:
 80    - Windows: C:\\Users\\Bob.Jones\\my-file.txt -> C:\\Users\\<masked>\\my-file.txt
 81    - Mac: /Users/Bob.Jones/my-file.txt -> /Users/<masked>\my-file.txt
 82    """
 83    try:
 84        sensitive_win = WINDOWS_SEP + "Users" + WINDOWS_SEP
 85        sensitive_mac = MAC_SEP + "Users" + MAC_SEP
 86
 87        if (
 88            sensitive_win in text or sensitive_mac in text
 89        ):  # Both can occur with git on Windows
 90            matches = set(pat.findall(text))
 91
 92            while matches:
 93                for m in matches:
 94                    text = text.replace(m, "<masked>")
 95                matches = set(pat.findall(text))
 96    except ValueError:
 97        pass  # logging code needs to be robust
 98    except RuntimeError:
 99        pass  # logging code needs to be robust
100
101    return text

Mask text that contains a user name.

Examples:

  • Windows: C:\Users\Bob.Jones\my-file.txt -> C:\Users<masked>\my-file.txt
  • Mac: /Users/Bob.Jones/my-file.txt -> /Users/\my-file.txt
def log_sensitive_info(text, logger):
104def log_sensitive_info(text, logger):
105    """
106    Log at info level, masking out any user name in the text.
107    """
108    logger.info(mask_sensitive_text(text))

Log at info level, masking out any user name in the text.

def log_sensitive_warn(text, logger):
111def log_sensitive_warn(text, logger):
112    """
113    Log at warn level, masking out any user name in the text.
114    """
115    logger.warn(mask_sensitive_text(text))

Log at warn level, masking out any user name in the text.