ds_common_logger_py_lib.formatter ================================= .. py:module:: ds_common_logger_py_lib.formatter .. autoapi-nested-parse:: **File:** ``formatter.py`` **Region:** ``ds_common_logger_py_lib`` Description ----------- Defines a custom logging formatter that appends non-standard LogRecord fields (i.e. values passed via the ``extra=...`` argument) to the formatted log output. .. rubric:: Example >>> import logging >>> from ds_common_logger_py_lib.formatter import ExtraFieldsFormatter >>> >>> formatter = ExtraFieldsFormatter() >>> handler = logging.StreamHandler() >>> handler.setFormatter(formatter) >>> >>> logger = logging.getLogger("test") >>> logger.addHandler(handler) >>> logger.setLevel(logging.INFO) >>> >>> logger.info("Test message", extra={"user_id": 123}) [2024-01-15T10:30:45][test][INFO][formatter.py:26]: Test message | extra: {"user_id": 123} Classes ------- .. autoapisummary:: ds_common_logger_py_lib.formatter.LoggerFilter ds_common_logger_py_lib.formatter.ExtraFieldsFormatter Module Contents --------------- .. py:class:: LoggerFilter(allowed_prefixes: set[str] | None = None, managed_loggers: set[str] | None = None) Bases: :py:obj:`logging.Filter` Filter to only allow logs from specified logger name prefixes. Simple whitelist approach: if a logger name starts with (or equals) any allowed prefix, it's allowed. Everything else is filtered out. Loggers in the managed_loggers set are automatically allowed, regardless of allowed_prefixes. .. py:attribute:: allowed_prefixes :value: None .. py:attribute:: managed_loggers .. py:method:: filter(record: logging.LogRecord) -> bool Filter log records - return True to allow, False to exclude. Loggers in managed_loggers are automatically allowed. If allowed_prefixes is None or empty, only managed loggers are allowed. Otherwise, managed loggers plus logs whose name starts with (or equals) an allowed prefix are allowed. :param record: The log record to filter. :returns: True if the log should be shown, False if it should be excluded. .. py:class:: ExtraFieldsFormatter(fmt: str | None = None, datefmt: str | None = None, template_vars: dict[str, str] | None = None) Bases: :py:obj:`logging.Formatter` Custom formatter that includes extra fields in log output. This formatter extends the standard logging.Formatter to properly handle extra fields passed via the extra parameter in logging calls. Extra fields are serialized as JSON and appended to the log message. The formatter also supports template variables in format strings, such as {prefix}, which are replaced at runtime with values provided by the caller. :param fmt: Format string for the log message. May contain template variables like {prefix} that will be replaced at runtime. :param datefmt: Date format string. :param template_vars: Optional dictionary of template variables to replace in the format string (e.g., {"prefix": "MyApp"}). :returns: Formatter instance that handles extra fields and template variables. .. rubric:: Example >>> import logging >>> formatter = ExtraFieldsFormatter( ... fmt="[%(asctime)s][{prefix}][%(name)s]: %(message)s", ... template_vars={"prefix": "MyApp"} ... ) >>> handler = logging.StreamHandler() >>> handler.setFormatter(formatter) >>> logger = logging.getLogger("test") >>> logger.addHandler(handler) >>> logger.setLevel(logging.INFO) >>> logger.info("Test message", extra={"user_id": 123}) [2024-01-15T10:30:45][MyApp][test]: Test message | extra: {"user_id": 123} .. py:attribute:: _STANDARD_ATTRS :type: ClassVar[set[str]] .. py:attribute:: template_vars .. py:method:: _resolve_template(fmt: str) -> str Resolve template variables in the format string. Remove empty bracket pairs: [] and optional space after it This handles patterns like "[] " or "[]" at the start/middle/end of format string :param fmt: Format string with potential template variables. :returns: Format string with template variables replaced. .. py:method:: format(record: logging.LogRecord) -> str Format the log record, including extra fields. :param record: The LogRecord instance to format. :returns: Formatted log message string with extra fields appended if present. .. rubric:: Example >>> import logging >>> formatter = ExtraFieldsFormatter() >>> handler = logging.StreamHandler() >>> handler.setFormatter(formatter) >>> logger = logging.getLogger("test") >>> logger.addHandler(handler) >>> logger.setLevel(logging.INFO) >>> logger.info("Test", extra={"user_id": 123}) [2024-01-15T10:30:45][test][INFO][test.py:1]: Test | extra: {"user_id": 123}