Language Page

ktrace for Python

This page is assembled from markdown in ktools-python. GitHub links point to the workspace repo and the relevant source files or directories.

4 markdown sections
QM-Code/ktools-python primary repo
HTML static output

Karma Trace Logging SDK

ktools-python/ktrace/README.md

ktrace is the Python tracing and operational logging layer for the ktools ecosystem.

It follows the same high-level model as the C++ implementation:

  • library-facing TraceLogger sources with named channels
  • executable-facing Logger runtime state for selector enablement and output
  • kcli integration through logger.makeInlineParser(...)
  • developer/operator output rather than end-user UI text

Documentation

Build SDK

Build from the ktools-python/ workspace root with the shared build tool:

python3 ../kbuild/kbuild.py --batch ktrace --build-latest

If kbuild is already on your PATH, the equivalent command is:

kbuild --batch ktrace --build-latest

SDK output:

  • build/latest/sdk/python/ktrace
  • build/latest/sdk/lib/cmake/KtraceSDK

Build And Test Demos

python3 -m unittest discover -s tests
python3 -m unittest discover -s demo/tests

Demo entrypoints from this repo root:

python3 demo/bootstrap/main.py --trace '.*'
python3 demo/exe/core/main.py --trace '*.*'
python3 demo/exe/omega/main.py --trace '*.{net,io}'

Trace CLI examples:

python3 demo/exe/core/main.py --trace '.*'
python3 demo/exe/omega/main.py --trace '*.*'
python3 demo/exe/omega/main.py --trace '*.{net,io}'
python3 demo/exe/omega/main.py --trace-namespaces
python3 demo/exe/omega/main.py --trace-channels
python3 demo/exe/omega/main.py --trace-colors

API Model

TraceLogger is the namespace-bearing source object:

import ktrace

trace = ktrace.TraceLogger("alpha")
trace.addChannel("net", ktrace.Color("DeepSkyBlue1"))
trace.addChannel("cache", ktrace.Color("Gold3"))

SDK-style Python modules will usually expose one shared trace source through a module-level helper:

_TRACE_LOGGER: ktrace.TraceLogger | None = None


def get_trace_logger() -> ktrace.TraceLogger:
    global _TRACE_LOGGER
    if _TRACE_LOGGER is not None:
        return _TRACE_LOGGER

    trace = ktrace.TraceLogger("alpha")
    trace.addChannel("net", ktrace.Color("DeepSkyBlue1"))
    _TRACE_LOGGER = trace
    return _TRACE_LOGGER

Logger owns the runtime registry, selector state, and formatting:

logger = ktrace.Logger()
logger.addTraceLogger(trace)
logger.enableChannels("alpha.*")

Behavior Highlights

  • trace output is channel-gated and disabled by default
  • info(), warn(), and error() are always visible once the trace source is attached to a Logger
  • selector matching supports local selectors, namespace-qualified selectors, wildcard segments inside qualified selectors such as *.*, and brace sets such as *.{net,io}
  • bare * is rejected; use a qualified selector such as .* or *.*
  • unmatched selectors produce warning output instead of raising
  • conflicting explicit channel-color merges are rejected when trace sources are attached to one Logger
  • invalid runtime channel queries return False rather than raising
  • makeInlineParser() exposes --trace, --trace-examples, --trace-namespaces, --trace-channels, --trace-colors, --trace-files, --trace-functions, and --trace-timestamps

Demo Layout

  • demo/bootstrap/ minimal logger and inline-parser smoke test
  • demo/sdk/{alpha,beta,gamma} reusable demo trace sources
  • demo/exe/core/ local executable tracing plus imported alpha tracing
  • demo/exe/omega/ combined local, alpha, beta, and gamma tracing

The demos are covered by subprocess-based CLI tests under demo/tests/.

Coding Agents

If you are using a coding agent, read the workspace-level agent instructions first and then follow the local repo layout.

ktrace Python

ktools-python/ktrace/docs/index.md

ktrace is the Python tracing and operational logging layer in the ktools stack.

It separates:

  • library-facing TraceLogger sources that define namespaces and channels
  • executable-facing Logger runtime state that owns selector enablement and output formatting

Quick Start

import kcli
import ktrace


logger = ktrace.Logger()

app_trace = ktrace.TraceLogger("core")
app_trace.addChannel("app", ktrace.Color("BrightCyan"))
app_trace.addChannel("startup", ktrace.Color("BrightYellow"))

logger.addTraceLogger(app_trace)

parser = kcli.Parser()
parser.addInlineParser(logger.makeInlineParser(app_trace))

argv = ["tool", "--trace", ".app"]
parser.parseOrExit(len(argv), argv)

app_trace.trace("app", "cli processing enabled")
app_trace.info("service starting")

Main Behaviors

  • trace output is channel-gated
  • operational logs from info(), warn(), and error() are always visible
  • selectors support local forms such as .app and wildcard forms such as *.*
  • conflicting explicit channel-color merges are rejected when multiple trace sources register the same qualified channel on one logger
  • invalid runtime channel queries return False
  • output formatting can include timestamps, filenames, line numbers, and function names
  • makeInlineParser() exposes the --trace* CLI surface through kcli

For the Python public surface, see api.md. For the concrete selector, merge, and formatting rules, see behavior.md.

API Guide

ktools-python/ktrace/docs/api.md

This page summarizes the Python public API in src/ktrace.

Core Types

Type Purpose
ktrace.TraceLogger Library-facing source object that owns a trace namespace and its declared channels.
ktrace.Logger Executable-facing runtime that owns channel registration, selector enablement, and formatted output.
ktrace.OutputOptions Output-format toggles for filenames, line numbers, function names, and timestamps.
ktrace.Color() Normalizes a named trace color token.

OutputOptions

options = ktrace.OutputOptions()
options.filenames = True
options.line_numbers = True
options.function_names = True
options.timestamps = True

These options affect both trace output and operational logs.

TraceLogger

Construction

trace = ktrace.TraceLogger("alpha")

The namespace must be a valid selector identifier.

Channel Registration

trace.addChannel("net")
trace.addChannel("cache", ktrace.Color("Gold3"))
trace.addChannel("deep.branch.leaf")

Channels must use dotted identifier paths.

Namespace And Enablement

trace.getNamespace()
trace.shouldTraceChannel("net")

shouldTraceChannel() returns False until the trace logger is attached to a ktrace.Logger.

Trace Output

trace.trace("net", "connected to {}", host)
trace.traceChanged("state", state_key, "state changed to {}", state)

traceChanged() suppresses repeated output only when the same call site emits the same key repeatedly.

Operational Logs

trace.info("service started")
trace.warn("retrying connection")
trace.error("startup failed")

These logs are not gated by channel selectors.

Logger

Attaching Trace Sources

logger = ktrace.Logger()
logger.addTraceLogger(app_trace)

A TraceLogger may only be attached to one Logger.

SDK-style modules will usually expose a shared trace source through a module-level getter:

_TRACE_LOGGER: ktrace.TraceLogger | None = None


def get_trace_logger() -> ktrace.TraceLogger:
    global _TRACE_LOGGER
    if _TRACE_LOGGER is not None:
        return _TRACE_LOGGER

    trace = ktrace.TraceLogger("alpha")
    trace.addChannel("net", ktrace.Color("DeepSkyBlue1"))
    _TRACE_LOGGER = trace
    return _TRACE_LOGGER

Channel Enablement

logger.enableChannel(app_trace, ".app")
logger.enableChannels("*.{net,io}")
logger.disableChannel(app_trace, ".app")
logger.disableChannels("alpha.cache")

Selector forms supported by the current Python implementation include:

  • .channel for a local channel in the provided local namespace
  • namespace.channel
  • wildcard segments inside a qualified selector, such as *.* or alpha.*.*
  • brace sets per segment, such as *.{net,io} or {alpha,beta}.*

Additional rules:

  • bare * is invalid; use a qualified selector such as .* or *.*
  • leading-dot selectors require a local namespace context
  • enableChannels(...) and disableChannels(...) accept CSV selector lists
  • unmatched selectors produce a warning log rather than raising

Querying State

logger.shouldTraceChannel(app_trace, ".app")
logger.getNamespaces()
logger.getChannels("alpha")

Output Formatting

options = logger.getOutputOptions()
options.timestamps = True
logger.setOutputOptions(options)

When filename output is enabled:

  • filenames + line_numbers renders [file:line]
  • adding function_names renders [file:line:function]

CLI Integration

parser.addInlineParser(logger.makeInlineParser(app_trace))

makeInlineParser() exposes:

  • --trace <channels>
  • --trace-examples
  • --trace-namespaces
  • --trace-channels
  • --trace-colors
  • --trace-files
  • --trace-functions
  • --trace-timestamps

ktrace Python Behavior

ktools-python/ktrace/docs/behavior.md

This page collects the Python ktrace runtime rules that matter in practice.

Trace Source Attachment

  • TraceLogger instances are library-facing sources of namespaces and channels
  • Logger owns the executable-facing runtime registry, selector state, and final output
  • a TraceLogger may only be attached to one Logger
  • SDK-style modules commonly expose one shared trace source through a module-level getter such as get_trace_logger()

When multiple trace sources register the same qualified channel on one logger:

  • duplicate default-color registrations are accepted
  • an explicit color may replace a previously-default color
  • conflicting explicit colors are rejected

Selector Semantics

Selectors are resolved against channels already registered on the logger.

Supported forms include:

  • local selectors such as .app
  • namespace-qualified selectors such as alpha.net
  • wildcard segments such as *.* or *.*.*.*
  • brace sets such as *.{net,io} or {alpha,beta}.*

Additional rules:

  • bare * is invalid; use a qualified selector such as .* or *.*
  • leading-dot selectors require a local namespace context
  • selector-list APIs accept CSV while preserving brace groups
  • empty selector lists are rejected
  • unmatched selectors emit warning output instead of raising
  • unregistered channels remain disabled even if a selector pattern would otherwise match them

Runtime Channel Queries

Logger.shouldTraceChannel(...) and TraceLogger.shouldTraceChannel(...) return False for:

  • unattached trace sources
  • unregistered channels
  • invalid runtime channel names

This keeps query helpers non-throwing in normal runtime usage.

Formatting Rules

Message formatting supports:

  • sequential {} placeholders
  • escaped braces {{ and }}
  • boolean values formatted as true and false

Invalid format strings raise ValueError, including:

  • too few arguments
  • too many arguments
  • unmatched { or }
  • unsupported tokens such as {:x}

Output Formatting

Trace output is channel-gated and disabled by default.

Operational logs from info(), warn(), and error() are always visible once the trace source is attached to a logger.

OutputOptions controls:

  • timestamps
  • filenames
  • line numbers
  • function names

These options affect both trace output and operational logs.