All Articles/Logging

Best Practices for Structured Logging

Learn how to structure your logs for maximum searchability and debugging value.


Use Metadata, Not String Interpolation

Embedding data in log messages makes them impossible to search reliably.

JavaScript
// Bad — hard to search, hard to aggregate
Lognitor.info(`User ${userId} purchased ${item} for $${amount}`);

// Good — searchable, filterable, structured
Lognitor.info('Purchase completed', {
  metadata: { userId, item, amount },
  tags: ['purchase', 'revenue'],
});

Consistent Field Names

Use the same metadata field names across all services. Create a team convention:

FieldConventionExample
User IDuserIduser_123
Order IDorderIdord_456
DurationdurationMs245
Amountamount99.99

Use Actions for Event Types

The action field creates a searchable event taxonomy:

JavaScript
Lognitor.info('User signed up', { action: 'user.signup' });
Lognitor.info('Order created', { action: 'order.create' });
Lognitor.info('Payment processed', { action: 'payment.process' });

Log at the Right Level

Don't log everything as info. Use levels meaningfully — debug for verbose internals, warn for concerning-but-functional states, error only when something actually failed.

Include Request Context

For HTTP services, always include request data:

JavaScript
Lognitor.info('Request completed', {
  request: {
    method: 'POST',
    url: '/api/orders',
    status_code: 201,
    duration_ms: 45,
  },
});
Framework middleware handles this

If you use Express, Fastify, Django, or Laravel middleware, request context is captured automatically. You don't need to add it manually.