using-logging

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

9 stars

Best use case

using-logging is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

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

Teams using using-logging should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/using-logging/SKILL.md --create-dirs "https://raw.githubusercontent.com/andrelandgraf/fullstackrecipes/main/.agents/skills/using-logging/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/using-logging/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How using-logging Compares

Feature / Agentusing-loggingStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

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

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

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

Related Skills

using-workflows

9
from andrelandgraf/fullstackrecipes

Create and run durable workflows with steps, streaming, and agent execution. Covers starting, resuming, and persisting workflow results.

using-user-stories

9
from andrelandgraf/fullstackrecipes

Document and track feature implementation with user stories. Workflow for authoring stories, building features, and marking acceptance criteria as passing.

using-tests

9
from andrelandgraf/fullstackrecipes

Testing strategy and workflow. Tests run in parallel with isolated data per suite. Prioritize Playwright for UI, integration tests for APIs, unit tests for logic.

using-sentry

9
from andrelandgraf/fullstackrecipes

Capture exceptions, add context, create performance spans, and use structured logging with Sentry.

using-nuqs

9
from andrelandgraf/fullstackrecipes

Manage React state in URL query parameters with nuqs. Covers Suspense boundaries, parsers, clearing state, and deep-linkable dialogs.

using-drizzle-queries

9
from andrelandgraf/fullstackrecipes

Write type-safe database queries with Drizzle ORM. Covers select, insert, update, delete, relational queries, and adding new tables.

using-authentication

9
from andrelandgraf/fullstackrecipes

Use Better Auth for client and server-side authentication. Covers session access, protected routes, sign in/out, and fetching user data.

using-analytics

9
from andrelandgraf/fullstackrecipes

Track custom events and conversions with Vercel Web Analytics. Covers common events, form tracking, and development testing.

pino-logging-setup

9
from andrelandgraf/fullstackrecipes

Configure structured logging with Pino. Outputs human-readable colorized logs in development and structured JSON in production for log aggregation services.

url-state-management

9
from andrelandgraf/fullstackrecipes

Sync React state to URL query parameters for shareable filters, search, and deep-linkable dialogs with nuqs.

testing

9
from andrelandgraf/fullstackrecipes

Complete testing setup with Neon database branching, Playwright browser tests, integration tests, and unit tests. Isolated branches with automatic TTL cleanup.

stripe-subscriptions

9
from andrelandgraf/fullstackrecipes

Complete subscription billing system with Stripe integration, feature flags for plan gating, webhook handling, and billing portal.