Skip to content

Reference

loggia.logger ¤

Main module for logging configuration, using standard logging.

loggia.logger.initialize ¤

initialize(conf: LoggerConfiguration | dict[str, str] | None = None, presets: str | list[str] | None = None) -> None

Initialize the logging system.

Source code in loggia/logger.py
def initialize(conf: LoggerConfiguration | dict[str, str] | None = None, presets: str | list[str] | None = None) -> None:
    """Initialize the logging system."""
    conf = _bootstrap_config(conf, presets)

    if conf.setup_excepthook:
        _set_excepthook(logging.getLogger())

    if conf.setup_unraisablehook:
        _set_unraisablehook(logging.getLogger())

    if conf.setup_threading_excepthook:
        _set_threading_excepthook(logging.getLogger())

    # XXX asyncio bullshit?
    # XXX audit subsystem bridge

    if conf.capture_warnings:
        # XXX test
        logging.captureWarnings(capture=True)

    if conf.capture_loguru in (FlexibleFlag.AUTO, FlexibleFlag.ENABLED):
        try:
            from loggia.loguru_sink import configure_loguru

            _patch_to_add_level(5, "TRACE")
            _patch_to_add_level(25, "SUCCESS")
            configure_loguru(conf)
        except ModuleNotFoundError as e:
            if conf.capture_loguru == FlexibleFlag.ENABLED:
                bootstrap_logger.error("Failed to configure loguru! Is is installed?", e)

    # XXX Check that logger levels exists
    # BIM BAM BADABEEM BADABOOM, LOGGIA MAGICA!
    logging.config.dictConfig(conf._dictconfig)

loggia.conf ¤

loggia.conf.LoggerConfiguration ¤

LoggerConfiguration(*, settings: dict[str, str] | None = None, presets: str | list[str] | None = None)

Environment-aware configuration container for loggia.

loggia.conf.LoggerConfiguration.add_log_filter ¤

add_log_filter(logger_name: str, filter_: SupportsFilter | Callable[[logging.LogRecord], bool]) -> None

Add a filter to a specific logger.

Use the empty string as logger name to add a filter to the root logger.

NB: Filters do not propagate like handlers do, see https://docs.python.org/3/library/logging.html#logging.Logger.propagate for more information.

If you want the filter to propagate, set it on the handler rather than the logger with add_handler_filter

loggia.conf.LoggerConfiguration.set_capture_warnings ¤

set_capture_warnings(enabled: bool | str) -> None

Explicitely enable the capture of warnings.

When set to true, Loggia will attempt to log warnings.

loggia.conf.LoggerConfiguration.set_default_formatter ¤

set_default_formatter(formatter: UserDefinedObject[logging.Formatter]) -> None

Sets the default formatter.

loggia.conf.LoggerConfiguration.set_excepthook ¤

set_excepthook(enabled: bool | str) -> None

Explicitely enable or disable setting sys.excepthook.

When set to true, Loggia log unhandled exceptions as CRITICAL errors.

loggia.conf.LoggerConfiguration.set_general_level ¤

set_general_level(level: int | str) -> None

Set the general/root, or default, log level.

Can be either a level name string or a level numder int.

loggia.conf.LoggerConfiguration.set_logger_level ¤

set_logger_level(logger_name: str, level: int | str) -> None

Set a specific log level for a specific logger.

This allows you to fine tune verbosity according to your needs.

loggia.conf.LoggerConfiguration.set_logger_propagation ¤

set_logger_propagation(logger_name: str, does_propagate: str) -> None

Set a specific logger's propagation.

loggia.conf.LoggerConfiguration.set_loguru_capture ¤

set_loguru_capture(enabled: FlexibleFlag | bool | str) -> None

Explicitely disable Loggia-Loguru interop.

When set to AUTO, Loggia will attempt to configure Loguru if possible, and be silent if it's not possible.

When set to ENABLED, Loggia will attempt to configure Loguru, and will produce an error if it is not importable.

When set to DISABLED, Loggia will not attempt to configure Loguru even if it is present.

loggia.conf.LoggerConfiguration.set_loguru_reconfiguration_block ¤

set_loguru_reconfiguration_block(enabled: bool | str) -> None

Explicitely allow loguru to be reconfigured.

Loggia may hack Loguru to prevent other systems to overwrite the interop. This allows early detection of problems arising from conflicting configurations. Generally speaking, Loggia does not support or test against any Loguru customizations. You may have to use this setting if your software fails to initialize.

loggia.conf.LoggerConfiguration.set_threading_excepthook ¤

set_threading_excepthook(enabled: bool | str) -> None

Explicitely enable or disable setting threading.excepthook.

When set to true, Loggia will log uncaught exception in threads as CRITICAL errors.

loggia.conf.LoggerConfiguration.set_unraisablehook ¤

set_unraisablehook(enabled: bool | str) -> None

Explicitely enable or disable setting sys.unraisablehook.

When set to true, Loggia will log unraisable exceptions as CRITICAL errors. Unraisable exceptions are unusual, and may happen i.e. during finalization or garbage collection.

loggia.stdlib_formatters ¤

Formatters for standard-lib logging.

loggia.stdlib_formatters.json_formatter ¤

loggia.stdlib_formatters.json_formatter.CustomJsonEncoder ¤

Bases: JsonEncoder

Custom JSON encoder, handling some extra types like UUID or socket.

loggia.stdlib_formatters.json_formatter.CustomJsonFormatter ¤

CustomJsonFormatter(*args: Any, **kwargs: Any)

Bases: JsonFormatter

Custom JSON formatter for Loggia.

loggia.stdlib_formatters.json_formatter.JsonSerializable ¤

Bases: Protocol

Protocol for any object willing to cooperate with our CustomJsonEncoder.

loggia.stdlib_formatters.pretty_formatter ¤

loggia.stdlib_formatters.pretty_formatter.PrettyFormatter ¤

PrettyFormatter(*args: Any, **kwargs: Any)

Bases: Formatter

A custom formatter for logging that uses colors.

loggia.presets ¤

loggia.presets.datadog_normalisation ¤

Remap anything to Datadog standard and common attributes.

loggia.presets.dev ¤

Dev is the overarching preset for a delightful development experience.

loggia.presets.gunicorn ¤

Logging presets for Gunicorn.

loggia.presets.hypercorn ¤

Logging presets for Hypercorn.

loggia.presets.null_preset ¤

The null preset does nothing.

Use this preset as an easy to cut and paste template to write you own. This preset changes strictly nothing.

loggia.presets.prod ¤

An overarching preset for a no-frills JSON production logger to stdout.

loggia.base_preset ¤

loggia.base_preset.BasePreset ¤

Base class for Loggia Presets.

Loggia presets are a very thin abstraction that allows bundling of settings that address a similar concern.

loggia.base_preset.BasePreset.apply abstractmethod ¤

apply

The defining part of what the preset does by mutating conf as appropriate.

loggia.base_preset.BasePreset.required_presets classmethod ¤

required_presets

Provides a mechanism for preset->preset dependencies.

This is the primary mechanism to make a preset tied to the 'dev' or 'prod' presets without introducing a new slot.

The returned value is interpreted using the following rules
  • Single strings point to another's prefix name or preference key
  • Sub-lists are also made of another's prefix name or preference key
  • Sub-lists elements are implicit AND
  • Main-list elements are implicit OR

Examples:

  • ["dev", "prod"] # 'dev' OR 'prod' preset is activating
  • [["prod", "datadog"]] # 'prod' AND 'datadog' is activating
  • ["dev", ["prod", "datadog"]] # 'dev' OR ('prod' AND 'datadog') are activating

Presets disabling themselves because the clause doesn't match will result in a log at TRACE level in the bootstrap logger.

NB: Requirements resolution happens after slot-selection and not before, unlike most dependency management solutions. This makes things simpler but less powerful.

loggia.base_preset.BasePreset.slots classmethod ¤

slots

Override the slots method to indicate mutually incompatible presets.

Mutually incompatible presets should have at least one slot in common. Slots have otherwise no use inside Loggia, but should roughly map to a single concern.

loggia.constants.BASE_DICTCONFIG module-attribute ¤

BASE_DICTCONFIG: Final[_DictConfigArgs] = {'version': 1, 'disable_existing_loggers': False, 'handlers': {'default': {'class': 'logging.StreamHandler', 'formatter': 'structured'}}, 'loggers': {'': {'handlers': ['default'], 'propagate': True, 'level': 'INFO'}}}

The base dictconfig for loggia.

See standard logging.config.dictConfig for details about this.

NB: We do not encourage you to modify the base dictconfig, but it is the ultimate escape hatch, where anything standard logging can do, you can do too. Remember anything put inside that dict has the lowest precedence over any kind of configuration in Loggia.