
Logging Best Practices
- 54 installs
- 18 repo stars
- Updated June 8, 2026
- andrelandgraf/fullstackrecipes
logging-best-practices is a Claude Code skill for emitting structured logs with Pino, covering levels, a context-first signature, and a workflow-safe step wrapper.
About
This skill shows how to emit structured logs with Pino across routes, libraries, and workflows, using a context-first signature (context object first, message second). It documents log levels from trace to fatal, the LOG_LEVEL threshold, API-route logging with timing context, and a use-step wrapper so workflows can log safely. Developers use it when adding logging to an application.
- Structured logging with Pino, context-first signature
- Log-level guidance (trace to fatal) and LOG_LEVEL threshold
- Workflow-safe step wrapper for the logger
Logging Best Practices by the numbers
- 54 all-time installs (skills.sh)
- Ranked #303 of 596 Debugging skills by installs in the Skillselion catalog
- Data as of Jul 28, 2026 (Skillselion catalog sync)
logging-best-practices capabilities & compatibility
- Capabilities
- logging · observability
- Use cases
- debugging · devops
- Pricing
- Free
What logging-best-practices says it does
Emit structured logs with Pino throughout the app.
The workflow runtime can't import Node modules, so the logger can't be called directly. Wrap it in a `"use step"` function.
npx skills add https://github.com/andrelandgraf/fullstackrecipes --skill logging-best-practicesAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 54 |
|---|---|
| repo stars | ★ 18 |
| Last updated | June 8, 2026 |
| Repository | andrelandgraf/fullstackrecipes ↗ |
What it does
Emit structured Pino logs across routes, libraries, and workflows with correct levels and context.
Who is it for?
Developers adding structured logging to routes, libraries, or workflows.
When should I use this skill?
Adding logging to routes, libraries, or workflows.
What you get
- Structured log calls
- Log-level configuration
- Workflow log step wrapper
By the numbers
- Six log levels: trace, debug, info, warn, error, fatal
- Default LOG_LEVEL is info
Files
Logging Best Practices
Emit structured logs with Pino throughout the app.
Prerequisites
Complete these setup recipes first:
- Pino Logging Setup
Logging
Import logger from @/lib/logging/logger. Pass a context object first, message second. For errors, put err in the context object.
import { logger } from "@/lib/logging/logger";
logger.info({ port: 3000 }, "Server started");
logger.warn({ endpoint: "/api/chat" }, "Rate limit reached");
logger.debug({ key: "user:123" }, "Cache miss");
logger.error({ err, userId: "123", endpoint: "/api/chat" }, "Request failed");Levels
| Level | When to Use |
|---|---|
trace | Detailed debugging (rarely used) |
debug | Development troubleshooting |
info | Normal operations, business events |
warn | Recoverable issues, deprecation warnings |
error | Failures that need attention |
fatal | Critical failures, app cannot continue |
Set the active threshold via LOG_LEVEL (defaults to info). Use warn in production.
LOG_LEVEL="debug"In API Routes
Log on the way out with timing context.
import { logger } from "@/lib/logging/logger";
export async function POST(request: Request) {
const start = Date.now();
try {
const result = await processRequest(request);
logger.info(
{ duration: Date.now() - start, status: 200 },
"Request completed",
);
return Response.json(result);
} catch (err) {
logger.error({ err, duration: Date.now() - start }, "Request failed");
return Response.json({ error: "Internal error" }, { status: 500 });
}
}In Workflows
The workflow runtime can't import Node modules, so the logger can't be called directly. Wrap it in a "use step" function.
// src/workflows/chat/steps/logger.ts
import { logger } from "@/lib/logging/logger";
export async function log(
level: "info" | "warn" | "error" | "debug",
message: string,
data?: Record<string, unknown>,
): Promise<void> {
"use step";
if (data) {
logger[level](data, message);
} else {
logger[level](message);
}
}import { log } from "./steps/logger";
export async function chatWorkflow({ chatId }) {
"use workflow";
await log("info", "Workflow started", { chatId });
}---
References
Related skills
FAQ
What order are logger arguments?
Pass a context object first and the message second; put err in the context object for errors.
How do I log inside a workflow?
Wrap the logger in a "use step" function because the workflow runtime can't import Node modules directly.