Modern QA2026Implementing Structured Logging (Python) — tiles
Log inJoin
22 / 67 · 06 Observability-Driven Testing · Structured Logging Best Practices← prev⊞ allnext →☰ Read as one page

4.3Implementing Structured Logging (Python)

# structured_logging_setup.py
import structlog
import logging

# Configure structlog for JSON output
structlog.configure(
    processors=[
        structlog.contextvars.merge_contextvars,      # thread-safe context
        structlog.processors.add_log_level,           # add "level" field
        structlog.processors.StackInfoRenderer(),     # include stack traces
        structlog.dev.set_exc_info,                   # attach exception info
        structlog.processors.TimeStamper(fmt="iso"),  # ISO 8601 timestamps
        structlog.processors.JSONRenderer(),          # output as JSON
    ],
    wrapper_class=structlog.make_filtering_bound_logger(logging.INFO),
    context_class=dict,
    logger_factory=structlog.PrintLoggerFactory(),
)

log = structlog.get_logger()

def process_order(user_id: str, order_id: str, items: list):
    # Bind context that will appear in ALL subsequent log entries
    log_ctx = log.bind(user_id=user_id, order_id=order_id, item_count=len(items))

    log_ctx.info("order_processing_started")

    try:
        total = calculate_total(items)
        log_ctx.info("order_total_calculated", total_cents=total)

        payment_result = charge_payment(user_id, total)
        log_ctx.info("payment_processed",
                     payment_id=payment_result.id,
                     payment_method=payment_result.method)

        reserve_inventory(items)
        log_ctx.info("inventory_reserved")

        log_ctx.info("order_processing_completed", duration_ms=elapsed())

    except PaymentTimeoutError as e:
        log_ctx.error("payment_timeout",
                      downstream_service="payment-service",
                      timeout_seconds=e.timeout,
                      retry_count=e.retries)
        raise

    except InsufficientInventoryError as e:
        log_ctx.warning("inventory_insufficient",
                        missing_items=e.missing_items,
                        available=e.available)
        raise

Node.js/TypeScript Example

// structured-logger.ts
import pino from 'pino';

const logger = pino({
  level: process.env.LOG_LEVEL || 'info',
  formatters: {
    level: (label) => ({ level: label }),
  },
  timestamp: pino.stdTimeFunctions.isoTime,
  base: {
    service: 'order-service',
    version: process.env.APP_VERSION,
    environment: process.env.NODE_ENV,
  },
});

export function processOrder(userId: string, orderId: string, items: Item[]) {
  const orderLog = logger.child({ userId, orderId, itemCount: items.length });

  orderLog.info('order_processing_started');

  try {
    const total = calculateTotal(items);
    orderLog.info({ totalCents: total }, 'order_total_calculated');

    const payment = chargePayment(userId, total);
    orderLog.info({ paymentId: payment.id, method: payment.method }, 'payment_processed');

    orderLog.info('order_processing_completed');
  } catch (err) {
    orderLog.error({ err, downstreamService: 'payment-service' }, 'order_processing_failed');
    throw err;
  }
}