Skip to content

Logging Configuration ​

This guide covers PyPtP's logging. PyPtP logs through Python's standard logging module, on a logger named pyptp. Learn how to enable logging, configure output destinations, customize formats, and set up multiple handlers.

Full Example

View the complete code: 06_logging.py

Silent by Default ​

PyPtP follows Python library best practices: no logging output is produced until explicitly enabled. This prevents unexpected console spam when PyPtP is used as a dependency in larger applications.

python
from pyptp.ptp_log import logger

# This produces no output (silent by default)
logger.info("Nothing happens")

Enabling Logging ​

Basic Console Logging ​

python
from pyptp import NetworkLV
from pyptp.ptp_log import configure_logging, logger

# Enable INFO level to console
configure_logging(level="INFO")

network = NetworkLV()
logger.info("Created network: %s", network)

configure_logging() is also available as pyptp.configure_logging.

Log Levels ​

LevelValueUse Case
DEBUG10Detailed development diagnostics
INFO20General operational messages
WARNING30Potential issues that don't stop execution
ERROR40Errors affecting specific operations
CRITICAL50System-wide failures
python
# Enable DEBUG for troubleshooting
configure_logging(level="DEBUG", colorize=True)

logger.debug("This is debug information")
logger.info("This is info")
logger.warning("This is a warning")

Output Destinations ​

Every call to configure_logging() adds a handler to the pyptp logger. Call it once per destination: calling it twice for the console prints every message twice.

File Logging ​

python
from pathlib import Path

log_file = Path("pyptp.log")
configure_logging(level="INFO", sink=log_file)

A file path gets a logging.FileHandler. Extra keyword arguments such as encoding and mode are passed to it:

python
configure_logging(level="INFO", sink="pyptp.log", encoding="utf-8", mode="w")

Colours are only added on a console (a terminal stream), never in a file.

Multiple Destinations ​

Log to both console and file simultaneously:

python
# Console with colors
configure_logging(level="INFO", colorize=True)

# File with verbose output
configure_logging(level="DEBUG", sink="debug.log", colorize=False)

Custom Sinks ​

sink accepts a stream, a file path, a logging.Handler or a function:

python
import logging
import sys

# Standard error (default)
configure_logging(sink=sys.stderr)

# Standard output
configure_logging(sink=sys.stdout)

# Any handler from the logging module
configure_logging(sink=logging.StreamHandler(sys.stdout))

# Custom function, called with each formatted message
def custom_sink(message):
    # Send to external service, database, etc.
    print(f"CUSTOM: {message}")

configure_logging(sink=custom_sink)

Format Customization ​

Custom Format String ​

format_string is a standard logging format string:

python
configure_logging(
    level="INFO",
    format_string="%(asctime)s | %(levelname)s | %(message)s",
)

Default Format ​

The default format includes timestamp, level, location, and message:

2026-01-15 14:30:45 | INFO     | pyptp:from_file:123 - Network loaded

Format Placeholders ​

PlaceholderDescription
%(asctime)sTimestamp, as YYYY-MM-DD HH:MM:SS
%(levelname)sLog level name
%(name)sLogger name (pyptp)
%(module)sModule name
%(funcName)sFunction name
%(lineno)dLine number
%(message)sThe log message

See LogRecord attributes for the full list.

Using the Logger ​

Basic Logging ​

python
from pyptp.ptp_log import logger

logger.debug("Debug message")
logger.info("Info message")
logger.warning("Warning message")
logger.error("Error message")

Formatted Messages ​

The logger uses the % style of the standard logging module. Pass the values as arguments, and they are only formatted when the message is logged:

python
logger.info("Loaded %s nodes and %s cables", node_count, cable_count)
logger.info("Node %s at %.1f kV", "Sub1", 10.0)

Exception Logging ​

python
try:
    network = NetworkMV.from_file("missing.vnf")
except Exception:
    logger.exception("Failed to load network")

The exception() method automatically includes the stack trace.

Standard Logging Configuration ​

Because pyptp is an ordinary logging logger, an application that configures logging itself can include it without configure_logging():

python
import logging

logging.basicConfig(level=logging.WARNING)
logging.getLogger("pyptp").setLevel(logging.INFO)

Configuration Patterns ​

Development Setup ​

python
# Verbose console output with colors
configure_logging(level="DEBUG", colorize=True)

Production Setup ​

python
# File logging, minimal console output
configure_logging(level="WARNING", colorize=False)  # Console
configure_logging(level="INFO", sink="/var/log/pyptp.log", colorize=False)  # File

Testing Setup ​

python
# Capture logs for assertions
import io

log_capture = io.StringIO()
configure_logging(level="DEBUG", sink=log_capture, colorize=False)

# Run code that logs...

log_output = log_capture.getvalue()
assert "expected message" in log_output

Complete Example ​

python
"""Logging Configuration Examples.

Shows how to configure PyPtP logging for different use cases.
"""

from pathlib import Path

from pyptp import NetworkLV
from pyptp.ptp_log import configure_logging, logger

# Example 1: Enable console logging at INFO level
configure_logging(level="INFO")

network = NetworkLV()
logger.info("Created network: %s", network)

# Example 2: Enable DEBUG logging for troubleshooting
configure_logging(level="DEBUG", colorize=True)

logger.debug("This is debug information")
logger.info("This is info")
logger.warning("This is a warning")

# Example 3: Log to file
log_file = Path("pyptp.log")
configure_logging(level="INFO", sink=log_file)

# Example 4: Custom format
configure_logging(
    level="INFO",
    format_string="%(asctime)s | %(levelname)s | %(message)s",
)

# Example 5: Multiple sinks (console + file)
configure_logging(level="INFO", colorize=True)
configure_logging(level="DEBUG", sink="debug.log", colorize=False)

# Note: PyPtP is silent by default - no logging unless configured