api-logging-guidelines

1
2
Source

Best practices and guidelines for using logger in API routes. Defines appropriate logging levels, what to log, and when to avoid logging. Use when implementing or reviewing API route logging, debugging strategies, or optimizing log output.

Install

mkdir -p .claude/skills/api-logging-guidelines && curl -L -o skill.zip "https://mcp.directory/api/skills/download/5458" && unzip -o skill.zip -d .claude/skills/api-logging-guidelines && rm skill.zip

Installs to .claude/skills/api-logging-guidelines

About this skill

API Route Logging Guidelines

Comprehensive guidance for appropriate use of logging in API routes to maintain clean, useful, and performant logs.


Core Principles

1. Avoid Redundant Logging

DON'T log what's already logged by middleware:

// ❌ BAD - Request details are already logged by middleware
logger.info({ tenantId, projectId }, 'Getting project details');

DO rely on request middleware logging:

  • Request/response middleware already logs: method, path, status, duration, path params
  • These logs include tenant/project IDs from the URL path
  • Adding duplicate logs creates noise without value

2. Log Level Guidelines

LevelUse CaseExamples
ERRORUnexpected failures requiring attentionDatabase connection failures, unhandled exceptions, critical service errors
WARNRecoverable issues or concerning patternsRate limiting triggered, deprecated API usage, fallback behavior activated
INFOImportant business events (NOT routine operations)User account created, payment processed, critical configuration changed
DEBUGDetailed diagnostic informationQuery parameters, intermediate calculations, cache hit/miss details

3. What TO Log

Log these important events:

// ✅ GOOD - Important business event
logger.info({
  userId,
  oldPlan: 'free',
  newPlan: 'pro',
  mrr: 99
}, 'User upgraded subscription');

// ✅ GOOD - Error with context
logger.error({
  error,
  tenantId,
  webhookUrl,
  attemptNumber: 3
}, 'Webhook delivery failed after retries');

// ✅ GOOD - Security-relevant event
logger.warn({
  ip: c.req.header('x-forwarded-for'),
  userId,
  attemptedResource
}, 'Unauthorized access attempt');

// ✅ GOOD - Performance issue
logger.warn({
  duration: 5234,
  query,
  resultCount: 10000
}, 'Slow query detected');

4. What NOT to Log

Avoid logging routine operations:

// ❌ BAD - Routine CRUD operation
logger.info('Getting user by ID');

// ❌ BAD - Already logged by middleware
logger.info(`Processing GET request to /api/users/${id}`);

// ❌ BAD - No actionable information
logger.info('Starting database query');

// ❌ BAD - Sensitive information
logger.info({ password, apiKey }, 'User login attempt');

// ❌ BAD - Overly granular
logger.debug('Entering function processUser');
logger.debug('Exiting function processUser');

API Route Patterns

Pattern 1: Error Handling

// ✅ GOOD - Log errors with context
export const route = router.get('/:id', async (c) => {
  try {
    const result = await riskyOperation();
    return c.json(result);
  } catch (error) {
    // Log error with relevant context
    logger.error({
      error,
      userId: c.get('userId'),
      operation: 'riskyOperation',
      // Include any relevant debugging context
      requestId: c.get('requestId')
    }, 'Operation failed');

    // Return generic error to client (don't leak internals)
    return c.json({ error: 'Internal server error' }, 500);
  }
});

Pattern 2: Business Events

// ✅ GOOD - Log significant business events
export const route = router.post('/subscription/upgrade', async (c) => {
  const { planId } = await c.req.json();

  const result = await upgradeSubscription(userId, planId);

  // This is worth logging - it's a significant business event
  logger.info({
    userId,
    oldPlan: result.previousPlan,
    newPlan: result.newPlan,
    mrr: result.mrr,
    timestamp: new Date().toISOString()
  }, 'Subscription upgraded');

  return c.json(result);
});

Pattern 3: Performance Monitoring

// ✅ GOOD - Log performance issues
export const route = router.get('/search', async (c) => {
  const start = Date.now();
  const results = await performSearch(query);
  const duration = Date.now() - start;

  // Only log if performance is concerning
  if (duration > 1000) {
    logger.warn({
      duration,
      query,
      resultCount: results.length,
      cached: false
    }, 'Slow search query');
  }

  return c.json(results);
});

Pattern 4: Security Events

// ✅ GOOD - Log security-relevant events
export const route = router.post('/api/admin/*', async (c) => {
  const hasPermission = await checkPermission(userId, resource);

  if (!hasPermission) {
    // Log unauthorized access attempts
    logger.warn({
      userId,
      resource,
      ip: c.req.header('x-forwarded-for'),
      userAgent: c.req.header('user-agent')
    }, 'Unauthorized access attempt');

    return c.json({ error: 'Forbidden' }, 403);
  }

  // Proceed with authorized request...
});

Environment-Specific Guidelines

Development

// More verbose logging acceptable in development
if (process.env.NODE_ENV === 'development') {
  logger.debug({ params, body }, 'Request details');
}

Production

  • Minimize INFO level logs to important events only
  • Never log sensitive data (passwords, tokens, keys, PII)
  • Use structured logging for better searchability
  • Include correlation IDs for tracing requests

Migration Strategy

When refactoring existing verbose logging:

  1. Identify redundant logs: Remove logs that duplicate middleware logging
  2. Downgrade routine operations: Move routine operations from INFO to DEBUG
  3. Enhance error logs: Add more context to error logs
  4. Add business event logs: Ensure important business events are logged
  5. Review log levels: Ensure each log uses the appropriate level

Before:

router.get('/:id', async (c) => {
  const { id } = c.req.param();
  logger.info({ id }, 'Getting item by ID');  // Redundant

  const item = await getItem(id);
  logger.info({ item }, 'Retrieved item');     // Too verbose

  return c.json(item);
});

After:

router.get('/:id', async (c) => {
  const { id } = c.req.param();

  try {
    const item = await getItem(id);
    // No logging needed - routine successful operation
    return c.json(item);
  } catch (error) {
    // Only log errors
    logger.error({ error, id }, 'Failed to retrieve item');
    return c.json({ error: 'Item not found' }, 404);
  }
});

Debugging Without Verbose Logs

Instead of verbose logging, use these strategies:

  1. Use debug mode selectively: Enable DEBUG level for specific modules when troubleshooting
  2. Use tracing: OpenTelemetry/Jaeger for distributed tracing
  3. Use metrics: Prometheus/StatsD for performance metrics
  4. Use error tracking: Sentry/Rollbar for error aggregation
  5. Use feature flags: Enable verbose logging for specific users/requests when debugging

Summary Checklist

Before adding a log statement, ask:

  • Is this already logged by middleware? (method, path, status, params)
  • Is this a significant business event or just routine operation?
  • Does this log provide actionable information?
  • Am I using the correct log level?
  • Am I including helpful context without sensitive data?
  • Will this log be useful in production or just create noise?

Remember: Good logging is about signal, not volume. Every log should serve a purpose.

adding-env-variables

inkeep

Guide for adding new environment variables to the codebase. Ensures env.ts schemas include descriptions and .env.example is kept in sync. Triggers on: add env variable, new environment variable, env.ts change, add config variable, INKEEP_, adding to .env.

00

accessibility-checklist

inkeep

Accessibility review checklist for React/Next.js components built on Radix UI / shadcn/ui. Covers component library misuse, form accessibility, accessible names, keyboard interaction, focus management, and dynamic content. Loaded by pr-review-frontend.

20

data-model-changes

inkeep

Guide for making changes to the database schema, validation, types, and data access layer. Use when adding tables, columns, relations, or modifying the data model. Triggers on: add table, add column, modify schema, database change, data model, new entity, schema migration.

00

next-upgrade

inkeep

Upgrade Next.js to the latest version following official migration guides and codemods

30

find-similar

inkeep

Find similar or analogous code patterns elsewhere in a codebase. Use when answering "Do we do something similar elsewhere?" or "What existing patterns match this?" Returns factual findings about similar code - locations, similarity type, and confidence.

110

pr-tldr

inkeep

PR TLDR context brief — serves dual purpose: 1. **Committed state (template):** Contains the document skeleton with {{FILL}} markers. The pr-review orchestrator loads this at startup, fills in the markers during Phase 1.5, and overwrites this file with the filled result. 2. **Runtime state (filled):** After the orchestrator writes, subagent reviewers load this file and get the filled context brief. If you're reading this and see {{FILL}} markers, the template has not been filled in — either the orchestrator hasn't run yet, or you're viewing the committed source.

00

You might also like

flutter-development

aj-geddes

Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.

643969

drawio-diagrams-enhanced

jgtolentino

Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.

591705

ui-ux-pro-max

nextlevelbuilder

"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."

318398

godot

bfollington

This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.

339397

nano-banana-pro

garg-aayush

Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.

451339

fastapi-templates

wshobson

Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.

304231

Stay ahead of the MCP ecosystem

Get weekly updates on new skills and servers.