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 observabilityInstruments apps with Logfire observability for traces, logs, metrics using Python, JavaScript/TypeScript, Rust SDKs and OpenTelemetry. Handles FastAPI, Django, Express, LLM calls correctly.
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 services with OpenTelemetry for RED metrics, structured logs, distributed tracing, and health checks. Outputs code/config for detected stacks like Node.js, Python, Go. Use for 'add monitoring', 'instrument', 'observability'.