Logging (rheojax.logging)

Structured logging system for monitoring and debugging RheoJAX operations.

Configuration

configure_logging

rheojax.logging.configure_logging(level='INFO', format='standard', file=None, colorize=True, **kwargs)[source]

Configure the RheoJAX logging system.

This function should be called once at application startup. Subsequent calls will reconfigure the logging system.

Parameters:
  • level (str) – Global log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)

  • format (str) – Output format (standard, detailed, json, scientific)

  • file (str | None) – Path to log file (None disables file logging)

  • colorize (bool) – Enable colored console output

  • **kwargs – Additional LogConfig parameters

Return type:

LogConfig

Returns:

The configured LogConfig instance.

Example

>>> from rheojax.logging import configure_logging
>>> configure_logging(level="DEBUG", file="rheojax.log")

Configure the RheoJAX logging system.

Quick Start:

from rheojax.logging import configure_logging

# Basic configuration
configure_logging(level="INFO")

# Verbose debugging
configure_logging(level="DEBUG")

# With file output
configure_logging(level="INFO", log_file="rheojax.log")

get_logger

rheojax.logging.get_logger(name, **context)[source]

Get a RheoJAX logger for the given name.

Creates a new logger or returns a cached instance. The logger is automatically configured based on the current logging configuration.

Note

The cache is process-global: all modules share it, and clear_logger_cache() affects every caller.

Parameters:
  • name (str) – Logger name (typically __name__).

  • **context – Default context to bind to the logger. Values must be representable as strings for cache keying.

Return type:

RheoJAXLogger

Returns:

RheoJAXLogger instance.

Example

>>> from rheojax.logging import get_logger
>>> logger = get_logger(__name__)
>>> logger.info("Model fitted", R2=0.9987)

Get a logger instance for the specified name.

from rheojax.logging import get_logger

logger = get_logger(__name__)
logger.info("Starting model fitting", model="Maxwell")
logger.debug("Iteration 100", cost=1e-5)

LogConfig

class rheojax.logging.LogConfig(level='INFO', format=LogFormat.STANDARD, console=True, file=None, file_max_bytes=10000000, file_backup_count=5, subsystem_levels=<factory>, lazy_formatting=True, include_timestamps=True, include_thread=False, colorize=True)[source]

Bases: object

RheoJAX logging configuration.

level

Global log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)

format

Output format (standard, detailed, json, scientific)

console

Enable console output

file

Path to log file (None disables file logging)

file_max_bytes

Maximum log file size before rotation (default 10MB)

file_backup_count

Number of backup files to keep (default 5)

subsystem_levels

Per-subsystem log level overrides

lazy_formatting

Enable lazy evaluation of log arguments

include_timestamps

Include timestamps in log output

include_thread

Include thread name in log output

colorize

Enable colored console output

level: str = 'INFO'
format: LogFormat | str = 'standard'
console: bool = True
file: Path | str | None = None
file_max_bytes: int = 10000000
file_backup_count: int = 5
subsystem_levels: dict[str, str]
lazy_formatting: bool = True
include_timestamps: bool = True
include_thread: bool = False
colorize: bool = True
__post_init__()[source]

Validate configuration after initialization.

Return type:

None

classmethod from_env()[source]

Create configuration from environment variables.

Reads the following environment variables:
  • RHEOJAX_LOG_LEVEL: Global log level

  • RHEOJAX_LOG_FILE: Path to log file

  • RHEOJAX_LOG_FORMAT: Output format

  • RHEOJAX_LOG_COLORIZE: Enable colors (true/false)

  • RHEOJAX_LOG_<SUBSYSTEM>: Per-subsystem levels

Return type:

LogConfig

Returns:

LogConfig instance with environment-based settings.

get_level(logger_name)[source]

Get the effective log level for a logger.

Parameters:

logger_name (str) – Full logger name (e.g., “rheojax.models.maxwell”)

Return type:

int

Returns:

Logging level as integer.

__init__(level='INFO', format=LogFormat.STANDARD, console=True, file=None, file_max_bytes=10000000, file_backup_count=5, subsystem_levels=<factory>, lazy_formatting=True, include_timestamps=True, include_thread=False, colorize=True)

LogFormat

class rheojax.logging.LogFormat(*values)[source]

Bases: Enum

Available log output formats.

STANDARD = 'standard'
DETAILED = 'detailed'
JSON = 'json'
SCIENTIFIC = 'scientific'

Environment Variables

The logging system respects these environment variables:

Environment Variables

Variable

Description

Default

RHEOJAX_LOG_LEVEL

Global log level (DEBUG, INFO, WARNING, ERROR)

INFO

RHEOJAX_LOG_FILE

Path to log file (enables file logging)

None

RHEOJAX_LOG_FORMAT

Output format (standard, detailed, json)

standard

Context Managers

Operation Logging

Context managers for automatic timing and context tracking:

log_fit

rheojax.logging.log_fit(logger, model, data_shape=None, test_mode='unknown', level=20, **kwargs)[source]

Context manager for model fitting operations.

Specialized wrapper around log_operation for model fitting.

Parameters:
  • logger (Logger | RheoJAXLogger) – Logger instance to use.

  • model (str) – Model name or class name.

  • data_shape (tuple[int, ...] | None) – Shape of input data (optional).

  • test_mode (str) – Test mode (relaxation, creep, oscillation, flow).

  • level (int) – Log level (default INFO).

  • **kwargs – Additional context.

Yields:

Dictionary for adding completion context (e.g., R2, parameters).

Example

>>> with log_fit(logger, "Maxwell", data_shape=(100,), test_mode="relaxation") as ctx:
...     result = model._fit(x, y)
...     ctx["R2"] = result.r_squared
...     ctx["n_iterations"] = result.iterations

Log model fitting operations with timing.

from rheojax.logging import log_fit, get_logger

logger = get_logger(__name__)

with log_fit(logger, model="Maxwell", data_shape=(100,)) as ctx:
    result = model.fit(x, y)
    ctx["R2"] = result.r_squared  # Add to completion log

log_bayesian

rheojax.logging.log_bayesian(logger, model, num_warmup, num_samples, num_chains=1, level=20, **kwargs)[source]

Context manager for Bayesian inference operations.

Specialized wrapper for MCMC sampling operations.

Parameters:
  • logger (Logger | RheoJAXLogger) – Logger instance to use.

  • model (str) – Model name.

  • num_warmup (int) – Number of warmup samples.

  • num_samples (int) – Number of posterior samples.

  • num_chains (int) – Number of MCMC chains.

  • level (int) – Log level (default INFO).

  • **kwargs – Additional context.

Yields:

Dictionary for adding completion context (e.g., R-hat, ESS).

Example

>>> with log_bayesian(logger, "Maxwell", num_warmup=1000, num_samples=2000) as ctx:
...     result = model.fit_bayesian(x, y)
...     ctx["r_hat_max"] = compute_rhat(result)
...     ctx["ess_min"] = compute_ess(result)
...     ctx["divergences"] = result.divergences

Log Bayesian inference operations.

from rheojax.logging import log_bayesian, get_logger

logger = get_logger(__name__)

with log_bayesian(logger, "Maxwell", num_warmup=1000, num_samples=2000) as ctx:
    result = model.fit_bayesian(x, y)
    ctx["r_hat"] = compute_rhat(result)
    ctx["divergences"] = result.divergences

log_transform

rheojax.logging.log_transform(logger, transform, input_shape=None, level=20, **kwargs)[source]

Context manager for transform operations.

Specialized wrapper for data transformation operations.

Parameters:
  • logger (Logger | RheoJAXLogger) – Logger instance to use.

  • transform (str) – Transform name.

  • input_shape (tuple[int, ...] | None) – Shape of input data.

  • level (int) – Log level (default INFO).

  • **kwargs – Additional context.

Yields:

Dictionary for adding completion context (e.g., output_shape).

Example

>>> with log_transform(logger, "mastercurve", input_shape=(10, 100)) as ctx:
...     result = transform.transform(datasets)
...     ctx["output_shape"] = result.shape
...     ctx["shift_factors"] = len(shift_factors)

Log data transformation operations.

log_io

rheojax.logging.log_io(logger, operation, filepath=None, level=20, **kwargs)[source]

Context manager for I/O operations.

Specialized wrapper for file read/write operations.

Parameters:
  • logger (Logger | RheoJAXLogger) – Logger instance to use.

  • operation (str) – I/O operation type (read, write, load, save).

  • filepath (str | None) – Path to file being accessed.

  • level (int) – Log level (default INFO).

  • **kwargs – Additional context.

Yields:

Dictionary for adding completion context (e.g., records, file_size).

Example

>>> with log_io(logger, "read", filepath="data.csv") as ctx:
...     data = read_csv(filepath)
...     ctx["records"] = len(data)
...     ctx["columns"] = list(data.columns)

Log I/O operations (file reading/writing).

log_pipeline_stage

rheojax.logging.log_pipeline_stage(logger, stage, pipeline_id=None, level=20, **kwargs)[source]

Context manager for pipeline stage execution.

Parameters:
  • logger (Logger | RheoJAXLogger) – Logger instance to use.

  • stage (str) – Pipeline stage name.

  • pipeline_id (str | None) – Optional pipeline identifier.

  • level (int) – Log level (default INFO).

  • **kwargs – Additional context.

Yields:

Dictionary for adding completion context.

Example

>>> with log_pipeline_stage(logger, "fit", pipeline_id="pipe_001") as ctx:
...     result = pipeline.fit()
...     ctx["model"] = result.model_name

Log pipeline stage execution.

log_operation

rheojax.logging.log_operation(logger, operation, level=20, **context)[source]

Context manager for logging operation start/end with timing.

Automatically logs when an operation starts and completes, including elapsed time and any exceptions that occur.

Parameters:
  • logger (Logger | RheoJAXLogger) – Logger instance to use.

  • operation (str) – Name of the operation being performed.

  • level (int) – Log level for start/end messages (default INFO).

  • **context – Additional context to include in log messages.

Yields:

Dictionary that can be used to add additional context to the completion log message.

Example

>>> with log_operation(logger, "fitting", model="Maxwell"):
...     result = model.fit(x, y)
14:32:05 | INFO | rheojax.models | fitting started | model=Maxwell
14:32:07 | INFO | rheojax.models | fitting completed | model=Maxwell | elapsed_seconds=2.15
Example with additional context:
>>> with log_operation(logger, "fitting", model="Maxwell") as ctx:
...     result = model.fit(x, y)
...     ctx["R2"] = result.r_squared
14:32:05 | INFO | rheojax.models | fitting started | model=Maxwell
14:32:07 | INFO | rheojax.models | fitting completed | model=Maxwell | R2=0.9987 | elapsed_seconds=2.15

Generic operation logging context manager.

Formatters

StandardFormatter

class rheojax.logging.StandardFormatter(colorize=True)[source]

Bases: Formatter

Human-readable format for console output.

Format: HH:MM:SS | LEVEL | logger.name | message

Supports optional colorization for terminal output.

Standard log format: LEVEL - message [key=value ...]

FORMAT = '%(asctime)s | %(levelname)-8s | %(name)s | %(message)s'
DATE_FORMAT = '%H:%M:%S'
__init__(colorize=True)[source]

Initialize the formatter.

Parameters:

colorize (bool) – Enable ANSI color codes in output.

format(record)[source]

Format the log record.

Parameters:

record (LogRecord) – LogRecord instance to format.

Return type:

str

Returns:

Formatted log string.

DetailedFormatter

class rheojax.logging.DetailedFormatter(colorize=False)[source]

Bases: Formatter

Detailed format with file/line info for debugging.

Format: YYYY-MM-DD HH:MM:SS.ffffff | LEVEL | logger:line | func | message

Detailed format with timestamp, logger name, file location.

FORMAT = '%(asctime)s | %(levelname)-8s | %(name)s:%(lineno)d | %(funcName)s | %(message)s'
DATE_FORMAT = '%Y-%m-%d %H:%M:%S'
__init__(colorize=False)[source]

Initialize the formatter.

Parameters:

colorize (bool) – Enable ANSI color codes (disabled by default for files).

formatTime(record, datefmt=None)[source]

Format timestamp with true microsecond precision.

Parameters:
  • record (LogRecord) – LogRecord instance.

  • datefmt (str | None) – Date format string (unused, uses DATE_FORMAT).

Return type:

str

Returns:

Timestamp string with microseconds.

format(record)[source]

Format the log record with microseconds.

Parameters:

record (LogRecord) – LogRecord instance to format.

Return type:

str

Returns:

Formatted log string.

JSONFormatter

class rheojax.logging.JSONFormatter(fmt=None, datefmt=None, style='%', validate=True, *, defaults=None)[source]

Bases: Formatter

JSON format for machine parsing and log aggregation.

Output: {“timestamp”: “…”, “level”: “…”, “logger”: “…”, …}

JSON output for machine parsing and log aggregation.

format(record)[source]

Format the log record as JSON.

Parameters:

record (LogRecord) – LogRecord instance to format.

Return type:

str

Returns:

JSON-formatted log string.

ScientificFormatter

class rheojax.logging.ScientificFormatter(colorize=False)[source]

Bases: DetailedFormatter

Format optimized for scientific computing output.

Provides consistent scientific notation for numerical values and special handling for array shapes and dtypes.

Scientific notation for numerical values.

Handlers

RheoJAXStreamHandler

class rheojax.logging.RheoJAXStreamHandler(stream=None, immediate_flush=True)[source]

Bases: StreamHandler

Enhanced stream handler with flush control.

Provides immediate flushing for interactive use and buffered output for batch processing.

Console output handler with optional color support.

__init__(stream=None, immediate_flush=True)[source]

Initialize the handler.

Parameters:
  • stream – Output stream (default: sys.stderr)

  • immediate_flush (bool) – Flush after each log message

emit(record)[source]

Emit a log record.

Parameters:

record (LogRecord) – LogRecord to emit.

Return type:

None

RheoJAXRotatingFileHandler

class rheojax.logging.RheoJAXRotatingFileHandler(filename, max_bytes=10000000, backup_count=5, encoding='utf-8')[source]

Bases: RotatingFileHandler

Enhanced rotating file handler with UTF-8 encoding.

Automatically handles log rotation and maintains backup files.

Rotating file handler for log rotation.

__init__(filename, max_bytes=10000000, backup_count=5, encoding='utf-8')[source]

Initialize the rotating file handler.

Parameters:
  • filename (Path | str) – Path to log file.

  • max_bytes (int) – Maximum file size before rotation (default 10MB).

  • backup_count (int) – Number of backup files to keep (default 5).

  • encoding (str) – File encoding (default UTF-8).

RheoJAXMemoryHandler

class rheojax.logging.RheoJAXMemoryHandler(capacity=1000, flush_level=40, target=None)[source]

Bases: MemoryHandler

Memory handler for buffered logging.

Useful for batch operations where you want to collect logs and flush them periodically or at the end of an operation.

In-memory buffer for log capture and testing.

__init__(capacity=1000, flush_level=40, target=None)[source]

Initialize the memory handler.

Parameters:
  • capacity (int) – Number of log records to buffer.

  • flush_level (int) – Level that triggers immediate flush.

  • target (Handler | None) – Target handler to flush to.

shouldFlush(record)[source]

Check if buffer should be flushed.

Extends stdlib behavior: when no target is set, caps the buffer at capacity by dropping the oldest records to prevent unbounded memory growth. With a target, delegates to stdlib MemoryHandler.

Parameters:

record (LogRecord) – Current log record.

Return type:

bool

Returns:

True if buffer should be flushed.

Examples

Basic Setup

from rheojax.logging import configure_logging, get_logger

# Configure once at startup
configure_logging(level="INFO")

# Get logger in each module
logger = get_logger(__name__)

# Log with structured data
logger.info("Model fitted", model="Maxwell", R2=0.9987, time=1.23)
logger.debug("Parameter values", G0=1e5, eta=1000)

Production Configuration

from rheojax.logging import configure_logging

configure_logging(
    level="INFO",
    log_file="/var/log/rheojax/app.log",
    format="json",  # Machine-readable
    max_bytes=10_000_000,  # 10 MB rotation
    backup_count=5
)

Debugging Workflow

import os

# Enable debug logging via environment
os.environ["RHEOJAX_LOG_LEVEL"] = "DEBUG"

from rheojax.logging import configure_logging, get_logger, log_fit

configure_logging()  # Uses environment variable
logger = get_logger(__name__)

# All operations now logged at debug level
with log_fit(logger, "FractionalMaxwell", data_shape=(500,)) as ctx:
    result = model.fit(x, y)
    ctx["iterations"] = result.nit
    ctx["final_cost"] = result.fun

Integration with Model Fitting

from rheojax.logging import (
    configure_logging,
    get_logger,
    log_fit,
    log_bayesian,
)
from rheojax.models import Maxwell

configure_logging(level="INFO")
logger = get_logger(__name__)

model = Maxwell()

# NLSQ fitting with logging
with log_fit(logger, "Maxwell", data_shape=x.shape) as ctx:
    model.fit(x, y)
    ctx["R2"] = model.score(x, y)

# Bayesian inference with logging
with log_bayesian(logger, "Maxwell", num_samples=2000) as ctx:
    result = model.fit_bayesian(x, y, num_samples=2000)

    ctx["r_hat"] = max(result.diagnostics["r_hat"].values())
    ctx["divergences"] = result.diagnostics.get("divergences", 0)

See Also