JSPM

@padfoot044/pepper-log

3.1.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • 0
  • Score
    100M100P100Q36333F
  • License MIT

Comprehensive OpenTelemetry observability with structured logging and tracing for JavaScript/TypeScript frameworks. Supports OTLP traces AND logs with auto-correlation.

Package Exports

  • @padfoot044/pepper-log

Readme

๐ŸŒถ๏ธ PepperLog v3.1.0

Comprehensive OpenTelemetry observability with structured logging and distributed tracing for JavaScript/TypeScript frameworks. Now supports OTLP traces AND logs with automatic correlation.

npm version License: MIT

๐Ÿ†• What's New in v3.1.0 - Developer Experience Enhancement

  • ๐Ÿงน Zero Console Noise: Removed 100+ console statements for clean production builds
  • ๐Ÿš€ Enhanced Performance: Reduced console call overhead and string concatenations
  • ๐Ÿ—๏ธ Professional Architecture: Production-ready internal logging system
  • ๐Ÿ”ง Smart Logging: Environment-aware logging levels (silent by default)
  • โœจ Clean Developer Experience: No more spammy debug messages in browser console
  • ๐Ÿ› ๏ธ Maintained Compatibility: 100% API compatibility (48/48 tests passing)

๐Ÿ›ก๏ธ CORS Issues? Solved Automatically!

No more CORS configuration needed! PepperLog includes built-in CORS handling with multiple fallback strategies:

  • โœ… Automatic fallbacks when CORS fails
  • โœ… Works with any local backend (localhost:4318, localhost:3000, etc.)
  • โœ… No framework configuration required
  • โœ… Traces stored locally if network fails
  • โœ… Console logging always works as fallback
// This just works - no CORS configuration needed!
const pepperLog = new PepperLog({
  serviceName: 'my-app',
  backend: 'grafana',
  config: {
    endpoint: 'http://localhost:4318/v1/traces' // CORS handled automatically
  }
});

๐Ÿ“– Read the Complete CORS Solution Guide โ†’

โœจ What's New in v3.1.0 - Developer Experience Enhancement

  • ๐Ÿงน Production-Ready Builds: Zero console noise in production environments
  • โšก Performance Boost: Eliminated 100+ console statements for faster execution
  • ๐Ÿ—๏ธ Professional Logging: Smart internal logger with environment-aware levels
  • ๐ŸŽฏ Clean Output: No more spammy ๐ŸŒถ๏ธ PepperLog messages cluttering your console
  • ๐Ÿ”ง Seamless Integration: Silent by default, configurable for development
  • โœ… Rock Solid: All 48 tests passing, 100% backward compatibility maintained

โœจ What's New in v3.0.0

  • ๐Ÿ“ Structured Logging: Real logs sent to /v1/logs endpoint (not just traces!)
  • ๐Ÿ”— Trace-Log Correlation: Automatic correlation with trace/span IDs
  • ๐ŸŽฏ Proper Separation: Traces appear in "Traces", Logs in "Logs" sections
  • โšก Enhanced Performance: Batched exports for both traces and logs
  • ๐ŸŒ Full OTLP Support: Complete OpenTelemetry Logs Protocol implementation
  • ๐Ÿง  Smart Configuration: Auto-detects logs endpoint from traces endpoint

โœจ Features

  • ๐Ÿš€ Universal Compatibility: Works in both browser and Node.js environments
  • ๐ŸŽฏ Auto-Detection: Automatically detects frameworks (Angular, React, Vue, Next.js, Express, etc.)
  • ๐Ÿ”Œ Multiple Backends: SigNoz, Grafana, Datadog, Jaeger, New Relic, and more
  • ๐ŸŒ Zero Browser Conflicts: Browser-optimized with no Node.js dependencies
  • ๐Ÿ“Š Complete Telemetry: Tracing, structured logging, and metrics in one package
  • ๐Ÿ›ก๏ธ Error-Safe: Graceful degradation - your app continues even if telemetry fails
  • ๐Ÿ“ TypeScript Support: Full TypeScript definitions included
  • ๐Ÿงน Production Ready: Clean console output, no debug spam (v3.1.0+)

๐Ÿš€ Quick Start

Installation

npm install @padfoot044/pepper-log

Basic Usage - Enhanced with Logging

import { PepperLog, LogLevel } from '@padfoot044/pepper-log';

// v3.0.0: Configure both traces AND logs
const logger = new PepperLog({
  serviceName: 'my-awesome-app',
  backend: 'signoz', // or 'grafana', 'jaeger', etc.
  config: {
    endpoint: 'http://localhost:4318/v1/traces',      // Traces endpoint
    logsEndpoint: 'http://localhost:4318/v1/logs',    // Logs endpoint (NEW!)
  },
  features: {
    tracing: true,
    logging: true,    // Enable structured logging
    metrics: true,
    autoInstrumentation: true
  },
  // Enhanced logging configuration
  logging: {
    enabled: true,
    level: LogLevel.INFO,
    enableCorrelation: true,    // Auto-correlate logs with traces
    consoleOutput: true
  }
});

await logger.initialize();

// STRUCTURED LOGGING (NEW!) - Goes to "Logs" section
logger.info('User logged in', { 
  userId: '12345', 
  method: 'oauth',
  duration: 150 
});

logger.error('Payment failed', new Error('Insufficient funds'), { 
  userId: '12345', 
  amount: 99.99,
  paymentMethod: 'credit_card'
});

// TRACING (Existing) - Goes to "Traces" section  
await logger.traceFunction('process-payment', async () => {
  // These logs are automatically correlated with the trace!
  logger.info('Payment processing started', { amount: 99.99 });
  
  // Your business logic here
  await processPayment();
  
  logger.info('Payment completed successfully');
  return { success: true };
}, { 
  userId: '12345',
  paymentAmount: 99.99 
});

// ๐Ÿ›ก๏ธ CORS DIAGNOSTICS (NEW!) - Check if your backend has CORS issues
const corsStatus = await logger.testEndpointCORS();
console.log('CORS Test:', corsStatus);
// Output: { endpoint: "http://localhost:4318/v1/traces", corsSupported: false, error: "CORS error" }

const status = logger.getCORSStatus();
console.log('CORS Status:', status);
// Output: { corsFailures: true, storedTraceCount: 5, recommendations: [...] }

// View traces stored locally due to CORS issues
const storedTraces = logger.getStoredTraces();
console.log(`Found ${storedTraces.length} traces stored locally`);

What's Different in v3.0.0?

Before (v1.x) - Tracing Only:

// Everything went to "Traces" section
logger.info('message');     // Created a span, not a log
logger.error('error');      // Created a span, not a log

Now (v3.0.0) - Proper Separation:

// Structured Logging โ†’ "Logs" section
logger.info('User action', { userId: '123' });          // Real log entry
logger.error('Error occurred', error, { context: 'payment' }); // Real log entry

// Tracing โ†’ "Traces" section  
logger.traceFunction('operation', async () => {         // Real span
  logger.info('Step completed');  // Correlated log with trace ID!
});

๐ŸŽฏ Framework Integration

Angular

import { Injectable } from '@angular/core';
import { PepperLog } from '@padfoot044/pepper-log';

@Injectable({ providedIn: 'root' })
export class TelemetryService {
  private pepperLog = new PepperLog({
    serviceName: 'angular-app',
    backend: 'grafana'
  });

  async initialize() {
    await this.pepperLog.initialize();
  }

  async traceUserAction(action: string, data?: any) {
    return this.pepperLog.traceFunction(`user-${action}`, async () => {
      // Your business logic
      return { action, data, timestamp: Date.now() };
    });
  }
}

React

import React, { useEffect } from 'react';
import { PepperLog } from '@padfoot044/pepper-log';

const telemetry = new PepperLog({
  serviceName: 'react-app',
  backend: 'signoz'
});

function App() {
  useEffect(() => {
    telemetry.initialize();
  }, []);

  const handleClick = async () => {
    await telemetry.traceFunction('button-click', async () => {
      console.log('Button clicked!');
    });
  };

  return <button onClick={handleClick}>Click me</button>;
}

Installation

npm install @padfoot044/pepper-log
# or
yarn add pepper-log
# or
pnpm add pepper-log

Basic Usage

import { PepperLog } from '@padfoot044/pepper-log';

// Initialize with minimal configuration
const logger = new PepperLog({
  serviceName: 'my-awesome-app',
  backend: 'signoz',
  config: {
    endpoint: 'http://localhost:4318/v1/traces'
  }
});

// Auto-detects framework and initializes everything
await logger.initialize();

// That's it! Your app is now instrumented ๐ŸŽ‰

Environment Variables (Alternative)

You can also configure PepperLog using environment variables:

PEPPER_LOG_SERVICE_NAME=my-app
PEPPER_LOG_BACKEND=signoz
PEPPER_LOG_ENDPOINT=http://localhost:4318/v1/traces
import { PepperLog } from '@padfoot044/pepper-log';

// Uses environment variables
const logger = new PepperLog({
  serviceName: process.env.PEPPER_LOG_SERVICE_NAME!,
  backend: process.env.PEPPER_LOG_BACKEND as any,
  config: {
    endpoint: process.env.PEPPER_LOG_ENDPOINT
  }
});

await logger.initialize();

๐ŸŽฏ Supported Frameworks

PepperLog automatically detects and provides optimized instrumentation for:

Framework Auto-Detection Custom Instrumentation
React โœ… Component lifecycle, route changes
Angular โœ… HTTP interceptors, route events
Vue.js โœ… Component lifecycle, Vue Router
Next.js โœ… Page transitions, API routes, SSR
Express โœ… Middleware, route handlers
Fastify โœ… Hooks, request lifecycle
Koa โœ… Middleware, context

๐Ÿ”Œ Supported Backends

const logger = new PepperLog({
  serviceName: 'my-app',
  backend: 'signoz',
  config: {
    endpoint: 'http://localhost:4318/v1/traces'
  }
});

Datadog

const logger = new PepperLog({
  serviceName: 'my-app',
  backend: 'datadog',
  config: {
    apiKey: process.env.DATADOG_API_KEY,
    endpoint: 'https://trace.agent.datadoghq.com/v0.4/traces'
  }
});

Jaeger

const logger = new PepperLog({
  serviceName: 'my-app',
  backend: 'jaeger',
  config: {
    endpoint: 'http://localhost:14268/api/traces'
  }
});

New Relic

const logger = new PepperLog({
  serviceName: 'my-app',
  backend: 'newrelic',
  config: {
    apiKey: process.env.NEW_RELIC_LICENSE_KEY,
    endpoint: 'https://otlp.nr-data.net/v1/traces'
  }
});

Grafana Cloud

const logger = new PepperLog({
  serviceName: 'my-app',
  backend: 'grafana',
  config: {
    apiKey: process.env.GRAFANA_CLOUD_API_KEY,
    endpoint: 'https://tempo.grafana.net:443/v1/traces'
  }
});

Custom Backend

const logger = new PepperLog({
  serviceName: 'my-app',
  backend: 'custom',
  config: {
    endpoint: 'https://your-custom-otlp-endpoint.com/v1/traces',
    headers: {
      'Authorization': 'Bearer your-token'
    }
  }
});

๐Ÿ“– Advanced Usage

Manual Instrumentation

// Create custom spans
const span = logger.createSpan('user.login', {
  attributes: {
    'user.id': '12345',
    'user.email': 'user@example.com'
  }
});

// Add attributes to current span
logger.addAttributes({
  'custom.attribute': 'value',
  'request.id': requestId
});

span.end();

Function Tracing

// Automatically trace any function
const result = await logger.traceFunction(
  'database.query',
  async () => {
    return await db.query('SELECT * FROM users');
  },
  {
    'db.operation': 'select',
    'db.table': 'users'
  }
);

Custom Metrics

// Create counters
const requestCounter = logger.createCounter(
  'http.requests.total',
  'Total number of HTTP requests'
);

// Create histograms
const responseTime = logger.createHistogram(
  'http.request.duration',
  'HTTP request duration in milliseconds'
);

// Use metrics
requestCounter.add(1, { method: 'GET', route: '/api/users' });
responseTime.record(150, { method: 'POST', route: '/api/auth' });

Framework-Specific Features

React

// Automatically instruments:
// - Component render cycles
// - React Router navigation
// - State changes (with React DevTools)

const logger = new PepperLog({
  serviceName: 'my-react-app',
  backend: 'signoz',
  config: { endpoint: 'http://localhost:4318/v1/traces' }
});

Angular

// Automatically instruments:
// - HTTP client requests
// - Router events
// - Component lifecycle

const logger = new PepperLog({
  serviceName: 'my-angular-app',
  backend: 'signoz',
  config: { endpoint: 'http://localhost:4318/v1/traces' }
});

Express

// Automatically instruments:
// - All middleware
// - Route handlers
// - Database queries
// - HTTP client requests

const logger = new PepperLog({
  serviceName: 'my-express-api',
  backend: 'signoz',
  config: { endpoint: 'http://localhost:4318/v1/traces' }
});

โš™๏ธ Configuration Options

interface PepperLogConfig {
  /** Service name for tracing */
  serviceName: string;
  
  /** Backend service provider */
  backend: 'signoz' | 'datadog' | 'jaeger' | 'newrelic' | 'grafana' | 'azure' | 'aws-xray' | 'custom';
  
  /** Backend-specific configuration */
  config: {
    endpoint?: string;
    apiKey?: string;
    headers?: Record<string, string>;
    batchConfig?: {
      maxExportBatchSize?: number;
      exportTimeoutMillis?: number;
      scheduledDelayMillis?: number;
    };
  };
  
  /** Optional framework override (auto-detected if not provided) */
  framework?: 'react' | 'angular' | 'vue' | 'express' | 'nextjs' | 'fastify' | 'koa' | 'auto';
  
  /** Enable/disable specific features */
  features?: {
    tracing?: boolean;        // Default: true
    metrics?: boolean;        // Default: true
    logging?: boolean;        // Default: true
    autoInstrumentation?: boolean; // Default: true
  };
  
  /** Environment (auto-detected if not provided) */
  environment?: string;
  
  /** Custom attributes added to all traces */
  globalAttributes?: Record<string, string | number | boolean>;
}

๐Ÿ” Auto-Detection

PepperLog uses multiple strategies to auto-detect your framework:

  1. Package.json Analysis: Scans dependencies for framework packages
  2. Runtime Detection: Checks for framework-specific global objects
  3. File Structure: Looks for framework-specific config files and folders
  4. Environment Variables: Checks for framework-specific environment variables

Detection Priority

  1. Next.js (highest priority - extends React)
  2. Angular
  3. React
  4. Vue.js
  5. Express/Fastify/Koa (Node.js frameworks)

๐Ÿ“Š What Gets Instrumented

Automatic Instrumentation

  • โœ… HTTP Requests: Incoming and outgoing HTTP calls
  • โœ… Database Queries: PostgreSQL, MySQL, MongoDB, Redis
  • โœ… File System: File read/write operations (configurable)
  • โœ… DNS Lookups: DNS resolution timing
  • โœ… Process Metrics: CPU, memory usage

Framework-Specific

React

  • Component render cycles
  • Route changes (React Router)
  • State management operations
  • Error boundaries

Angular

  • HTTP interceptor traces
  • Router navigation events
  • Component lifecycle
  • Service injections

Vue.js

  • Component lifecycle hooks
  • Vue Router navigation
  • Vuex state changes
  • Computed property evaluation

Express/Node.js

  • Middleware execution
  • Route handler performance
  • Database connection pooling
  • External API calls

๐Ÿ› Debugging

Enable debug mode to see what's happening:

const logger = new PepperLog({
  serviceName: 'my-app',
  backend: 'signoz',
  config: { 
    endpoint: 'http://localhost:4318/v1/traces'
  },
  environment: 'development' // Enables debug logging
});

// Check what was detected
const framework = logger.getDetectedFramework();
console.log('Detected framework:', framework);

const config = logger.getConfig();
console.log('Final config:', config);

๐Ÿ”ง Troubleshooting

Common Issues

Q: Framework not detected correctly

// Override auto-detection
const logger = new PepperLog({
  framework: 'react', // Force specific framework
  serviceName: 'my-app',
  backend: 'signoz',
  config: { endpoint: 'http://localhost:4318/v1/traces' }
});

Q: Too much or too little instrumentation

const logger = new PepperLog({
  serviceName: 'my-app',
  backend: 'signoz',
  config: { endpoint: 'http://localhost:4318/v1/traces' },
  features: {
    autoInstrumentation: false, // Disable auto-instrumentation
    tracing: true,              // Keep manual tracing
    metrics: false              // Disable metrics
  }
});

Q: Backend connection issues

// Test with a simple backend first
const logger = new PepperLog({
  serviceName: 'my-app',
  backend: 'jaeger',
  config: { 
    endpoint: 'http://localhost:14268/api/traces'
  }
});

๐Ÿค Contributing

We welcome contributions! See our Contributing Guide for details.

๐Ÿ“„ License

MIT License - see LICENSE file for details.

๐Ÿ™ Acknowledgments

  • Built on top of OpenTelemetry
  • Inspired by the need for easier observability in JavaScript applications
  • Special thanks to the SigNoz, Jaeger, and OpenTelemetry communities

Made with โค๏ธ and ๐ŸŒถ๏ธ by the PepperLog team