mcpField
L
logging-best-practices

logging-best-practices

github.com/andrelandgrafDevelopment23106 installsUpdated 22w ago
Repository

About logging-best-practices

A development skill for applying structured Pino logging in an application. It covers log levels, API route context, and a wrapper pattern for logging from workflows.

Key features

  1. 01Structured logs with Pino
  2. 02Context-first logging calls
  3. 03Log-level guidance and configuration
  4. 04Timing and status in API logs
  5. 05Workflow logging through a step wrapper

Use cases

  1. 01Record API request outcomes and duration
  2. 02Choose levels for operational events or failures
  3. 03Log from workflows that cannot import Node modules

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/andrelandgraf/fullstackrecipes --skill logging-best-practices

After installing, type/logging-best-practicesin Claude Code to confirm it loaded.

Details

From the project README

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

Comments

Markdown supported