LuminaLog
Waitlist
SDK Reference

Node.js / TypeScript SDK

Production-grade logging SDK with automatic batching, retry logic, graceful shutdown, and zero dependencies. Built with TypeScript for complete type safety.

Installation

npm install @luminalog/sdk
# or
yarn add @luminalog/sdk
# or
pnpm add @luminalog/sdk

Quick Start

logger.ts
import { LuminaLog } from '@luminalog/sdk';

export const logger = new LuminaLog({
  apiKey: process.env.LUMINALOG_API_KEY!,
  environment: process.env.NODE_ENV || 'development',
  batchSize: 100,        // Auto-flush after 100 logs
  flushInterval: 5000,   // Auto-flush every 5 seconds
});

// Start logging
logger.info('Application started', { 
  version: '1.0.0',
  nodeVersion: process.version 
});

// Automatic error tracking with stack traces
try {
  await riskyOperation();
} catch (error) {
  logger.captureError(error, { userId: 'user_123' });
}

Configuration Options

OptionTypeDefaultDescription
apiKeystringRequiredYour LuminaLog API key
environmentstring'default'Label for filtering logs (stored as metadata). Actual environment is set by your API key.
projectIdstringundefinedOptional project identifier for multi-project apps
batchSizenumber100Logs to buffer before auto-flush. Min: 50, Max: 500. Values outside this range are automatically capped/floored.
flushIntervalnumber5000Milliseconds between auto-flushes (real-time balance)
minLevelLogLevelundefinedFilter logs by minimum level (debug|info|warn|error|fatal|panic)
privacyModebooleanfalseSkip automatic PII scrubbing (you handle sensitive data)
endpointstringapi.luminalog.cloudCustom API endpoint for self-hosted deployments
debugbooleanfalseEnable SDK debug logging to console

Environment Handling

The environment parameter is stored as metadata for filtering within your logs. The actual environment (production, staging, etc.) is determined by your API key's environment setting in the dashboard.

Why? This prevents quota abuse and ensures clear project boundaries. Create separate API keys for each environment in your project settings.

SDK Batching Strategy

To ensure maximum ingestion efficiency and protect platform stability, LuminaLog enforces batch size guardrails:

  • Minimum (50): Prevents excessive HTTP overhead. Values below 50 are ignored and treated as 50.
  • Maximum (500): Prevents payloads from exceeding AWS Lambda/Firehose buffers. Values above 500 are capped at 500.

Optimized batching reduces your billing by grouping multiple log lines into a single ingestion request.

Logging Methods

πŸ”logger.debug(message, metadata)

Detailed diagnostics for development. Filtered in production with minLevel.

ℹ️logger.info(message, metadata)

General operational events. Track user actions, system events.

⚠️logger.warn(message, metadata)

Warning conditions. Slow queries, deprecated API usage, high memory.

❌logger.error(message, metadata)

Error conditions requiring attention. Failed operations, exceptions.

πŸ”₯logger.fatal(message, metadata)

Critical errors causing service degradation.

🚨logger.panic(message, metadata)

System-wide failures. Flushes immediately, bypasses batching.

Child Loggers

Create child loggers with inherited context metadata. Perfect for request-scoped logging where you want to automatically include request ID, user ID, trace ID, or other contextual information in every log.

middleware.ts
import { logger } from './logger';

// Express middleware example
app.use((req, res, next) => {
  // Create child logger with request context
  req.logger = logger.child({
    requestId: req.id,
    userId: req.user?.id,
    path: req.path,
    method: req.method,
    ip: req.ip,
    userAgent: req.get('user-agent')
  });
  next();
});

// In your route handlers
app.post('/api/payment', async (req, res) => {
  req.logger.info('Processing payment', {
    amount: req.body.amount,
    currency: req.body.currency
  });
  // Log automatically includes: requestId, userId, path, method, ip, userAgent
  
  try {
    const result = await processPayment(req.body);
    req.logger.info('Payment successful', { transactionId: result.id });
    res.json(result);
  } catch (error) {
    req.logger.captureError(error, { 
      amount: req.body.amount,
      paymentMethod: req.body.method 
    });
    res.status(500).json({ error: 'Payment failed' });
  }
});

Nested Child Loggers

You can create child loggers from child loggers. Each level inherits and merges metadata from its parent, enabling hierarchical context tracking across your application layers.
const requestLogger = logger.child({ requestId: 'req_123' });
const userLogger = requestLogger.child({ userId: 'user_456' });
const transactionLogger = userLogger.child({ transactionId: 'txn_789' });

transactionLogger.info('Payment processed');
// Includes: requestId, userId, transactionId

Level Filtering

Filter logs by minimum level before sending to reduce costs and noise in production. Logs below the minimum level are discarded in the SDK, saving bandwidth and ingestion costs.

logger.ts
// Environment-based filtering
const logger = new LuminaLog({
  apiKey: process.env.LUMINALOG_API_KEY!,
  environment: process.env.NODE_ENV || 'development',
  minLevel: process.env.NODE_ENV === 'production' ? 'info' : 'debug'
});

// Development: All logs sent (debug, info, warn, error, fatal, panic)
logger.debug('Detailed variable state', { vars: localVars });  // βœ… Sent in dev
logger.info('User logged in');                                  // βœ… Sent in dev

// Production: Only info and above (info, warn, error, fatal, panic)
logger.debug('Detailed variable state', { vars: localVars });  // ❌ Filtered in prod
logger.info('User logged in');                                  // βœ… Sent in prod
logger.error('Payment failed');                                 // βœ… Always sent

Log Level Hierarchy

debug→info→warn→error→fatal→panic

Setting minLevel: 'info' sends info, warn, error, fatal, and panic logs. Debug logs are filtered out.

Cost Savings

Filtering debug logs in production can reduce your log volume by 60-80%, significantly lowering ingestion costs while maintaining visibility into critical issues.

Error Tracking

Automatic error tracking with stack traces, fingerprinting, and context. Errors are automatically deduplicated and grouped in your dashboard.

try {
  await processPayment(order);
} catch (error) {
  // Automatically extracts:
  // - Error type and message
  // - Full stack trace
  // - Error fingerprint for deduplication
  logger.captureError(error, { 
    orderId: order.id,
    userId: order.userId,
    amount: order.amount 
  });
}

// Also available as captureException (alias)
logger.captureException(error, context);

Automatic Fingerprinting

Errors are automatically fingerprinted based on the stack trace. This prevents duplicate alerts and keeps your "Errors" dashboard clean even during a storm of identical errors.

Privacy Mode

Enable privacy mode to skip automatic PII scrubbing when you handle sensitive data yourself. This tells LuminaLog to store your logs as-is without processing.

const logger = new LuminaLog({
  apiKey: process.env.LUMINALOG_API_KEY!,
  privacyMode: true  // Skip automatic PII scrubbing
});

// You're responsible for not sending PII
logger.info('User action', {
  userId: hashUserId(user.id),  // βœ… Hashed ID
  action: 'login',               // βœ… No PII
  timestamp: Date.now()          // βœ… Safe
});

// Don't send raw PII in privacy mode
logger.info('User login', {
  email: user.email  // ❌ Raw email in privacy mode
});

Privacy Mode Responsibility

When privacy mode is enabled, automatic PII scrubbing is disabled. You are responsible for ensuring no sensitive data (emails, SSNs, credit cards, etc.) is sent in your logs.

Distributed Tracing

The Node.js SDK provides built-in utilities for generating and extracting trace identifiers, compatible with W3C Trace Context standards.

Tracing Helpers

  • generateTraceId()Generates a unique UUID v4 for request tracing.
  • generateSpanId()Generates a unique UUID v4 for operation tracing.
  • getTraceIdFromRequest(req)Extracts trace ID from 'x-trace-id' or 'traceparent' headers.

Tracing Example

import { generateTraceId, generateSpanId } from '@luminalog/sdk';

const traceId = generateTraceId();
const spanId = generateSpanId();

logger.info('Starting checkout', {
  trace_id: traceId,
  span_id: spanId
});

Next Steps