From observability
Add structured log points and trace spans to existing code. Use this skill when asked to "instrument this function", "add logging to this module", "add tracing to this pipeline", or "make this code observable".
How this skill is triggered — by the user, by Claude, or both
Slash command
/observability:instrument-codeThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Add structured logging and distributed tracing instrumentation to existing code.
Add structured logging and distributed tracing instrumentation to existing code.
Read the target file(s) and identify:
Choose based on the project's existing dependencies:
| Language | Recommended library | Install command |
|---|---|---|
| Python | structlog | uv add structlog |
| Python | opentelemetry-sdk | uv add opentelemetry-sdk opentelemetry-exporter-otlp |
| TypeScript | pino | bun add pino |
| TypeScript | @opentelemetry/sdk-node | bun add @opentelemetry/sdk-node |
If the project already imports a logging library, use that — do not add a second one.
For each external-facing function, wrap the body in a trace span:
# Python (structlog + opentelemetry)
import structlog
from opentelemetry import trace
logger = structlog.get_logger(__name__)
tracer = trace.get_tracer(__name__)
def process_request(payload: dict) -> dict:
with tracer.start_as_current_span("process_request") as span:
span.set_attribute("payload.size", len(str(payload)))
logger.info("process_request.start", payload_keys=list(payload.keys()))
result = _do_work(payload)
logger.info("process_request.end", result_keys=list(result.keys()))
return result
Insert log statements at:
Keep log messages machine-readable: use event="snake_case_name" as the primary key.
For every except/catch block, emit a structured error log:
except SomeError as exc:
logger.error(
"process_request.failed",
error=str(exc),
error_type=type(exc).__name__,
exc_info=True,
)
raise
For loops and repeated external calls, record timing and counts:
import time
start = time.perf_counter()
result = call_llm_api(prompt)
duration_ms = (time.perf_counter() - start) * 1000
logger.info("llm_call.complete", duration_ms=round(duration_ms, 1), tokens=result.usage.total_tokens)
Run the test suite after adding instrumentation:
Output the instrumented code as a unified diff, keeping changes minimal. Avoid restructuring logic — instrumentation should be additive only.
npx claudepluginhub ats-kinoshita-iso/agent-workshop --plugin observabilityAdds Pydantic Logfire observability (tracing, logging, metrics) to Python, JS/TS, and Rust apps. Handles SDK setup, instrumentation, and framework-specific extras.
Instrument a service with OpenTelemetry — RED metrics, structured logs, distributed tracing, and health checks. Outputs actual code and config, not a plan. Use when asked to "add monitoring", "instrument this", "add logging", "set up tracing", or "observability".
Instruments code with logging, metrics, and tracing so production behavior is visible and diagnosable. Use when shipping features that run in production or when production issues are hard to diagnose.