From ae5893c22fbe9fa2c35c5073eb285d0552c79098 Mon Sep 17 00:00:00 2001 From: "D. Scott Boggs" Date: Sat, 31 May 2025 09:10:17 -0400 Subject: [PATCH] add structured logging --- pyproject.toml | 9 ++++++++- roc_fnb/util/__init__.py | 1 + roc_fnb/util/logging.py | 30 ++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 roc_fnb/util/__init__.py create mode 100644 roc_fnb/util/logging.py diff --git a/pyproject.toml b/pyproject.toml index 693bd80..c968c61 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,8 +9,15 @@ description = "Temporary placeholder for fnb web site" readme = "README.md" requires-python = ">=3.11" # Self type added license = "AGPL-3.0-only" -dependencies = ["flask", "gunicorn"] +dependencies = [ + "flask", + "gunicorn", + "structlog", +] dynamic = ["version"] [project.scripts] # Put scripts here + +[tool.yapf] +based_on_style = "facebook" \ No newline at end of file diff --git a/roc_fnb/util/__init__.py b/roc_fnb/util/__init__.py new file mode 100644 index 0000000..0be7677 --- /dev/null +++ b/roc_fnb/util/__init__.py @@ -0,0 +1 @@ +from roc_fnb.util.logging import log \ No newline at end of file diff --git a/roc_fnb/util/logging.py b/roc_fnb/util/logging.py new file mode 100644 index 0000000..b98508a --- /dev/null +++ b/roc_fnb/util/logging.py @@ -0,0 +1,30 @@ +import logging +from os import environ + +from structlog.processors import JSONRenderer, TimeStamper +from structlog.dev import ConsoleRenderer +import structlog + +if not structlog.is_configured(): + if (env := environ.get('ENV_MODE')) and env == 'production': + timestamper = TimeStamper(fmt="%Y-%m-%d %H:%M:%S", utc=True) + renderer: JSONRenderer | ConsoleRenderer = JSONRenderer() + else: + timestamper = TimeStamper(fmt="%Y-%m-%d %H:%M:%S", utc=False) + renderer = ConsoleRenderer() + structlog.configure( + processors=[ + structlog.contextvars.merge_contextvars, + structlog.processors.add_log_level, + structlog.processors.StackInfoRenderer(), + structlog.dev.set_exc_info, + timestamper, + renderer, + ], + wrapper_class=structlog.make_filtering_bound_logger(logging.NOTSET), + context_class=dict, + logger_factory=structlog.PrintLoggerFactory(), + cache_logger_on_first_use=False + ) + +log = structlog.get_logger()