Skip to content
Back to skills

Structured Logging

ASecurity

Structured logging patterns with loguru and structlog for Python services, JSON output, correlation IDs, and Loki/Grafana integration

  • 6 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 8, 2026
ai-agentspythongosqlbackendsecurity

Security analysis

A100/100

Scanned September 8, 2026

npx -y skills add kmshihab7878/claude-code-setup --skill structured-logging --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Structured Logging?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Structured Logging
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/kmshihab7878-structured-logging/badge)](https://www.skillsdirectory.com/skills/kmshihab7878-structured-logging)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: structured-logging
description: Structured logging patterns with loguru and structlog for Python services, JSON output, correlation IDs, and Loki/Grafana integration
triggers:
  - logging
  - structured logging
  - loguru
  - structlog
  - log format
  - observability logs
---

# Structured Logging

Production logging patterns for Python services. Replace stdlib logging with structured, machine-parseable output that integrates with Grafana Loki.

## Setup: loguru + structlog

```python
# src/coremind/core/logging.py
import structlog
from loguru import logger
import sys
import json

def setup_logging(json_output: bool = True, level: str = "INFO"):
    """Configure structured logging for CoreMind services."""

    # Remove default loguru handler
    logger.remove()

    if json_output:
        # JSON format for production (Loki/ELK ingest)
        logger.add(
            sys.stdout,
            format="{message}",
            level=level,
            serialize=True,
        )
    else:
        # Human-readable for development
        logger.add(
            sys.stdout,
            format="<green>{time:HH:mm:ss}</green> | <level>{level:<8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>",
            level=level,
            colorize=True,
        )

    # Configure structlog to use loguru as backend
    structlog.configure(
        processors=[
            structlog.contextvars.merge_contextvars,
            structlog.processors.add_log_level,
            structlog.processors.StackInfoRenderer(),
            structlog.dev.set_exc_info,
            structlog.processors.TimeStamper(fmt="iso"),
            structlog.processors.JSONRenderer() if json_output
            else structlog.dev.ConsoleRenderer(),
        ],
        wrapper_class=structlog.make_filtering_bound_logger(level),
        context_class=dict,
        logger_factory=structlog.PrintLoggerFactory(),
        cache_logger_on_first_use=True,
    )
```

## Correlation IDs

```python
# Middleware for request correlation
import uuid
from contextvars import ContextVar

correlation_id: ContextVar[str] = ContextVar("correlation_id", default="")

class CorrelationMiddleware:
    async def __call__(self, request, call_next):
        req_id = request.headers.get("X-Request-ID", str(uuid.uuid4()))
        correlation_id.set(req_id)
        structlog.contextvars.bind_contextvars(correlation_id=req_id)

        response = await call_next(request)
        response.headers["X-Request-ID"] = req_id
        return response
```

## Log Levels Guide

- **DEBUG**: Variable values, function entry/exit, SQL queries
- **INFO**: Request handled, task started/completed, state transitions
- **WARNING**: Retry attempts, deprecation usage, approaching limits
- **ERROR**: Failed operations that can be retried or degraded
- **CRITICAL**: Data loss risk, security incidents, unrecoverable failures

## Anti-Patterns

- Never log sensitive data (tokens, passwords, PII)
- Never use f-strings in log messages (use structured fields)
- Never log inside tight loops (use sampling)
- Never suppress exceptions silently

```python
# BAD
logger.info(f"User {user.email} logged in with token {token}")

# GOOD
logger.info("user_login", user_id=user.id, auth_method="oauth")
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…