api-logging-guidelines

API Route Logging Guidelines

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "api-logging-guidelines" with this command: npx skills add inkeep/agents/inkeep-agents-api-logging-guidelines

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

  1. Log Level Guidelines

Level Use Case Examples

ERROR Unexpected failures requiring attention Database connection failures, unhandled exceptions, critical service errors

WARN Recoverable issues or concerning patterns Rate limiting triggered, deprecated API usage, fallback behavior activated

INFO Important business events (NOT routine operations) User account created, payment processed, critical configuration changed

DEBUG Detailed diagnostic information Query parameters, intermediate calculations, cache hit/miss details

  1. 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');

  1. 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:

  • Identify redundant logs: Remove logs that duplicate middleware logging

  • Downgrade routine operations: Move routine operations from INFO to DEBUG

  • Enhance error logs: Add more context to error logs

  • Add business event logs: Ensure important business events are logged

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

  • Use debug mode selectively: Enable DEBUG level for specific modules when troubleshooting

  • Use tracing: OpenTelemetry/Jaeger for distributed tracing

  • Use metrics: Prometheus/StatsD for performance metrics

  • Use error tracking: Sentry/Rollbar for error aggregation

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

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

adding-env-variables

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

data-model-changes

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

internal-surface-areas

No summary provided by upstream source.

Repository SourceNeeds Review