using-logging
Use structured logging with Pino throughout your application. Covers log levels, context, and workflow-safe logging patterns.
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
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/using-logging/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How using-logging Compares
| Feature / Agent | using-logging | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/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
Create and run durable workflows with steps, streaming, and agent execution. Covers starting, resuming, and persisting workflow results.
using-user-stories
Document and track feature implementation with user stories. Workflow for authoring stories, building features, and marking acceptance criteria as passing.
using-tests
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
Capture exceptions, add context, create performance spans, and use structured logging with Sentry.
using-nuqs
Manage React state in URL query parameters with nuqs. Covers Suspense boundaries, parsers, clearing state, and deep-linkable dialogs.
using-drizzle-queries
Write type-safe database queries with Drizzle ORM. Covers select, insert, update, delete, relational queries, and adding new tables.
using-authentication
Use Better Auth for client and server-side authentication. Covers session access, protected routes, sign in/out, and fetching user data.
using-analytics
Track custom events and conversions with Vercel Web Analytics. Covers common events, form tracking, and development testing.
pino-logging-setup
Configure structured logging with Pino. Outputs human-readable colorized logs in development and structured JSON in production for log aggregation services.
url-state-management
Sync React state to URL query parameters for shareable filters, search, and deep-linkable dialogs with nuqs.
testing
Complete testing setup with Neon database branching, Playwright browser tests, integration tests, and unit tests. Isolated branches with automatic TTL cleanup.
stripe-subscriptions
Complete subscription billing system with Stripe integration, feature flags for plan gating, webhook handling, and billing portal.