home / skills / andrelandgraf / fullstackrecipes / using-logging

using-logging skill

/.agents/skills/using-logging

This skill enforces structured logging with Pino across your app, improving observability with consistent context, levels, and workflow-safe patterns.

npx playbooks add skill andrelandgraf/fullstackrecipes --skill using-logging

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
3.4 KB
---
name: using-logging
description: Use structured logging with Pino throughout your application. Covers log levels, context, and workflow-safe logging patterns.
---

# Working with Logging

Use structured logging with Pino throughout your application. Covers log levels, context, and workflow-safe logging patterns.

## Implement Working with Logging

Use structured logging with Pino throughout your application. Covers log levels, context, and workflow-safe logging patterns.

**See:**

- Resource: `using-logging` in Fullstack Recipes
- URL: https://fullstackrecipes.com/recipes/using-logging

---

### Basic Logging

Import the logger and use it throughout your application:

```typescript
import { logger } from "@/lib/logging/logger";

// Info level for normal operations
logger.info("Server started", { port: 3000 });

// Warn level for recoverable issues
logger.warn("Rate limit reached", { endpoint: "/api/chat" });

// Error level with Error objects
logger.error(err, "Failed to process request");

// Debug level for development troubleshooting
logger.debug("Cache miss", { key: "user:123" });
```

### Structured Logging

Always include context as the first argument for structured logs:

```typescript
// Context object first, message second
logger.info({ userId: "123", action: "login" }, "User logged in");

// For errors, pass the error first
logger.error({ err, userId: "123", endpoint: "/api/chat" }, "Request failed");
```

### Log Levels

Use appropriate levels for different scenarios:

| 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 |

### Configuring Log Level

Set the `LOG_LEVEL` environment variable:

```env
# Show all logs including debug
LOG_LEVEL="debug"

# Production: only warnings and errors
LOG_LEVEL="warn"
```

Default is `info` if not set. Valid values: `trace`, `debug`, `info`, `warn`, `error`, `fatal`.

### Logging in API Routes

```typescript
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 });
  }
}
```

### Logging in Workflows

Workflow functions run in a restricted environment. Use the logger step wrapper:

```typescript
// 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);
  }
}
```

Then use it in workflows:

```typescript
import { log } from "./steps/logger";

export async function chatWorkflow({ chatId }) {
  "use workflow";

  await log("info", "Workflow started", { chatId });
}
```

---

## References

- [Pino Documentation](https://getpino.io/)
- [Pino Log Levels](https://getpino.io/#/docs/api?id=levels)

Overview

This skill teaches using structured logging with Pino across a TypeScript full-stack application. It focuses on log levels, attaching contextual data, and safe logging patterns for restricted workflow environments. The goal is consistent, searchable logs that help with debugging, monitoring, and incident response.

How this skill works

Instrument your app by importing a central logger and calling level-specific methods (trace, debug, info, warn, error, fatal). Always prefer structured logs: pass a context object first and a human message second. For workflows, use a small step wrapper that respects the runtime restrictions and forwards structured entries to the central logger.

When to use it

  • Log business events and normal operations with info (e.g., user actions, job completion).
  • Use debug or trace for development-only diagnostics and detailed troubleshooting.
  • Emit warn for recoverable issues or impending deprecations.
  • Record errors and stack traces with error; use fatal for unrecoverable app crashes.
  • Wrap logging calls when running inside restricted workflow steps or sandboxed runtimes.

Best practices

  • Always include a context object (userId, requestId, duration, endpoint) as the first argument for searchable structured logs.
  • Use appropriate log levels and set LOG_LEVEL via environment variables to control verbosity per environment.
  • Log durations and status codes for API routes to measure performance and failure patterns.
  • Pass Error objects (or an err field) to error-level logs to preserve stack traces.
  • Use a minimal, workflow-safe logger wrapper for steps to avoid violating runtime constraints.

Example use cases

  • API route: log request start, duration, and final status to detect slow endpoints.
  • Auth flows: log login attempts with userId and outcome at info or warn as appropriate.
  • Background jobs: log job start, progress checkpoints, and errors with context for retries.
  • Workflows: call a step-level log function to emit structured events from sandboxed workflow code.
  • Prod debugging: switch LOG_LEVEL to debug temporarily to capture more diagnostic data.

FAQ

What is the recommended default log level?

Use info as the default. Set LOG_LEVEL to debug or trace for development and to warn or error in production to reduce noise.

How should I include errors in logs?

Pass an Error object or an err field inside the context object to error-level logs so the logger can capture the stack trace and structured details.