Skip to content

Commit

Permalink
fix: don't create logging handler multiple times (DEV-2891) (#609)
Browse files Browse the repository at this point in the history
  • Loading branch information
jnussbaum committed Oct 30, 2023
1 parent 736f02b commit e6aa47c
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 43 deletions.
41 changes: 23 additions & 18 deletions src/dsp_tools/cli.py
Expand Up @@ -154,15 +154,15 @@ def _make_parser(
parser_upload_files.add_argument("-p", "--password", default=root_user_pw, help=password_text)

# fast-xmlupload
parser_fast_xmlupload_files = subparsers.add_parser(
parser_fast_xmlupload = subparsers.add_parser(
name="fast-xmlupload",
help="For internal use only: create resources with already uploaded files",
)
parser_fast_xmlupload_files.set_defaults(action="fast-xmlupload")
parser_fast_xmlupload_files.add_argument("-s", "--server", default=default_dsp_api_url, help=dsp_server_text)
parser_fast_xmlupload_files.add_argument("-u", "--user", default=root_user_email, help=username_text)
parser_fast_xmlupload_files.add_argument("-p", "--password", default=root_user_pw, help=password_text)
parser_fast_xmlupload_files.add_argument("xml_file", help="path to XML file containing the data")
parser_fast_xmlupload.set_defaults(action="fast-xmlupload")
parser_fast_xmlupload.add_argument("-s", "--server", default=default_dsp_api_url, help=dsp_server_text)
parser_fast_xmlupload.add_argument("-u", "--user", default=root_user_email, help=username_text)
parser_fast_xmlupload.add_argument("-p", "--password", default=root_user_pw, help=password_text)
parser_fast_xmlupload.add_argument("xml_file", help="path to XML file containing the data")

# excel2json
parser_excel2json = subparsers.add_parser(
Expand Down Expand Up @@ -296,24 +296,29 @@ def _log_cli_arguments(parsed_args: argparse.Namespace) -> None:
Args:
parsed_args: parsed arguments
"""
msg = f"*** Called the DSP-TOOLS action '{parsed_args.action}' from the command line with these parameters:"
metadata_lines = []
_version = version("dsp-tools")
metadata_lines.append(f"DSP-TOOLS {_version}: Called the action '{parsed_args.action}' from the command line")
metadata_lines.append(f"Location of this installation: {__file__}")
metadata_lines.append("CLI arguments:")
metadata_lines = [f"*** {line}" for line in metadata_lines]

parameter_lines = list()
parameters_to_log = {key: value for key, value in vars(parsed_args).items() if key != "action"}
longest_key_length = max(len(key) for key in parameters_to_log) if parameters_to_log else 0
lines = list()
for key, value in parameters_to_log.items():
if key == "password":
lines.append(f"*** {key:<{longest_key_length}} = {'*' * len(value)}")
parameter_lines.append(f"{key:<{longest_key_length}} = {'*' * len(value)}")
else:
lines.append(f"*** {key:<{longest_key_length}} = {value}")
if not lines:
lines.append("*** (no parameters)")
asterisk_count = max(
len(msg),
max(len(line) for line in lines),
)
parameter_lines.append(f"{key:<{longest_key_length}} = {value}")
parameter_lines = parameter_lines or ["(no parameters)"]
parameter_lines = [f"*** {line}" for line in parameter_lines]

asterisk_count = max(len(line) for line in metadata_lines + parameter_lines)
logger.info("*" * asterisk_count)
logger.info(msg)
for line in lines:
for line in metadata_lines:
logger.info(line)
for line in parameter_lines:
logger.info(line)
logger.info("*" * asterisk_count)

Expand Down
2 changes: 1 addition & 1 deletion src/dsp_tools/fast_xmlupload/process_files.py
Expand Up @@ -21,7 +21,7 @@
from dsp_tools.utils.create_logger import get_logger
from dsp_tools.utils.shared import http_call_with_retry, make_chunks

logger = get_logger(__name__, filesize_mb=100, backupcount=36)
logger = get_logger(__name__)
sipi_container: Optional[Container] = None
export_moving_image_frames_script: Optional[Path] = None

Expand Down
72 changes: 48 additions & 24 deletions src/dsp_tools/utils/create_logger.py
Expand Up @@ -2,37 +2,34 @@
import logging.handlers
from pathlib import Path

# the handler must live on module level, so that it is created only once
_rotating_file_handler: logging.handlers.RotatingFileHandler | None = None

def get_logger(
name: str,
level: int = logging.INFO,
filesize_mb: int = 5,
backupcount: int = 4,
) -> logging.Logger:

def _make_handler(
logfile_directory: Path,
filesize_mb: int,
backupcount: int,
) -> logging.handlers.RotatingFileHandler:
"""
Create a logger instance,
set its level to INFO,
and configure it to write to a file in the user's home directory.
Create a rotating file handler.
A RotatingFileHandler fills "filename" until it is "maxBytes" big,
then appends ".1" to it and starts with a new file "filename",
fills it until it is "maxBytes" big,
then appends ".1" to it (replacing the old ".1" file)
Args:
name: name of the logger
level: logging level, defaults to logging.INFO
filesize_mb: maximum size per log file in MB, defaults to 5
backupcount: number of log files to keep, defaults to 4
logfile_directory: directory to store the logfiles in
filesize_mb: maximum size of a logfile in MB
backupcount: number of logfiles to keep
Returns:
the logger instance
handler instance
"""
_logger = logging.getLogger(name)
_logger.setLevel(level)
formatter = logging.Formatter(fmt="{asctime} {filename: <20} {levelname: <8} {message}", style="{")
formatter = logging.Formatter(fmt="{asctime} {filename: <30} {levelname: <8} {message}", style="{")
formatter.default_time_format = "%Y-%m-%d %H:%M:%S"
formatter.default_msec_format = "%s.%03d"
# a RotatingFileHandler fills "filename" until it is "maxBytes" big,
# then appends ".1" to it and starts with a new file "filename",
# fills it until it is "maxBytes" big,
# then appends ".1" to it (replacing the old ".1" file)
logfile_directory = Path.home() / Path(".dsp-tools")

logfile_directory.mkdir(exist_ok=True)
handler = logging.handlers.RotatingFileHandler(
filename=logfile_directory / "logging.log",
Expand All @@ -41,5 +38,32 @@ def get_logger(
backupCount=backupcount,
)
handler.setFormatter(formatter)
_logger.addHandler(handler)
return _logger
return handler


def get_logger(
name: str,
level: int = logging.DEBUG,
) -> logging.Logger:
"""
Create a logger instance,
and configure it to write to a file in the user's home directory.
Args:
name: name of the logger
level: logging level, defaults to logging.DEBUG
Returns:
the logger instance
"""
global _rotating_file_handler
if not _rotating_file_handler:
_rotating_file_handler = _make_handler(
Path.home() / Path(".dsp-tools"),
filesize_mb=100,
backupcount=30,
)
logger = logging.getLogger(name)
logger.setLevel(level)
logger.addHandler(_rotating_file_handler)
return logger

0 comments on commit e6aa47c

Please sign in to comment.