Skip to content

OpenTelemetry Overview

Doug Fennell edited this page Oct 1, 2025 · 1 revision

OpenTelemetry Integration Overview

πŸš€ Get enterprise-grade trace correlation with RDCP in under 10 minutes!

What You Get

Before OpenTelemetry Integration:

// Basic RDCP debug logs
rdcp.debug.database('User query executed', { 
  userId: 123, 
  query: 'SELECT * FROM users WHERE id = ?' 
})
// Output: [DATABASE] User query executed { userId: 123, query: "SELECT..." }

After OpenTelemetry Integration:

// Same code, but now automatically enriched with trace context
rdcp.debug.database('User query executed', { 
  userId: 123, 
  query: 'SELECT * FROM users WHERE id = ?' 
})
// Output: [DATABASE] User query executed { 
//   userId: 123, 
//   query: "SELECT...",
//   trace: {
//     traceId: "4bf92f3577b34da6a3ce929d0e0e4736",
//     spanId: "00f067aa0ba902b7"
//   }
// }

The Power: Now your debug logs and distributed traces are perfectly correlated. Click on a trace in Jaeger/DataDog and immediately find the corresponding debug logs!


⚑ 10-Minute Quick Start

Step 1: Install (30 seconds)

npm install @rdcp.dev/server @rdcp.dev/otel-plugin @opentelemetry/api

Step 2: Enable Correlation (2 minutes)

// Add these 3 lines to your existing RDCP setup
const { setupRDCPWithOpenTelemetry } = require('@rdcp.dev/otel-plugin')

// One line enables trace correlation (uses active OpenTelemetry spans)
setupRDCPWithOpenTelemetry()

Step 3: Verify It Works (1–2 minutes)

import { NodeSDK } from '@opentelemetry/sdk-node'
import { trace } from '@opentelemetry/api'
import { setupRDCPWithOpenTelemetry } from '@rdcp.dev/otel-plugin'
import { enableDebugCategories, debug } from '@rdcp.dev/server'

// Start a minimal OpenTelemetry SDK (dev verification)
const sdk = new NodeSDK()
await sdk.start()

// Enable RDCP ↔ OTel correlation
setupRDCPWithOpenTelemetry()

// Turn on a debug category so logs emit
enableDebugCategories(['DATABASE'])

// Create an active span and emit a RDCP debug log
trace.getTracer('verify').startActiveSpan('sample-span', span => {
  debug.database('Query executed', { sql: 'SELECT 1' })
  span.end()
})

// Expected console output includes a trace suffix like:
// πŸ”Œ [DB] [trace:90abcdef] Query executed [ { sql: 'SELECT 1' } ]

Troubleshooting

  • Ensure a tracer provider is initialized (e.g., NodeSDK.start() or your own provider)
  • Make sure a debug category is enabled (e.g., enableDebugCategories(['DATABASE']))
  • Check console output for the [trace:xxxxxxxx] suffix; if missing, verify your OpenTelemetry span is active
  • In production, confirm exporter setup (OTLP/HTTP, etc.) and that traces appear in your backend

Step 4: Connect Your Backend (5 minutes)

Choose your observability backend:

That's it! You now have enterprise-grade observability with perfect correlation between traces and debug logs.


Architecture: Zero Impact Design

Plugin Architecture Benefits

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   @rdcp/server  β”‚    β”‚  @rdcp.dev/otel-plugin   β”‚
β”‚                 β”‚    β”‚                      β”‚
β”‚ βœ… Works standaloneβ”‚    β”‚ βœ… Optional enhancementβ”‚
β”‚ βœ… Zero OTel deps β”‚    β”‚ βœ… Peer dependencies   β”‚
β”‚ βœ… Fast & lean    β”‚    β”‚ βœ… Enterprise features β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Benefits:

  • πŸ“¦ Optional Dependency: Teams without OpenTelemetry aren't forced to install it
  • πŸš€ Performance: Zero overhead when OpenTelemetry isn't configured
  • πŸ”„ Gradual Adoption: Start with basic RDCP, add OpenTelemetry when ready
  • 🏒 Enterprise Ready: Works with any OpenTelemetry-compatible backend

Framework Examples (Copy & Paste Ready)

Express.js (Most Popular)

const express = require('express')
const { RDCPClient } = require('@rdcp.dev/server')
const { setupRDCPWithOpenTelemetry } = require('@rdcp.dev/otel-plugin')

const app = express()
const rdcp = new RDCPClient({ /* config */ })

// One line enables trace correlation
setupRDCPWithOpenTelemetry(rdcp)

app.get('/users/:id', async (req, res) => {
  rdcp.debug.api('User request started', { userId: req.params.id })
  
  const user = await getUserById(req.params.id)
  rdcp.debug.database('User fetched', { userId: user.id, found: !!user })
  
  res.json(user)
})

Next.js App Router

// app/api/users/route.js
import { RDCPClient } from '@rdcp/server'
import { setupRDCPWithOpenTelemetry } from '@rdcp.dev/otel-plugin'

const rdcp = new RDCPClient({ /* config */ })
setupRDCPWithOpenTelemetry(rdcp)

export async function GET(request) {
  rdcp.debug.api('API route called', { route: '/api/users' })
  
  const users = await fetchUsers()
  rdcp.debug.database('Users retrieved', { count: users.length })
  
  return Response.json(users)
}

Want more frameworks? See Framework Examples for Fastify, Koa, and more.


Migration Scenarios (Enterprise Adoption Patterns)

Scenario 1: "We have console.log everywhere"

Before:

console.log('Processing user request', userId)

After (10 minutes):

rdcp.debug.api('Processing user request', { userId })
// Now: Structured, categorized, controllable, traceable

Scenario 2: "We use Winston/Pino logging"

Before:

logger.info('Database query executed', { query, duration })

After (10 minutes):

rdcp.debug.database('Query executed', { query, duration })
// Now: RDCP control + trace correlation + existing structured logging

Scenario 3: "We already have OpenTelemetry traces"

Before:

span.addEvent('Query executed', { query, duration })

After (5 minutes):

rdcp.debug.database('Query executed', { query, duration })
// Now: Debug logs automatically correlated with your existing traces

Need detailed migration steps? See Migration Guides.


Real-World Impact: Enterprise Success Stories

Debugging Distributed Systems

// Before: Finding issues across services was a nightmare
// After: Click trace ID in any service, immediately see debug logs

// Service A
rdcp.debug.api('Request received', { orderId: 12345 })

// Service B  
rdcp.debug.payment('Payment processed', { orderId: 12345, amount: 99.99 })

// Service C
rdcp.debug.inventory('Stock updated', { orderId: 12345, items: 3 })

// All logs share the same traceId - perfect correlation!

Performance Investigation

// Trace shows slow database calls
// Debug logs show exact queries and parameters
rdcp.debug.database('Slow query detected', { 
  query: 'SELECT * FROM orders WHERE created_at > ?',
  duration: '2.3s',
  rowCount: 50000 
})
// traceId: "4bf92f3577b34da6a3ce929d0e0e4736"

Production Incident Response

// Alert fires in DataDog/New Relic
// Get trace ID from alert
// Search logs by trace ID
// Immediately see debug context from all services

Next Steps

  1. Quick Framework Setup - Copy-paste examples for your framework
  2. Backend Configuration - Connect to your observability platform
  3. Migration Guide - Step-by-step migration from current logging
  4. OpenTelemetry Roadmap - See what's coming next

Community Adoption β†’ Enterprise Interest

Developers learn RDCP + OpenTelemetry on side projects β†’ Bring it to work β†’ Enterprise procurement follows developer preference.

Ready to get started? Pick your framework: Express | Next.js | Fastify | Koa

Clone this wiki locally