nlsq.logging module

Debug logging and monitoring utilities.

Comprehensive logging system for NLSQ package.

This module provides structured logging for monitoring package operations, error tracking, and debugging. Key features:

  • Operation tracking with unique IDs for tracing

  • Structured logging with consistent formats

  • Performance metrics and timing

  • Memory usage monitoring

  • Error context with actionable suggestions

Environment Variables

NLSQ_DEBUGstr

Set to “1” to enable debug mode with detailed logging

NLSQ_VERBOSEstr

Set to “1” to enable verbose mode (INFO level)

NLSQ_LOG_DIRstr

Directory for debug log files (default: current directory)

NLSQ_TRACE_JAXstr

Set to “1” to trace JAX compilation events

NLSQ_SAVE_ITERATIONSstr

Directory to save optimization iteration history

Example

>>> from nlsq.utils.logging import get_logger
>>> logger = get_logger("my_module")
>>> with logger.operation("curve_fit", n_points=1000, n_params=3):
...     # Your fitting code here
...     logger.info("Fitting completed successfully")
class nlsq.utils.logging.LogLevel(*values)[source]

Bases: IntEnum

Custom log levels for NLSQ.

DEBUG = 10
INFO = 20
PERFORMANCE = 25
WARNING = 30
ERROR = 40
CRITICAL = 50
class nlsq.utils.logging.NLSQLogger(name, level=LogLevel.INFO)[source]

Bases: object

Comprehensive logger for NLSQ optimization routines.

Features: - Operation tracking with unique IDs - Structured logging with consistent formats - Performance tracking and timing - Memory usage monitoring - JAX compilation event logging - Debug mode with detailed tracing

Examples

>>> logger = NLSQLogger("curve_fit")
>>> with logger.operation("fit", dataset_size=10000):
...     logger.info("Starting optimization")
...     # ... fitting code ...
...     logger.fit_complete(iterations=50, final_cost=1.2e-6)
__init__(name, level=LogLevel.INFO)[source]

Initialize NLSQ logger.

Parameters:
  • name (str) – Logger name, typically the module name

  • level (int | LogLevel) – Initial logging level

timers: dict[str, float]
optimization_history: deque[dict[str, Any]]
debug(message, **kwargs)[source]

Log debug message with optional structured data.

info(message, **kwargs)[source]

Log info message with optional structured data.

warning(message, exc_info=False, **kwargs)[source]

Log warning message with optional structured data.

error(message, exc_info=False, **kwargs)[source]

Log error message with optional exception info.

critical(message, exc_info=True, **kwargs)[source]

Log critical error with exception info.

performance(message, **kwargs)[source]

Log performance-related message.

operation(name, **context)[source]

Context manager for tracking operations with unique IDs.

Provides operation-level context for all log messages within the block, including timing and memory usage tracking.

Parameters:
  • name (str) – Name of the operation (e.g., “curve_fit”, “jacobian”)

  • **context – Additional context to log (e.g., n_points, n_params)

Examples

>>> with logger.operation("curve_fit", n_points=10000, n_params=5):
...     # All logs within this block include operation context
...     logger.info("Starting optimization")
fit_start(n_points, n_params, method='trf', bounds='none', **kwargs)[source]

Log the start of a fitting operation.

Parameters:
  • n_points (int) – Number of data points

  • n_params (int) – Number of parameters to fit

  • method (str) – Optimization method

  • bounds (str) – Bounds type (“none”, “bounded”, “semi-bounded”)

fit_complete(success=True, iterations=None, final_cost=None, termination=None, **kwargs)[source]

Log completion of a fitting operation.

Parameters:
  • success (bool) – Whether the fit converged successfully

  • iterations (int, optional) – Number of iterations taken

  • final_cost (float, optional) – Final cost/residual value

  • termination (str, optional) – Termination reason

optimization_step(iteration, cost, gradient_norm=None, step_size=None, nfev=None, **kwargs)[source]

Log optimization iteration details.

Parameters:
  • iteration (int) – Current iteration number

  • cost (float) – Current cost/loss value

  • gradient_norm (float, optional) – Norm of the gradient

  • step_size (float, optional) – Size of the step taken

  • nfev (int, optional) – Number of function evaluations

  • **kwargs – Additional metrics to log

convergence(reason, iterations, final_cost, time_elapsed=None, **kwargs)[source]

Log convergence information.

Parameters:
  • reason (str) – Reason for convergence

  • iterations (int) – Total iterations

  • final_cost (float) – Final cost value

  • time_elapsed (float, optional) – Total time taken

  • **kwargs – Additional convergence metrics

numerical_issue(issue_type, details, suggestion=None, **kwargs)[source]

Log numerical issues with actionable suggestions.

Parameters:
  • issue_type (str) – Type of issue (e.g., “ill-conditioned”, “overflow”, “nan”)

  • details (str) – Description of the issue

  • suggestion (str, optional) – Suggested fix or action

memory_usage(label='current')[source]

Log current memory usage.

Parameters:

label (str) – Label for this memory checkpoint

jax_compilation(function_name, input_shape=None, compilation_time=None, **kwargs)[source]

Log JAX compilation events.

Parameters:
  • function_name (str) – Name of function being compiled

  • input_shape (tuple, optional) – Shape of input data

  • compilation_time (float, optional) – Time taken to compile

  • **kwargs – Additional compilation details

timer(name, log_result=True)[source]

Context manager for timing code sections.

Parameters:
  • name (str) – Name of the timed section

  • log_result (bool) – Whether to log the timing result

Examples

>>> with logger.timer('jacobian_computation'):
...     J = compute_jacobian(x)
matrix_info(name, matrix, compute_condition=False)[source]

Log information about a matrix.

Parameters:
  • name (str) – Name of the matrix

  • matrix (np.ndarray) – The matrix to analyze

  • compute_condition (bool) – Whether to compute condition number (expensive)

data_summary(x, y, sigma=None)[source]

Log summary statistics of input data.

Parameters:
  • x (np.ndarray) – Independent variable data

  • y (np.ndarray) – Dependent variable data

  • sigma (np.ndarray, optional) – Uncertainty/weights

parameter_update(params, param_names=None)[source]

Log parameter values during optimization.

Parameters:
  • params (np.ndarray) – Current parameter values

  • param_names (list[str], optional) – Names for each parameter

save_iteration_data(output_dir=None)[source]

Save optimization history to file.

Parameters:

output_dir (str, optional) – Directory to save data. Uses NLSQ_SAVE_ITERATIONS env var if not provided.

nlsq.utils.logging.get_logger(name, level=LogLevel.INFO)[source]

Get or create a logger for the given name (thread-safe).

Parameters:
  • name (str) – Logger name (will be prefixed with “nlsq.” if not already)

  • level (int | LogLevel) – Logging level

Returns:

Logger instance

Return type:

NLSQLogger

Examples

>>> logger = get_logger("my_module")
>>> logger.info("Processing started", n_items=100)
nlsq.utils.logging.set_global_level(level)[source]

Set logging level for all NLSQ loggers.

Parameters:

level (int | LogLevel) – New logging level

nlsq.utils.logging.enable_debug_mode()[source]

Enable debug mode with detailed logging.

Sets NLSQ_DEBUG=1 and configures all loggers for DEBUG level output.

nlsq.utils.logging.enable_verbose_mode()[source]

Enable verbose mode with INFO level logging.

Sets NLSQ_VERBOSE=1 for detailed operational messages.

nlsq.utils.logging.enable_performance_tracking()[source]

Enable performance tracking mode.

Enables JAX tracing and iteration history saving.