Skip to content

Logging

Add LoggingOptMixin to the parser and configure logging through Meta. If the app already owns handlers / dictConfig, omit the mixin — see Two approaches in the logging guide. Full walkthrough: Logging.

from clak import LoggingOptMixin, Parser

class App(LoggingOptMixin, Parser):
    class Meta:
        log_prefix = __name__
        log_default_level = "WARNING"
        log_levels = [
            ["WARNING|myapp"],
            ["INFO|myapp"],
            ["DEBUG|myapp"],
            ["DEBUG|"],
        ]
        log_silent = ["noisy_dependency"]

    def cli_run(self, **_):
        self.logger.info("ready")
        self.logger.success("done")

Each log_levels entry is a cumulative -v tier (LEVEL|logger). An empty logger name configures the root logger. The legacy [["clak"], [""]] form remains supported and expands every group into INFO and DEBUG tiers. log_silent namespaces stay at WARNING until maximum verbosity.

CLI flags: -v / --verbose, --log-format, --trace, and --log-colors / --no-log-colors (always present; ANSI needs pip install 'mrjk.clak[colors]'). Default is on for TTY, or CLAK_LOG_COLORS when set (override the env name with Meta.log_colors_env).

Custom levels spam, verbose, success, and notice are registered automatically.

clak.comp.logging

Provides logging functionality and configuration for CLI applications.

This module implements a flexible logging system with the following key features: - Configurable log levels and verbosity through CLI arguments - Support for colored output (when coloredlogs is installed) - Multiple log formatters (default, extended, audit, debug) - Hierarchical logger naming with prefix/suffix support - Mixin class for easy integration with CLI parsers

The logging system can be configured through Meta settings in parser classes: - log_prefix: Sets the base name for loggers (typically name) - log_suffix: Controls the right part of logger names - log_default_level: Sets the default logging level

Notes: - Set log_prefix (typically __name__) so self.logger uses your app namespace.

Example:

class AppMain(LoggingOptMixin,Parser):


    class Meta:

        log_prefix = f"{__name__}"    # AKA myapp
        # log_prefix = f"other_prefix.{__name__}"
        # log_prefix = f"{__name__}.other_prefix"
        # log_suffix = "suffix"

    def cli_group(self, ctx, **_):
        "Main group"

        # Usual logger, usually from logger = logging.getLogger(__name__)
        logger.debug("Hello World - App")
        logger.info("Hello World - App")
        logger.warning("Hello World - App")
        logger.error("Hello World - App")

        # Only useful when `log_prefix` is set
        self.logger.debug("Hello World - Self")
        self.logger.info("Hello World - Self")
        self.logger.warning("Hello World - Self")
        self.logger.error("Hello World - Self")

Without log_prefix set (by default):

 WARNING myapp.cli                 Hello World - App
   ERROR myapp.cli                 Hello World - App
 WARNING clak.parser               Hello World - Self
   ERROR clak.parser               Hello World - Self

With log_prefix set:

 WARNING myapp.cli                 Hello World - App
   ERROR myapp.cli                 Hello World - App
 WARNING myapp.cli.AppMain         Hello World - Self
   ERROR myapp.cli.AppMain         Hello World - Self

DEFAULT_LOG_LEVEL = logging.WARNING module-attribute

DEFAULT_LOG_LEVELS = [['INFO|clak'], ['DEBUG|clak'], ['INFO|'], ['DEBUG|']] module-attribute

LoggingOptMixin

Bases: PluginHelpers

Logging options support

add_arguments(arguments=None)

Format --log-colors help with Meta.log_colors_env, then register.

assemble_user_config(configs)

Build cumulative verbosity tiers from Meta.log_levels.

Explicit entries use LEVEL|logger. Legacy configurations containing only logger names are expanded to INFO and DEBUG tiers for each group.

cli_hook__logging(instance, ctx, **_)

Inject or create logger into instance

select_user_config(user_config, req=0)

Select user config from requested level

test_logger(instance=None)

Test the logger by sending test messages at different log levels.

Parameters:

Name Type Description Default
instance object | None

The instance to test logging for. If None, uses self.

None

get_app_logger(loggers=None, level='WARNING', colors=False, formatter='default', level_styles=None)

Instanciate application logger

clak.runtime.log_levels

Custom logging level registration for Clak applications.

CLAK_CUSTOM_LEVELS = (('SPAM', 5, 'spam'), ('VERBOSE', 15, 'verbose'), ('SUCCESS', logging.INFO + 3, 'success'), ('NOTICE', logging.INFO + 5, 'notice')) module-attribute

CLAK_CUSTOM_LEVEL_STYLES = {'spam': {'color': 'black', 'faint': True}, 'verbose': {'color': 'cyan'}, 'success': {'color': 'green', 'bold': True}, 'notice': {'color': 'green'}} module-attribute

KEEP = 'keep' module-attribute

KEEP_WARN = 'keep-warn' module-attribute

OVERWRITE = 'overwrite' module-attribute

OVERWRITE_WARN = 'overwrite-warn' module-attribute

RAISE = 'raise' module-attribute

add_logging_level(level_name, level_num, method_name=None, if_exists=KEEP_WARN, *, exc_info=False, stack_info=False)

Register a custom logging level on :py:mod:logging.

Source: adapted from haggis / python-iam add_logging_level.

register_clak_log_levels(if_exists=KEEP)

Register Clak's built-in custom levels (SPAM, VERBOSE, SUCCESS, NOTICE).