agentleFS
komlukkomluk/scaffolding/skills/logging-standards/SKILL.md

logging-standards

Skill16 starsChanged 5 days agoMITView on GitHub

Structured logging standards: log levels, structured fields, correlation IDs, PII masking, and event naming. TRIGGER when: adding log statements, configuring loggers, or reviewing log output. SKIP: metrics and alerting (use monitoring-observability); error control flow (use error-handling). (Examples use structlog + an OTLP sink.)

  • Reads credentials

3 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

10 rules. 0 are common, 10 are distinctive, and 0 are very specific to this project.

  • 0

    Common

    Most of the 3 edited versions we read keep these.

  • 10

    Distinctive

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Never log TRACE in production

    line 35
  2. Distinctive:

    Start with action verb: "Creating user", "Processing order"

    line 53
  3. Distinctive:

    Keep enough for debugging (last 4 digits)

    line 124
  4. Distinctive:

    Never log masked values to DEBUG level

    line 125
  5. Distinctive:

    Don't log expected errors as ERROR

    line 143
  6. Distinctive:

    Delete non-essential logs aggressively

    line 198
  7. Distinctive:

    Keep audit logs per compliance

    line 199
  8. Distinctive:

    Use structured logging (JSON)

    line 206
  9. Distinctive:

    Use async logging in production

    line 210
  10. Distinctive:

    Use string concatenation for messages

    line 215

“Common” is measured: kept by at least 6 in 10 of the 3 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Logging Standards Skill

Purpose

Standards for consistent, useful logging across all application layers.

Auto-Invoke Triggers

  • Adding log statements
  • Configuring logging infrastructure
  • Debugging issues
  • Setting up monitoring

Log Levels

LevelUse CaseExample
TRACEDetailed debuggingVariable values, loop iterations
DEBUGDiagnostic infoMethod entry/exit, state changes
INFONormal operationsRequest completed, job started
WARNPotential issuesRetry attempt, deprecated usage
ERRORFailuresException caught, operation failed
FATALSystem failureCannot start, out of memory

Level Selection Rules

  • Production default: INFO
  • Development default: DEBUG
  • Never log TRACE in production
  • ERROR should always have context

Log Message Format

Structure

[timestamp] [level] [correlation-id] [logger] - message {structured-data}

Example

2024-01-15T10:30:45.123Z INFO abc-123-def UserService - User created {"userId": 42, "email": "user@example.com"}

Message Guidelines

  • Start with action verb: "Creating user", "Processing order"
  • Be specific: "User 123 deleted" not "Deleted"
  • Include relevant IDs
  • Keep messages concise

Structured Logging

Required Fields

FieldDescriptionExample
timestampISO 8601 format2024-01-15T10:30:45.123Z
levelLog levelINFO, ERROR
messageHuman-readable"User created"
correlationIdRequest trace IDabc-123-def
loggerSource class/moduleUserService

Contextual Fields

FieldWhen to Include
userIdAuthenticated request
requestPathHTTP request
requestMethodHTTP request
durationOperation timing
errorCodeError situations
stackTraceERROR level only

What to Log

Always Log

  • Application startup/shutdown
  • Authentication events (login, logout, failures)
  • Authorization failures
  • External service calls (start, end, errors)
  • Database migrations
  • Configuration changes
  • Business-critical operations

Per Request

  • Request start (DEBUG)
  • Request completion with duration (INFO)
  • Validation errors (WARN)
  • Exceptions (ERROR)

Never Log

  • Passwords or tokens
  • Credit card numbers
  • Personal data (PII) without masking
  • Session IDs in plain text
  • API keys or secrets
  • Full request/response bodies with sensitive data

PII Masking

Fields to Mask

FieldMaskingExample
EmailPartialj***@example.com
PhonePartial+1***456
Credit CardPartial--****-1234
SSNFull***
PasswordNever log-
TokenNever log-

Masking Rules

  • Mask at log time, not display time
  • Keep enough for debugging (last 4 digits)
  • Never log masked values to DEBUG level

Error Logging

Required Information

  • Error type/code
  • Error message
  • Stack trace (first occurrence)
  • Request context (path, method, user)
  • Correlation ID
  • Timestamp

Error Logging Rules

  • Log full stack trace on first occurrence
  • Group repeated errors (rate limit logging)
  • Include recovery actions taken
  • Don't log expected errors as ERROR

Performance Logging

Metrics to Log

MetricLevelWhen
Request durationINFOEvery request
Slow queryWARN> 1 second
External callDEBUGEvery call
Cache hit/missDEBUGWhen relevant

Slow Operation Thresholds

OperationWarn Threshold
HTTP request> 1s
Database query> 500ms
External API> 2s
Cache operation> 100ms

Log Aggregation

Requirements

  • Centralized log storage
  • Full-text search
  • Correlation ID filtering
  • Time-range queries
  • Alerting on patterns

Recommended Tools

ToolUse Case
ELK StackSelf-hosted, full-featured
DatadogCloud, APM integration
SplunkEnterprise, compliance
LokiKubernetes-native

Log Retention

EnvironmentRetention
Development7 days
Staging30 days
Production90 days
Audit logs1 year+

Archival Rules

  • Compress logs older than 7 days
  • Archive to cold storage after retention
  • Delete non-essential logs aggressively
  • Keep audit logs per compliance

Best Practices

DO

  • Use structured logging (JSON)
  • Include correlation IDs
  • Log at appropriate levels
  • Mask sensitive data
  • Use async logging in production
  • Set up alerts for ERROR logs

DON'T

  • Log passwords or secrets
  • Use string concatenation for messages
  • Log inside tight loops
  • Ignore log level guidelines
  • Skip correlation IDs
  • Log full stack traces repeatedly

Logging Checklist

  • Structured logging configured
  • Log levels appropriate per environment
  • Correlation IDs propagated
  • PII masking implemented
  • Error logs include context
  • Slow operation logging enabled
  • Log aggregation configured
  • Alerts set up for errors
  • Retention policy implemented

Example: structlog + OTLP sink (illustrative)

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.

structlog Configuration (<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:

  1. Console - ConsoleRenderer(colors=True) for dev, JSONRenderer for prod
  2. OTLP sink (e.g. Seq, Grafana Loki, any OTLP collector) - JSONRenderer always (no ANSI codes), via OTLPLogExporter

Context Variables

Four 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

Logger Creation Pattern

from core import get_logger          # Re-exported from core/__init__.py
logger = get_logger(__name__)        # Returns structlog.stdlib.BoundLogger

Log Event Naming Convention

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)

OTLP Sink / OpenTelemetry Integration

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.

Key Files

FilePurpose
<your-logging-module>/__init__.pyPublic API: get_logger, set_log_context, TaskLogger
<your-logging-module>/config.pystructlog setup, OTel/OTLP integration, context vars
<your-logging-module>/task_logger.pyTask-specific step logging
<your-middleware-module>/CorrelationIdMiddleware, LoggingMiddleware, UserContextMiddleware

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.