From scaffolding
Defines structured logging standards: log levels, message format, required fields, PII masking, and what to log/never log. Useful when adding log statements or configuring loggers.
How this skill is triggered — by the user, by Claude, or both
Slash command
/scaffolding:logging-standardsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Standards for consistent, useful logging across all application layers.
Standards for consistent, useful logging across all application layers.
| Level | Use Case | Example |
|---|---|---|
| TRACE | Detailed debugging | Variable values, loop iterations |
| DEBUG | Diagnostic info | Method entry/exit, state changes |
| INFO | Normal operations | Request completed, job started |
| WARN | Potential issues | Retry attempt, deprecated usage |
| ERROR | Failures | Exception caught, operation failed |
| FATAL | System failure | Cannot start, out of memory |
[timestamp] [level] [correlation-id] [logger] - message {structured-data}
2024-01-15T10:30:45.123Z INFO abc-123-def UserService - User created {"userId": 42, "email": "user@example.com"}
| Field | Description | Example |
|---|---|---|
| timestamp | ISO 8601 format | 2024-01-15T10:30:45.123Z |
| level | Log level | INFO, ERROR |
| message | Human-readable | "User created" |
| correlationId | Request trace ID | abc-123-def |
| logger | Source class/module | UserService |
| Field | When to Include |
|---|---|
| userId | Authenticated request |
| requestPath | HTTP request |
| requestMethod | HTTP request |
| duration | Operation timing |
| errorCode | Error situations |
| stackTrace | ERROR level only |
| Field | Masking | Example |
|---|---|---|
| Partial | j***@example.com | |
| Phone | Partial | +1***456 |
| Credit Card | Partial | --****-1234 |
| SSN | Full | *** |
| Password | Never log | - |
| Token | Never log | - |
| Metric | Level | When |
|---|---|---|
| Request duration | INFO | Every request |
| Slow query | WARN | > 1 second |
| External call | DEBUG | Every call |
| Cache hit/miss | DEBUG | When relevant |
| Operation | Warn Threshold |
|---|---|
| HTTP request | > 1s |
| Database query | > 500ms |
| External API | > 2s |
| Cache operation | > 100ms |
| Tool | Use Case |
|---|---|
| ELK Stack | Self-hosted, full-featured |
| Datadog | Cloud, APM integration |
| Splunk | Enterprise, compliance |
| Loki | Kubernetes-native |
| Environment | Retention |
|---|---|
| Development | 7 days |
| Staging | 30 days |
| Production | 90 days |
| Audit logs | 1 year+ |
Illustrative — this is one team's logging stack shown as a concrete example. Substitute your own logging library, processor pipeline, and log sink. The universal guidance above (levels, structured fields, correlation IDs, PII masking, event naming) is the reusable part; the specifics below are an example.
<your-logging-module>/config.py)This example uses structlog with stdlib integration, routing all logs through Python's logging module with per-handler formatters.
Processor chain (shared across all handlers):
shared_processors = [
structlog.contextvars.merge_contextvars,
_add_log_context, # Injects task_id, session_id, project_id, user_id
_inject_context_to_record, # Copies context to LogRecord for OTel attributes
structlog.stdlib.add_log_level,
structlog.stdlib.add_logger_name,
structlog.processors.TimeStamper(fmt="iso"),
structlog.processors.StackInfoRenderer(),
structlog.processors.UnicodeDecoder(),
]
Two output pipelines:
ConsoleRenderer(colors=True) for dev, JSONRenderer for prodJSONRenderer always (no ANSI codes), via OTLPLogExporterFour contextvars.ContextVar fields are automatically injected into every log event:
from core.logging import set_log_context, clear_log_context
set_log_context(task_id="abc", session_id="sess", project_id="proj", user_id="123")
# All subsequent logs in this async context include these fields
from core import get_logger # Re-exported from core/__init__.py
logger = get_logger(__name__) # Returns structlog.stdlib.BoundLogger
Events use dot-separated domain.action format:
logger.info("app.startup_complete", max_concurrent_tasks=3)
logger.info("redis.connected")
logger.warning("db.schema_mismatch", migration_commands=[...])
logger.info("contributor.added", project_id=pid, user_id=uid, role="owner")
logger.error("redis.queue_push_error", queue=name, error=str(e))
logger.debug("redis.subscribed", channel=ch, task_id=tid)
Configured at app startup (this example targets a Seq OTLP endpoint):
setup_logging(
log_level=LOG_LEVEL, # From core.config (env: LOG_LEVEL)
log_format=LOG_FORMAT, # "console" or "json" (env: LOG_FORMAT)
log_file=LOG_FILE, # Optional rotating file (10MB, 5 backups)
seq_enabled=SEQ_ENABLED, # env: SEQ_ENABLED
seq_endpoint=SEQ_ENDPOINT,# Default: https://localhost:5341/ingest/otlp/v1/logs
seq_api_key=SEQ_API_KEY, # env: SEQ_API_KEY (X-Seq-ApiKey header)
service_name=OTEL_SERVICE_NAME, # Resource: service.name, namespace: "scaffolding"
)
Shutdown flushes pending logs: shutdown_logging() called in app lifespan teardown.
| File | Purpose |
|---|---|
<your-logging-module>/__init__.py | Public API: get_logger, set_log_context, TaskLogger |
<your-logging-module>/config.py | structlog setup, OTel/OTLP integration, context vars |
<your-logging-module>/task_logger.py | Task-specific step logging |
<your-middleware-module>/ | CorrelationIdMiddleware, LoggingMiddleware, UserContextMiddleware |
npx claudepluginhub komluk/scaffolding --plugin scaffoldingImplements structured logging with proper log levels (TRACE through FATAL), level-selection decision trees, and 9 mandatory canonical events for production observability.
Provides structured JSON logging patterns with correlation IDs, context propagation, log levels, and required fields for observability and production incident debugging.
Implements structured JSON logging with levels, correlation IDs, PII redaction, aggregation, and retention for Node.js, Go, Python apps. Migrates from console.log/printf.