Logging

Wrapper around loguru with some opinionated formatting. There are pydantic models for configuring the sinks, and custom logger class that does some formatting for you and helps with structured data.

Main Logging Class

main interface to setup and use the logger.

pydantic model Logger

The main interface. Use the ‘setup_logger’ classmethod to configure the logger and ‘get_logger’ classmethod to get a Logger instance to use. The methods are the standard ones you’d want in a logger.

Show JSON schema
{
   "title": "Logger",
   "description": "The main interface. Use the 'setup_logger' classmethod to configure the logger\nand 'get_logger' classmethod to get a Logger instance to use.\nThe methods are the standard ones you'd want in a logger.",
   "type": "object",
   "properties": {
      "service_name": {
         "title": "Service Name",
         "type": "string"
      },
      "sinks": {
         "items": {
            "discriminator": {
               "mapping": {
                  "file": "#/$defs/FilePathLogSink",
                  "sys": "#/$defs/SysLogSink"
               },
               "propertyName": "class_id"
            },
            "oneOf": [
               {
                  "$ref": "#/$defs/SysLogSink"
               },
               {
                  "$ref": "#/$defs/FilePathLogSink"
               }
            ]
         },
         "title": "Sinks",
         "type": "array"
      }
   },
   "$defs": {
      "FilePathLogSink": {
         "additionalProperties": false,
         "description": "see https://loguru.readthedocs.io/en/stable/overview.html\n#easier-file-logging-with-rotation-retention-compression\nfor more info. We only support a small subset here for now",
         "properties": {
            "class_id": {
               "const": "file",
               "default": null,
               "description": "this is the field we dispatch the different sub-classes on. Concrete classes will constrain this to be only one specific value.",
               "enum": [
                  "file"
               ],
               "title": "Class Id",
               "type": "string"
            },
            "level": {
               "allOf": [
                  {
                     "$ref": "#/$defs/LogLevel"
                  }
               ],
               "default": "info",
               "description": "the level for this logger"
            },
            "backtrace": {
               "default": true,
               "description": "if true, we automatically include tracebacks when we are logging an error. We can still augment our logs with a call stack whenever we want, regardless of if we are in the exception context. see the relevant log augmentorsee `docs <https://loguru.readthedocs.io/en/stable/overview.html#fully-descriptive-exceptions>`_",
               "title": "Backtrace",
               "type": "boolean"
            },
            "diagnose": {
               "default": false,
               "description": "if we true, we annotate the stacktrace with values of specific variables in the stack trace. Like as debugger. see `docs <https://loguru.readthedocs.io/en/stable/overview.html#fully-descriptive-exceptions>`_",
               "title": "Diagnose",
               "type": "boolean"
            },
            "struct_log": {
               "default": false,
               "description": "if true, we serialize the logs for usage in a structured way. this field is used when building the loguru_kwargs passed in when setting up the sink",
               "title": "Struct Log",
               "type": "boolean"
            },
            "include_extra_data": {
               "default": true,
               "description": "if false, we do not include extra data for this sink",
               "title": "Include Extra Data",
               "type": "boolean"
            },
            "custom_loguru_fmat": {
               "anyOf": [
                  {
                     "type": "string"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "description": "an optional field you can use to manually specify the loguru format for this sink",
               "title": "Custom Loguru Fmat"
            },
            "file_name_prefix": {
               "description": "the prefix of the file name where we'll be writing logs",
               "title": "File Name Prefix",
               "type": "string"
            },
            "dir_path": {
               "format": "directory-path",
               "title": "Dir Path",
               "type": "string"
            },
            "file_ext": {
               "default": "log",
               "title": "File Ext",
               "type": "string"
            },
            "add_timestamp_to_name": {
               "default": true,
               "title": "Add Timestamp To Name",
               "type": "boolean"
            },
            "rotation_size": {
               "anyOf": [
                  {
                     "type": "string"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": "500 MB",
               "title": "Rotation Size"
            }
         },
         "required": [
            "file_name_prefix",
            "dir_path"
         ],
         "title": "FilePathLogSink",
         "type": "object"
      },
      "LogLevel": {
         "anyOf": [
            {
               "enum": [
                  "debug",
                  "info",
                  "warning",
                  "error",
                  "critical"
               ],
               "type": "string"
            },
            {
               "enum": [
                  10,
                  20,
                  30,
                  40,
                  50
               ],
               "type": "integer"
            }
         ],
         "description": "a root model holding enum values.",
         "title": "LogLevel"
      },
      "SysLogSink": {
         "additionalProperties": false,
         "properties": {
            "class_id": {
               "const": "sys",
               "default": null,
               "description": "this is the field we dispatch the different sub-classes on. Concrete classes will constrain this to be only one specific value.",
               "enum": [
                  "sys"
               ],
               "title": "Class Id",
               "type": "string"
            },
            "level": {
               "allOf": [
                  {
                     "$ref": "#/$defs/LogLevel"
                  }
               ],
               "default": "info",
               "description": "the level for this logger"
            },
            "backtrace": {
               "default": true,
               "description": "if true, we automatically include tracebacks when we are logging an error. We can still augment our logs with a call stack whenever we want, regardless of if we are in the exception context. see the relevant log augmentorsee `docs <https://loguru.readthedocs.io/en/stable/overview.html#fully-descriptive-exceptions>`_",
               "title": "Backtrace",
               "type": "boolean"
            },
            "diagnose": {
               "default": false,
               "description": "if we true, we annotate the stacktrace with values of specific variables in the stack trace. Like as debugger. see `docs <https://loguru.readthedocs.io/en/stable/overview.html#fully-descriptive-exceptions>`_",
               "title": "Diagnose",
               "type": "boolean"
            },
            "struct_log": {
               "default": false,
               "description": "if true, we serialize the logs for usage in a structured way. this field is used when building the loguru_kwargs passed in when setting up the sink.This must be False for system-based log sink",
               "title": "Struct Log",
               "type": "boolean"
            },
            "include_extra_data": {
               "default": true,
               "description": "if false, we do not include extra data for this sink",
               "title": "Include Extra Data",
               "type": "boolean"
            },
            "custom_loguru_fmat": {
               "anyOf": [
                  {
                     "type": "string"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "description": "an optional field you can use to manually specify the loguru format for this sink",
               "title": "Custom Loguru Fmat"
            },
            "channel": {
               "default": "stdout",
               "enum": [
                  "stdout",
                  "stderr"
               ],
               "title": "Channel",
               "type": "string"
            }
         },
         "title": "SysLogSink",
         "type": "object"
      }
   },
   "required": [
      "service_name",
      "sinks"
   ]
}

field service_name: str [Required]

the name of the service to use

field sinks: t.List[_sinks.AnySinkT] [Required]

the sink configs we used for this logger. Merely there for informational purposes as they are used for setup prior to initializing this instance

critical(msg: str, extra_data: list[Any] | None = None, depth: int | None = None)
debug(msg: str, extra_data: list[Any] | None = None, depth: int | None = None)
error(msg: str, extra_data: list[Any] | None = None, depth: int | None = None)
exception(msg: str, extra_data: list[Any] | None = None, depth: int | None = None)
classmethod get_logger(service_name: str | None = None) Logger

get a previously set up logger. If nothing specified, we’ll create a logger with no sink configs and raise a warning about it.

Parameters:

service_name – if specified, we’ll change the service name to this value, otherwise it’ll be unchanged

Returns: a Logger instance

info(msg: str, extra_data: list[Any] | None = None, depth: int | None = None)
log(level: LogLevel, msg: str, extra_data: list[Any] | None = None, depth: int | None = None) None
model_post_init(__context: Any) None

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that’s what pydantic-core passes when calling it.

Parameters:
  • self – The BaseModel instance.

  • __context – The context.

classmethod setup_logger(service_name: str, sinks: List[SysLogSink | FilePathLogSink], cache_res: bool = True) Logger

Sets up the logger with the sinks and the service name. Use this classmethod to initially set up a logger and for all subsequent calls, use ‘get_logger’ class method.

Parameters:
  • service_name – the name of the service we are setting up the logger for

  • sinks – the sink configs we want to use

  • cache_res – if True, we cache the Logger inst for later usage. default is True

Returns:

a setup logger inst

Return type:

Logger

classmethod setup_logger_uvicorn(service_name: str, sinks: List[SysLogSink | FilePathLogSink], cache_res: bool = True) Logger

Sets up the logger with the sinks and the service name, with special logic for when we’re using it within an uvicorn server context

Parameters:
  • service_name – the name of the service we are setting up the logger for

  • sinks – the sink configs we want to use

  • cache_res – if True, we cache the Logger inst for later usage. default is True

Returns:

a setup logger inst

Return type:

Logger

property loguru_logger: Logger

the underlying loguru logger instance