@sourabhkumawat0105/healops-opentelemetry
v0.21.0
Published
HealOps OpenTelemetry SDK for Node.js and Browser with automatic file path detection and server-side source map resolution
Maintainers
Readme
@sourabhkumawat0105/healops-opentelemetry
The official HealOps OpenTelemetry SDK for Node.js and Browser. Automatically captures and reports errors, logs, and traces to the HealOps platform.
Features
- 🚀 Automatic Error Tracking: Catches unhandled errors, promise rejections, and HTTP errors
- 📊 Real-time Logging: Send logs with different severity levels (INFO, WARNING, ERROR, CRITICAL)
- 🔍 Automatic File Path Detection: Captures file path, line number, and column in browser
- 🎯 Complete Log Storage: All logs (INFO, WARNING, ERROR, CRITICAL) are persisted to database
- 🎯 Smart Incident Detection: Only ERROR and CRITICAL logs trigger incident creation
- 🔄 Auto-instrumentation: Automatically instruments Express, HTTP, and other Node.js libraries
- 🌐 Browser Compatible: Works in all modern browsers with automatic error catching
- ⚡ High-Performance Batching: Batches logs for 98% reduction in HTTP requests (v0.7.0+)
- ✨ Universal Init: One-line setup that works everywhere with auto-detection
- 🎛️ Console Interception: Automatically captures all console.log, console.error, etc.
- 🚄 Optimized Backend: Bulk ingestion endpoint with single-transaction persistence
Installation
npm install @sourabhkumawat0105/healops-opentelemetryQuick Start
🆕 Universal Setup (Recommended - New in v0.6.0)
One line of code - works everywhere! Automatically detects your environment and framework.
// CommonJS (Node.js, Fastify, Express, NestJS)
const { init } = require('@sourabhkumawat0105/healops-opentelemetry');
const healops = init({
apiKey: process.env.HEALOPS_API_KEY,
serviceName: 'my-app'
});
// That's it! Now captures:
// ✅ All console.log, console.error, console.warn
// ✅ Unhandled errors and promise rejections
// ✅ HTTP requests, database queries (via OpenTelemetry)
// ✅ Everything HyperDX captures and more!// ES Modules / TypeScript
import { init } from '@sourabhkumawat0105/healops-opentelemetry';
const healops = init({
apiKey: process.env.HEALOPS_API_KEY!,
serviceName: 'my-app'
});Advanced Options:
const healops = init({
apiKey: process.env.HEALOPS_API_KEY,
serviceName: 'my-app',
endpoint: 'https://engine.healops.ai', // Optional: Custom endpoint
captureConsole: true, // Default: true - Capture console.log/error/warn
captureErrors: true, // Default: true - Capture unhandled errors
captureTraces: true, // Default: true - Capture HTTP/DB traces (Node.js only)
debug: false // Default: false - Enable debug logging
});
// You can still use the logger manually
healops.info('User logged in', { userId: '123' });
healops.error('Payment failed', { orderId: '456' });⚡ Performance & Batching (New in v0.7.0)
Intelligent batching for high-volume logging!
const healops = init({
apiKey: process.env.HEALOPS_API_KEY,
serviceName: 'my-app',
// Batching configuration (optional)
enableBatching: true, // Default: true (batching enabled)
batchSize: 50, // Default: 50 logs per batch
batchIntervalMs: 1000 // Default: 1000ms (1 second)
});How it works:
- Logs are buffered and sent in batches
- Automatically flushes when batch reaches 50 logs OR every 1 second
- 98% reduction in HTTP requests (100 logs = 1-2 requests instead of 100!)
- 95% faster log ingestion
- Graceful shutdown handling (flushes on process exit)
Performance comparison: | Scenario | Without Batching | With Batching | Improvement | |----------|------------------|---------------|-------------| | 100 logs | 100 HTTP requests | 2 requests | 98% fewer requests | | Database writes | 100 transactions | 1 transaction | 99% faster | | Total time | ~5-10s | ~100-200ms | 95% faster |
Manual flush (if needed):
// Flush any queued logs before exiting
await healops.flush();Environment Variables
# .env file
HEALOPS_API_KEY=your-api-key-hereLegacy Setup (Still Supported)
Node.js (Backend)
1. Initialize at the start of your application (e.g., index.js, app.js, or server.js):
const { initHealOpsOTel, createLogger } = require('@sourabhkumawat0105/healops-opentelemetry');
// Option 1: Automatic OpenTelemetry instrumentation (recommended for Node.js)
initHealOpsOTel({
apiKey: process.env.HEALOPS_API_KEY,
serviceName: 'my-backend-service',
// Optional: Override endpoint (defaults to https://engine.healops.ai)
// endpoint: 'https://engine.healops.ai'
});
// Option 2: Manual logger (if you prefer direct control)
const logger = createLogger({
apiKey: process.env.HEALOPS_API_KEY,
serviceName: 'my-backend-service',
endpoint: 'https://engine.healops.ai',
source: 'backend'
});
// Use the logger anywhere in your app
logger.error('Database connection failed', {
error: 'Connection timeout',
database: 'postgres'
});2. Add to your .env file:
HEALOPS_API_KEY=your-api-key-hereBrowser (Frontend)
1. Initialize in your app entry point (e.g., app.js, index.js, _app.js for Next.js):
Option A: Automatic browser detection (recommended)
import { initHealOpsLogger } from '@sourabhkumawat0105/healops-opentelemetry';
// Initialize with automatic error catching (recommended)
const logger = initHealOpsLogger({
apiKey: process.env.NEXT_PUBLIC_HEALOPS_API_KEY, // or your API key
serviceName: 'my-frontend-app',
endpoint: 'https://engine.healops.ai',
source: 'frontend'
});
// That's it! Errors are now automatically capturedOption B: Explicit browser import
import { initHealOpsLogger } from '@sourabhkumawat0105/healops-opentelemetry/browser';
// Initialize with automatic error catching
const logger = initHealOpsLogger({
apiKey: process.env.NEXT_PUBLIC_HEALOPS_API_KEY,
serviceName: 'my-frontend-app',
endpoint: 'https://engine.healops.ai',
source: 'frontend'
});2. Add to your environment variables:
NEXT_PUBLIC_HEALOPS_API_KEY=your-api-key-hereFramework-Specific Integration
Next.js
1. Create or update lib/healops.js:
import { initHealOpsLogger } from '@sourabhkumawat0105/healops-opentelemetry';
let logger = null;
export function initHealOps() {
if (typeof window !== 'undefined' && !logger) {
logger = initHealOpsLogger({
apiKey: process.env.NEXT_PUBLIC_HEALOPS_API_KEY,
serviceName: 'my-nextjs-app',
endpoint: 'https://engine.healops.ai',
source: 'nextjs-frontend'
});
}
return logger;
}2. Initialize in pages/_app.js or app/layout.js:
// pages/_app.js (Pages Router)
import { useEffect } from 'react';
import { initHealOps } from '../lib/healops';
function MyApp({ Component, pageProps }) {
useEffect(() => {
initHealOps();
}, []);
return <Component {...pageProps} />;
}
export default MyApp;// app/layout.js (App Router)
'use client';
import { useEffect } from 'react';
import { initHealOps } from '../lib/healops';
export default function RootLayout({ children }) {
useEffect(() => {
initHealOps();
}, []);
return (
<html>
<body>{children}</body>
</html>
);
}React
1. Create src/utils/healops.js:
import { initHealOpsLogger } from '@sourabhkumawat0105/healops-opentelemetry';
export const logger = initHealOpsLogger({
apiKey: process.env.REACT_APP_HEALOPS_API_KEY,
serviceName: 'my-react-app',
endpoint: 'https://engine.healops.ai',
source: 'react-frontend'
});2. Import in src/index.js:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './utils/healops'; // Initialize HealOps
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);Fastify (New Universal Init)
One line setup - automatically captures everything!
// main.ts or index.js
const { init } = require('@sourabhkumawat0105/healops-opentelemetry');
const Fastify = require('fastify');
// 🆕 Initialize HealOps FIRST (before creating Fastify instance)
const healops = init({
apiKey: process.env.HEALOPS_API_KEY,
serviceName: 'my-fastify-app'
});
// Now create your Fastify app
const fastify = Fastify({ logger: true });
// All logs are automatically captured!
fastify.get('/api/users', async (request, reply) => {
console.log('Fetching users'); // ✅ Captured automatically
try {
// Your code here
return { users: [] };
} catch (error) {
console.error('Failed to fetch users:', error); // ✅ Captured automatically
throw error;
}
});
fastify.listen({ port: 3000 });Express.js (New Universal Init)
One line setup:
const { init } = require('@sourabhkumawat0105/healops-opentelemetry');
const express = require('express');
// 🆕 Initialize HealOps FIRST
const healops = init({
apiKey: process.env.HEALOPS_API_KEY,
serviceName: 'my-express-app'
});
const app = express();
// All logs and errors are automatically captured!
app.get('/api/users', async (req, res) => {
console.log('Fetching users'); // ✅ Captured
try {
res.json({ users: [] });
} catch (error) {
console.error('Failed to fetch users:', error); // ✅ Captured
res.status(500).json({ error: 'Internal server error' });
}
});
app.listen(3000);Express.js (Legacy Setup)
1. Initialize in your main server file:
const express = require('express');
const { initHealOpsOTel, createLogger } = require('@sourabhkumawat0105/healops-opentelemetry');
// Initialize OpenTelemetry instrumentation (must be first!)
initHealOpsOTel({
apiKey: process.env.HEALOPS_API_KEY,
serviceName: 'my-express-app'
});
const app = express();
// Optional: Use logger directly in routes
const logger = createLogger({
apiKey: process.env.HEALOPS_API_KEY,
serviceName: 'my-express-app',
source: 'express'
});
app.get('/api/users', async (req, res) => {
try {
// Your code here
res.json({ users: [] });
} catch (error) {
logger.error('Failed to fetch users', {
error: error.message,
route: '/api/users'
});
res.status(500).json({ error: 'Internal server error' });
}
});
app.listen(3000);Vue.js
1. Create src/plugins/healops.js:
import { initHealOpsLogger } from '@sourabhkumawat0105/healops-opentelemetry';
export default {
install(app) {
if (typeof window !== 'undefined') {
const logger = initHealOpsLogger({
apiKey: process.env.VUE_APP_HEALOPS_API_KEY,
serviceName: 'my-vue-app',
endpoint: 'https://engine.healops.ai',
source: 'vue-frontend'
});
app.config.globalProperties.$healops = logger;
}
}
};2. Use in src/main.js:
import { createApp } from 'vue';
import App from './App.vue';
import HealOps from './plugins/healops';
const app = createApp(App);
app.use(HealOps);
app.mount('#app');Usage
Manual Logging
import { createLogger } from '@sourabhkumawat0105/healops-opentelemetry';
const logger = createLogger({
apiKey: 'your-api-key',
serviceName: 'my-app',
endpoint: 'https://engine.healops.ai',
source: 'my-app'
});
// INFO - Broadcast only (not persisted)
logger.info('User logged in', { userId: '123', email: '[email protected]' });
// WARNING - Broadcast only (not persisted)
logger.warn('High memory usage', { memory: '85%', threshold: '80%' });
// ERROR - Broadcast AND persisted to database
logger.error('Database connection failed', {
error: 'Connection timeout',
database: 'postgres',
host: 'db.example.com'
});
// CRITICAL - Broadcast AND persisted to database
logger.critical('Payment service down', {
service: 'stripe',
lastSuccess: new Date().toISOString()
});Automatic Error Catching (Browser)
When using initHealOpsLogger(), the following are automatically captured:
- ✅ Unhandled JavaScript errors (
window.onerror) - ✅ Unhandled promise rejections (
unhandledrejection) - ✅ HTTP errors (4xx, 5xx responses from fetch)
- ✅ Network errors (connection failures, timeouts)
- ✅ Console errors (
console.error())
// These are automatically caught and sent to HealOps:
// Unhandled error
throw new Error('Something went wrong');
// Unhandled promise rejection
Promise.reject('Failed to load data');
// HTTP error (automatically caught by fetch interceptor)
fetch('/api/users').then(res => {
if (!res.ok) throw new Error('Request failed');
});
// Console error
console.error('An error occurred');Console Interception
The logger can automatically intercept all console.log, console.warn, and console.error calls:
import { initHealOpsLogger } from '@sourabhkumawat0105/healops-opentelemetry';
// Console interception is enabled by default
const logger = initHealOpsLogger({
apiKey: 'your-api-key',
serviceName: 'my-app',
endpoint: 'https://engine.healops.ai'
});
// These are automatically sent to HealOps:
console.log('User clicked button'); // → Sent as INFO
console.warn('Slow API response'); // → Sent as WARNING
console.error('Failed to load data'); // → Sent as ERROR
console.error(new Error('Something broke')); // → Sent as ERROR with stack trace
// Disable console interception:
const logger2 = initHealOpsLogger(config, false);Configuration
API Reference
initHealOpsOTel(config) - Node.js OpenTelemetry
Initializes automatic OpenTelemetry instrumentation for Node.js applications.
interface HealOpsConfig {
apiKey: string; // Required: Your HealOps API key
serviceName: string; // Required: Name of your service
endpoint?: string; // Optional: Endpoint URL (default: https://engine.healops.ai/otel/errors)
}createLogger(config) - Manual Logger
Creates a logger instance for manual logging.
interface HealOpsLoggerConfig {
apiKey: string; // Required: Your HealOps API key
serviceName: string; // Required: Name of your service
endpoint?: string; // Optional: Endpoint URL (default: https://engine.healops.ai)
source?: string; // Optional: Source identifier (e.g., 'frontend', 'backend')
}initHealOpsLogger(config, interceptConsole?) - Browser Logger
Initializes logger with automatic error catching for browser applications.
interface HealOpsLoggerConfig {
apiKey: string; // Required: Your HealOps API key
serviceName: string; // Required: Name of your service
endpoint?: string; // Optional: Endpoint URL (default: https://engine.healops.ai)
source?: string; // Optional: Source identifier (e.g., 'frontend')
}
// Parameters:
// config: HealOpsLoggerConfig
// interceptConsole: boolean (default: true) - Whether to intercept console methodsLogger Methods
logger.info(message: string, metadata?: Record<string, any>): void;
logger.warn(message: string, metadata?: Record<string, any>): void;
logger.error(message: string, metadata?: Record<string, any>): void;
logger.critical(message: string, metadata?: Record<string, any>): void;What Gets Logged?
Log Severity Levels
| Severity | Broadcast | Persisted | Creates Incident | Use Case | |----------|-----------|-----------|------------------|----------| | INFO | ✅ | ✅ | ❌ | General information, user actions | | WARNING | ✅ | ✅ | ❌ | Potential issues, deprecations | | ERROR | ✅ | ✅ | ✅ | Errors that need attention | | CRITICAL | ✅ | ✅ | ✅ | Critical failures, system down |
Key Points:
- ✅ All logs are stored in the database for complete observability
- ✅ Live logs show all severity levels in real-time via WebSocket
- ✅ Incidents are only created from ERROR and CRITICAL logs
- ✅ Search & query across all log levels in the dashboard
Automatic Metadata
The logger automatically captures:
- Browser: File path, line number, column number (from stack trace)
- All: Timestamp, service name, source
- Errors: Error name, message, stack trace
Example log payload:
{
"service_name": "my-app",
"severity": "ERROR",
"message": "Database connection failed",
"source": "backend",
"timestamp": "2024-01-15T10:30:00.000Z",
"metadata": {
"error": "Connection timeout",
"database": "postgres",
"filePath": "/app/src/db.js",
"line": 42,
"column": 15
}
}Troubleshooting
Logs not appearing in HealOps dashboard?
Check API Key: Ensure your API key is correct and active
console.log('API Key:', process.env.HEALOPS_API_KEY?.substring(0, 10) + '...');Check Network Requests: Open browser DevTools → Network tab, filter for
engine.healops.ai- Look for POST requests to
/ingest/logs - Check if requests are successful (200 status)
- Check for CORS errors
- Look for POST requests to
Check Console for Errors: The logger logs errors when it fails to send:
HealOps Logger failed to send ERROR log: { message: "...", statusCode: 401, ... }Verify Endpoint: Ensure your endpoint is correct
// Default endpoint endpoint: 'https://engine.healops.ai'Check CORS: If using browser, ensure
engine.healops.aiallows requests from your domain
Common Issues
Issue: "Failed to send log: 401 Unauthorized"
- Solution: Check your API key is correct
Issue: "Failed to send log: CORS error"
- Solution: Ensure CORS is configured on the backend to allow your domain
Issue: "Not seeing logs in the database"
- Solution: All logs are persisted. Check your database connection and ensure the API key has the correct permissions.
Issue: "Errors not being caught automatically"
- Solution: Ensure
initHealOpsLogger()is called before any errors occur (at app startup)
Environment Variables
Node.js
HEALOPS_API_KEY=your-api-key-hereBrowser (Next.js)
NEXT_PUBLIC_HEALOPS_API_KEY=your-api-key-hereBrowser (React)
REACT_APP_HEALOPS_API_KEY=your-api-key-hereBrowser (Vue)
VUE_APP_HEALOPS_API_KEY=your-api-key-hereExamples
See the examples/ directory for complete working examples:
logger-example.js- Basic logger usage- More examples coming soon!
Support
- Documentation: HealOps Docs
- Issues: GitHub Issues
- Email: [email protected]
License
MIT
