Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
andrelandgraf avatar

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)
At a glance

logging-best-practices capabilities & compatibility

Capabilities
logging · observability
Use cases
debugging · devops
Pricing
Free
From the docs

What logging-best-practices says it does

Emit structured logs with Pino throughout the app.
SKILL.md
The workflow runtime can't import Node modules, so the logger can't be called directly. Wrap it in a `"use step"` function.
SKILL.md
npx skills add https://github.com/andrelandgraf/fullstackrecipes --skill logging-best-practices

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs54
repo stars18
Last updatedJune 8, 2026
Repositoryandrelandgraf/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

SKILL.mdMarkdownGitHub ↗

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

LevelWhen to Use
traceDetailed debugging (rarely used)
debugDevelopment troubleshooting
infoNormal operations, business events
warnRecoverable issues, deprecation warnings
errorFailures that need attention
fatalCritical 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.

Debuggingmonitoring

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.