Skip to main content
Template logging lets you aggregate and analyze logs with variable data while preserving the original template.

What is Template Logging?

logger.info(`User ${userId} logged in from ${city}`);
// Result: "User user_123 logged in from New York"
// Result: "User user_456 logged in from London"
// Result: "User user_789 logged in from Tokyo"
// These appear as 3 different log messages

Using the fmt Helper

The logger.fmt tagged template creates a log template:
const logger = Proliferate.logger;

const userId = 'user_123';
const action = 'checkout';
const amount = 99.99;

logger.info(logger.fmt`User ${userId} performed ${action} for $${amount}`);
This produces:
{
  level: 'info',
  message: 'User user_123 performed checkout for $99.99',  // Readable
  template: 'User {0} performed {1} for ${2}',             // For grouping
  attributes: {
    'param.0': 'user_123',
    'param.1': 'checkout',
    'param.2': 99.99,
  }
}

Benefits of Templates

Log Aggregation

Logs with the same template are grouped together in the dashboard

Pattern Recognition

Identify patterns and anomalies in your logs

Cardinality Control

High-cardinality fields don’t explode your log count

Example: Pattern Recognition

Template: "Payment failed: {0}"
├── 89 occurrences
├── Top errors: "Card declined" (45), "Insufficient funds" (30), ...
└── Spike detected at 14:00 UTC

Syntax

Basic Usage

const logger = Proliferate.logger;

// String interpolation
logger.info(logger.fmt`Processing order ${orderId}`);

// Numbers
logger.info(logger.fmt`Request completed in ${durationMs}ms`);

// Multiple values
logger.info(logger.fmt`User ${userId} bought ${quantity} items for $${total}`);

With Additional Attributes

Combine templates with extra attributes:
logger.info(
  logger.fmt`Order ${orderId} shipped to ${country}`,
  {
    carrier: 'ups',
    weight_kg: 2.5,
    priority: true,
  }
);

When to Use Templates

Variable identifiers:
logger.info(logger.fmt`User ${userId} logged in`);
logger.info(logger.fmt`Processing order ${orderId}`);
logger.info(logger.fmt`Request ${requestId} completed`);
Metrics with varying values:
logger.info(logger.fmt`API latency: ${latency}ms for ${endpoint}`);
logger.warn(logger.fmt`Queue depth: ${depth}, threshold: ${threshold}`);
Status messages with context:
logger.info(logger.fmt`${operation} completed successfully`);
logger.error(logger.fmt`${operation} failed: ${error}`);
Static messages (no variables):
// Just use regular logging
logger.info('Application started');
logger.info('Shutting down gracefully');
Low-cardinality enums:
// Better as attributes than template params
logger.info('Payment processed', { method: paymentMethod });
Sensitive data:
// Don't template sensitive info
logger.info('User logged in', { ip: clientIp });  // IP in attributes, not template

Template vs. String Interpolation

ScenarioRecommendation
High-frequency eventsUse templates
User/session-specific IDsUse templates
Debugging in developmentString interpolation is fine
Rare eventsEither works
Fixed set of valuesUse attributes

Examples

// Order lifecycle
logger.info(logger.fmt`Order ${orderId} created by ${userId}`);
logger.info(logger.fmt`Order ${orderId} payment of $${amount} received`);
logger.info(logger.fmt`Order ${orderId} shipped via ${carrier}`);
logger.info(logger.fmt`Order ${orderId} delivered to ${city}`);

// Errors
logger.error(logger.fmt`Order ${orderId} payment failed: ${reason}`);

Dashboard Features

In the Proliferate dashboard, template logs enable:
  1. Template grouping: See all instances of a template together
  2. Parameter analysis: View distribution of parameter values
  3. Pattern detection: Identify unusual parameter distributions
  4. Trend analysis: Compare template frequency over time
  5. Search: Find logs by template or parameter values