Metrics Utilities¶
Public API for performance measurement: timing, memory tracking, call statistics, and step tracking. These utilities help profile code execution and identify bottlenecks.
Tip
Pair this reference with Metrics for the feature guide.
Quick overview¶
@metricsdecorator provides unified time + memory tracking with Rich output@call_statstracks call count, avg/min/max duration across multiple invocationsmetrics_contextcontext manager measures code blocks inlineStopwatchprovides manual lap timing with summary displayStep tracking with
step=Trueassigns incrementing numbers for pipeline visualizationConfiguration follows the standard priority chain: decorator args >
kstlib.conf.yml> defaults
Configuration cascade¶
The module consults the loaded config for default values. A minimal config block:
metrics:
colors: true
defaults:
time: true
memory: true
step: false
thresholds:
time_warn: 5
time_crit: 30
Override any of these per call:
from kstlib.metrics import metrics
@metrics(memory=False, step=True)
def my_step():
pass
Usage patterns¶
Basic decorator usage¶
from kstlib.metrics import metrics
@metrics
def process_data(items: list) -> int:
return sum(items)
result = process_data([1, 2, 3])
# Output: [process_data (script.py:3)] | 0.001s | Peak: 64 KB
Step tracking for pipelines¶
from kstlib.metrics import metrics, metrics_summary, clear_metrics
clear_metrics()
@metrics(step=True)
def load():
pass
@metrics(step=True, title="Transform")
def transform():
pass
load()
transform()
metrics_summary()
Call statistics¶
from kstlib.metrics import call_stats, print_all_call_stats
@call_stats
def api_call():
return fetch()
for _ in range(10):
api_call()
print_all_call_stats()
Context manager¶
from kstlib.metrics import metrics_context
with metrics_context("Data loading") as m:
data = load_data()
print(f"Took {m.elapsed_seconds:.3f}s, peak {m.peak_memory_formatted}")
Manual stopwatch¶
from kstlib.metrics import Stopwatch
sw = Stopwatch("Pipeline")
sw.start()
# ... work ...
sw.lap("Step 1")
# ... work ...
sw.lap("Step 2")
sw.stop()
sw.summary()
Module reference¶
Metrics and timing utilities for measuring execution performance.
This module provides a unified decorator and tools for:
Time Measurement: Track execution time of functions and code blocks
Memory Tracking: Monitor peak memory usage with tracemalloc
Call Statistics: Track call count, avg/min/max durations
Step Tracking: Numbered step tracking with summary
All behavior is config-driven with sensible defaults.
Examples
Unified metrics decorator (config defaults):
>>> from kstlib.metrics import metrics
>>> @metrics
... def slow_function():
... return sum(range(1000000))
>>> slow_function()
[slow_function] ⏱ 0.023s | 🧠 Peak: 128 KB
Step tracking for pipelines:
>>> from kstlib.metrics import metrics, metrics_summary, clear_metrics
>>> @metrics(step=True)
... def load_data():
... pass
>>> @metrics(step=True, title="Process records")
... def process():
... pass
>>> load_data()
[STEP 1] load_data ⏱ 0.001s
>>> process()
[STEP 2] Process records ⏱ 0.002s
>>> metrics_summary()
# Displays summary table with all steps
Context manager usage:
>>> from kstlib.metrics import metrics_context
>>> with metrics_context("Data loading"):
... data = load_large_file()
[Data loading] ⏱ 2.34s | 🧠 Peak: 512 MB
Manual stopwatch:
>>> from kstlib.metrics import Stopwatch
>>> sw = Stopwatch("Pipeline")
>>> sw.start()
>>> # ... work ...
>>> sw.lap("Step 1")
>>> sw.stop()
>>> sw.summary()
- class kstlib.metrics.CallStats(name, call_count=0, total_time=0.0, min_time=inf, max_time=0.0, _lock=<factory>)[source]
Bases:
objectStatistics for tracked function calls.
Examples
>>> stats = CallStats("my_func") >>> stats.record(0.5) >>> stats.record(1.0) >>> stats.call_count 2 >>> stats.avg_time 0.75
- name: str
- call_count: int = 0
- total_time: float = 0.0
- min_time: float = inf
- max_time: float = 0.0
- record(self, elapsed: 'float') 'None' -> None[source]
Record a call duration.
- property avg_time: float
Return average call duration.
- reset(self) 'None' -> None[source]
Reset all statistics.
- __str__(self) 'str' -> str[source]
Return human-readable summary with Rich colors.
- __init__(self, name: 'str', call_count: 'int' = 0, total_time: 'float' = 0.0, min_time: 'float' = inf, max_time: 'float' = 0.0, _lock: 'threading.Lock' = <factory>) None -> None
- exception kstlib.metrics.MetricsError[source]
Bases:
KstlibErrorBase exception for metrics-related errors.
Examples
>>> raise MetricsError("Something went wrong") Traceback (most recent call last): ... kstlib.metrics.exceptions.MetricsError: Something went wrong
- class kstlib.metrics.MetricsRecord(number, title, elapsed_seconds=0.0, peak_memory_bytes=None, function='', module='', file='', line=0)[source]
Bases:
objectRecord of a metrics measurement.
- number
Step number (if step=True).
- Type:
int | None
- title
Display title.
- Type:
- elapsed_seconds
Execution time.
- Type:
- peak_memory_bytes
Peak memory usage.
- Type:
int | None
- function
Function name.
- Type:
- module
Module name.
- Type:
- file
Source file.
- Type:
- line
Source line.
- Type:
- title: str
- elapsed_seconds: float = 0.0
- function: str = ''
- module: str = ''
- file: str = ''
- line: int = 0
- property elapsed_formatted: str
Return formatted elapsed time.
- __init__(self, number: 'int | None', title: 'str', elapsed_seconds: 'float' = 0.0, peak_memory_bytes: 'int | None' = None, function: 'str' = '', module: 'str' = '', file: 'str' = '', line: 'int' = 0) None -> None
- class kstlib.metrics.Stopwatch(name='Stopwatch', _start_time=None, _lap_start=None, _laps=<factory>, _stopped=False, _lock=<factory>)[source]
Bases:
objectManual stopwatch for timing code sections.
For cases where you need explicit start/stop/lap control.
Examples
>>> sw = Stopwatch("Pipeline") >>> _ = sw.start() >>> # ... work ... >>> sw.lap("Step 1") >>> _ = sw.stop() >>> sw.summary()
- name: str = 'Stopwatch'
- start(self) 'Stopwatch' -> Stopwatch[source]
Start the stopwatch.
- lap(self, name: 'str', *, print_result: 'bool' = True, track_memory: 'bool' = False) 'float' -> float[source]
Record a lap time.
- stop(self) 'float' -> float[source]
Stop the stopwatch.
- property total_elapsed: float
Get total elapsed time.
- reset(self) 'None' -> None[source]
Reset the stopwatch.
- summary(self, *, show_percentages: 'bool' = True) 'None' -> None[source]
Print a summary of all laps.
- __init__(self, name: 'str' = 'Stopwatch', _start_time: 'float | None' = None, _lap_start: 'float | None' = None, _laps: 'list[tuple[str, float, int | None]]' = <factory>, _stopped: 'bool' = False, _lock: 'threading.RLock' = <factory>) None -> None
- kstlib.metrics.call_stats(func: 'Callable[P, R] | None' = None, /, *, name: 'str | None' = None, print_on_call: 'bool' = False) 'Callable[P, R] | Callable[[Callable[P, R]], Callable[P, R]]' -> Callable[P, R] | Callable[[Callable[P, R]], Callable[P, R]][source]
Track call statistics for the decorated function.
Tracks call count, total time, min, max, and average duration. Use get_call_stats() or print_all_call_stats() to access results.
Examples
>>> @call_stats ... def api_call(): ... pass >>> api_call() >>> api_call() >>> stats = get_call_stats("api_call") >>> stats.call_count 2
- kstlib.metrics.clear_metrics() 'None' -> None[source]
Clear all recorded metrics and reset step counter.
Examples
>>> clear_metrics()
- kstlib.metrics.get_all_call_stats() 'dict[str, CallStats]' -> dict[str, CallStats][source]
Get all tracked call statistics.
- kstlib.metrics.get_call_stats(func_name: 'str') 'CallStats | None' -> CallStats | None[source]
Get call statistics for a tracked function.
- kstlib.metrics.get_metrics() 'list[MetricsRecord]' -> list[MetricsRecord][source]
Get all recorded metrics.
- Returns:
List of MetricsRecord objects.
- Return type:
list[MetricsRecord]
Examples
>>> records = get_metrics() >>> isinstance(records, list) True
- kstlib.metrics.metrics(func_or_title: 'Callable[P, R] | str | None' = None, /, *, title: 'str | None' = None, time: 'bool | None' = None, memory: 'bool | None' = None, step: 'bool | None' = None, print_result: 'bool' = True) 'Callable[P, R] | Callable[[Callable[P, R]], Callable[P, R]]' -> Callable[P, R] | Callable[[Callable[P, R]], Callable[P, R]][source]
Unified decorator for timing, memory tracking, and step counting.
Config-driven with sensible defaults. All options can be overridden.
- Parameters:
func_or_title (Callable[P, R] | str | None) – Function to decorate or custom title string.
title (str | None) – Custom title (alternative to positional).
time (bool | None) – Track execution time (default from config, typically True).
memory (bool | None) – Track peak memory (default from config, typically True).
step (bool | None) – Enable step numbering (default from config, typically False).
print_result (bool) – Whether to print result to stderr.
- Returns:
Decorated function.
- Return type:
Callable[P, R] | Callable[[Callable[P, R]], Callable[P, R]]
Examples
Default behavior (time + memory from config):
>>> @metrics ... def process(): ... return sum(range(1000)) >>> process() [process] ⏱ 0.001s | 🧠 Peak: 64 KB
Time only:
>>> @metrics(memory=False) ... def quick(): ... pass
With step numbering:
>>> @metrics(step=True) ... def step1(): ... pass >>> step1() [STEP 1] step1 ⏱ 0.001s | 🧠 Peak: 32 KB
Custom title:
>>> @metrics("Loading configuration") ... def load_config(): ... pass
- kstlib.metrics.metrics_context(title: 'str', *, time: 'bool | None' = None, memory: 'bool | None' = None, step: 'bool | None' = None, print_result: 'bool' = True) 'Generator[MetricsRecord, None, None]' -> Generator[MetricsRecord, None, None][source]
Context manager for metrics tracking.
- Parameters:
- Yields:
MetricsRecord being tracked.
Examples
>>> with metrics_context("Loading data") as m: ... data = load_file() [Loading data] ⏱ 1.23s | 🧠 Peak: 256 MB
- kstlib.metrics.metrics_summary(*, show_percentages: 'bool' = True, style: 'str' = 'table') 'None' -> None[source]
Print summary of all recorded metrics (step=True records).
Uses kstlib.ui.tables for pretty output.
- Parameters:
Examples
>>> metrics_summary()
- kstlib.metrics.print_all_call_stats() 'None' -> None[source]
Print all tracked call statistics to stderr.
- kstlib.metrics.reset_all_call_stats() 'None' -> None[source]
Reset all tracked call statistics.
Exceptions¶
Exceptions for the metrics module.
- exception kstlib.metrics.exceptions.MetricsError[source]
Bases:
KstlibErrorBase exception for metrics-related errors.
Examples
>>> raise MetricsError("Something went wrong") Traceback (most recent call last): ... kstlib.metrics.exceptions.MetricsError: Something went wrong