Usage

For Python applications, this is as simple as:

import logging
from ska_ser_logging import configure_logging

def main():
    configure_logging()
    logger = logging.getLogger("ska.example")
    logger.info("Logging started for Example application")

Applying Custom Log Configuration

Log Level

The configure_logging function takes additional arguments, including one that allows the initial log level to be specified. It may be useful to link that to a command line option or environment variable.

import logging
from ska_ser_logging import configure_logging

def main():
    configure_logging(logging.DEBUG)

Log Filter

SKA’s logging format allows for simple tags (key-value pairs) to be included in log messages. Application-specific behaviour can be provided via a filter, which will be added to all handlers in the configuration used by configure_logging. If this filter is provided, it must add a tags attribute to each record, as the log message formatting string will include a %(tags)s field.

Note that the logging format limits the characters allowed in tags. For example, | is not allowed. No validation is done by this library. If the filter is None (the default), then the field will be omitted.

import logging
from ska_ser_logging import configure_logging

class TangoDeviceTagsFilter(logging.Filter):
    def filter(self, record):
        record.tags = "tango-device:my/tango/device"
        return True

def main():
    configure_logging(level="DEBUG", tags_filter=TangoDeviceTagsFilter)

Log Config Dict

In the more general case, the configuration can be updated with an additional dict, matching the logging.config.dictConfig schema. This additional dict is recursively merged with the default configuration. While not recommended, keys in the default configuration can be removed by setting the corresponding override key’s value to None. In the example below, we add output to a file.

Note

The "default" formatter and "console" handler are provided by the default configuration.

import logging.handlers
from ska_ser_logging import configure_logging

ADDITIONAL_LOGGING_CONFIG = {
    "handlers": {
        "file": {
            "()" : logging.handlers.RotatingFileHandler,
            "formatter": "default",
            "filename": "./ska.example.log",
            "maxBytes": 2048,
            "backupCount": 2,
        }
    },
    "root": {
        "handlers": ["console", "file"],
    }
}

def main():
    configure_logging(overrides=ADDITIONAL_LOGGING_CONFIG)

Custom Handlers

Custom handlers that use the standard logging format may be useful. In this case, the function get_default_formatter is available. The example below is contrived, but shows the approach. A more practical use case is adding and removing handlers at runtime.

import logging
import logging.handlers
from ska_ser_logging import configure_logging, get_default_formatter

def main():
    configure_logging()
    logger = logging.getLogger("ska.example")
    handler = logging.handlers.MemoryHandler(capacity=10)
    handler.setFormatter(get_default_formatter())
    logger.addHandler(handler)
    logger.info("Logging started for Example application")

Tip

By default, calls to configure_logging do not disable existing non-root loggers. This allows multiple calls to the function, although that will generally not be required. This behaviour can be overridden using the disable_existing_loggers key.