Package Exports
- @hemantwasthere/monitoring-sdk
- @hemantwasthere/monitoring-sdk/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@hemantwasthere/monitoring-sdk) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@hemantwasthere/monitoring-sdk
Comprehensive monitoring SDK for Node.js applications with Prometheus, Loki, and Grafana integration
🚀 Quick Start
npm install @hemantwasthere/monitoring-sdk
import { MonitoringSDK } from '@hemantwasthere/monitoring-sdk';
const monitoring = MonitoringSDK.initializeWithDefaults({
projectName: 'my-app',
serviceName: 'api-server',
technology: 'express' // 'nestjs', 'nodejs'
});
// Automatic HTTP monitoring
app.use(monitoring.express.middleware());
// Custom metrics
monitoring.metrics.incrementCounter('orders_total');
monitoring.logger.info('Order processed', { orderId: '123' });
📊 Features
- ✅ Easy Integration: Drop-in for Express, NestJS, Node.js
- ✅ Prometheus Metrics: HTTP metrics + custom counters/gauges
- ✅ Centralized Logging: Structured logs to Loki via Winston
- ✅ Cron Monitoring: Built-in job monitoring decorators
- ✅ Auto Configuration: Environment-based setup
- ✅ Consistent Labels: Standardized across all metrics/logs
⚙️ Configuration
Set environment variables:
# Required
LOKI_HOST=http://localhost:3100
PROMETHEUS_HOST=http://localhost:9090
# Optional
PROJECT_NAME=my-project
NODE_ENV=development
export LOKI_URL=http://your-monitoring-server:3100 export NODE_ENV=production export CLUSTER_NAME=prod-cluster
```typescript
import { MonitoringSDK } from '@hemantwasthere/monitoring-sdk';
// Auto-configures from environment variables
const monitoring = MonitoringSDK.initializeWithDefaults({
projectName: 'my-project',
serviceName: 'user-service',
technology: 'nestjs'
});
Method 2: Global Configuration (Recommended)
Set up global configuration once at your application startup:
import { MonitoringSDK } from '@hemantwasthere/monitoring-sdk';
// Set global configuration once
MonitoringSDK.setGlobalConfig({
lokiHost: 'http://your-monitoring-server:3100',
environment: process.env.NODE_ENV || 'development',
logLevel: 'info',
customLabels: {
region: 'us-east-1',
cluster: 'prod-cluster'
}
});
// Now initialize each service without repeating common configuration
const monitoring = MonitoringSDK.initialize({
projectName: 'my-project',
serviceName: 'user-service',
technology: 'nestjs'
});
Method 3: Full Configuration (Most Control)
Configure everything explicitly for each service:
const monitoring = MonitoringSDK.initialize({
projectName: 'my-project',
serviceName: 'user-service',
technology: 'nestjs',
lokiHost: 'http://your-monitoring-server:3100',
environment: 'production',
logLevel: 'info',
customLabels: { region: 'us-east-1' }
});
Summary:
- Method 1: Perfect for microservices with consistent environment setup
- Method 2: Best for applications where you want explicit control over global config
- Method 3: Use when each service needs different configuration
Framework Integration
NestJS
import { MonitoringSDK, MonitoringInterceptor } from '@hemantwasthere/monitoring-sdk';
import { APP_INTERCEPTOR } from '@nestjs/core';
// In your main.ts
MonitoringSDK.setGlobalConfig({
lokiHost: 'http://monitoring-server:3100',
environment: process.env.NODE_ENV,
});
const monitoring = MonitoringSDK.initialize({
projectName: 'ecommerce',
serviceName: 'user-service',
technology: 'nestjs'
});
// In your AppModule
@Module({
providers: [
{
provide: APP_INTERCEPTOR,
useClass: MonitoringInterceptor,
},
],
})
export class AppModule {}
// Add metrics endpoint
app.getHttpAdapter().get('/metrics', async (req, res) => {
const metrics = await monitoring.getMetrics().getMetrics();
res.setHeader('Content-Type', monitoring.getMetrics().getRegistry().contentType);
res.send(metrics);
});
// Add health endpoint
app.getHttpAdapter().get('/health', (req, res) => {
res.json({ status: 'ok', timestamp: new Date().toISOString() });
});
Express
import { MonitoringSDK, expressMetricsMiddleware, MonitoringController } from '@hemantwasthere/monitoring-sdk';
MonitoringSDK.setGlobalConfig({
lokiHost: 'http://monitoring-server:3100',
environment: process.env.NODE_ENV,
});
const monitoring = MonitoringSDK.initialize({
projectName: 'my-project',
serviceName: 'payment-service',
technology: 'express'
});
const app = express();
// Add metrics middleware
app.use(expressMetricsMiddleware());
// Add monitoring endpoints
const controller = new MonitoringController();
app.get('/metrics', (req, res) => controller.getMetrics(req, res));
app.get('/health', (req, res) => controller.getHealth(req, res));
Cron Job Monitoring
import { CronMonitor } from '@hemantwasthere/monitoring-sdk';
class DataProcessingService {
@CronMonitor.monitor('daily-report-generation')
async generateDailyReports() {
// Your cron job logic here
// Metrics will be automatically collected:
// - Execution duration
// - Success/failure counts
// - Error details if job fails
}
@CronMonitor.monitor('cleanup-old-data', { timeout: 30000 })
async cleanupOldData() {
// Job with custom timeout
}
}
Custom Metrics
const monitoring = MonitoringSDK.getInstance();
const metrics = monitoring.getMetrics();
// Counter
const orderCounter = metrics.createCounter('orders_total', 'Total orders processed', ['status', 'payment_method']);
orderCounter.inc({ status: 'completed', payment_method: 'credit_card' });
// Gauge
const activeUsers = metrics.createGauge('active_users', 'Number of active users');
activeUsers.set(150);
// Histogram
const responseTime = metrics.createHistogram('api_response_time', 'API response time', ['endpoint']);
responseTime.observe({ endpoint: '/api/users' }, 0.25);
Logging
const monitoring = MonitoringSDK.getInstance();
const logger = monitoring.getLogger();
logger.info('User logged in', {
userId: '12345',
correlationId: 'abc-123'
});
logger.error('Database connection failed', {
error: 'Connection timeout',
database: 'users-db'
});
Configuration Options
Global Configuration
interface GlobalMonitoringConfig {
lokiHost: string; // Loki server URL
environment?: string; // Environment name (dev, prod, etc.)
logLevel?: string; // Log level (info, debug, error)
customLabels?: Record<string, string>; // Labels added to all metrics/logs
}
Service Configuration
interface MonitoringConfig {
projectName: string; // Project/application name
serviceName: string; // Service name within the project
technology: string; // Technology stack (nestjs, express, nodejs)
environment?: string; // Override global environment
lokiHost?: string; // Override global Loki host
metricsPath?: string; // Custom metrics endpoint path
logLevel?: string; // Override global log level
enableDefaultMetrics?: boolean; // Enable Node.js default metrics
prefixDefaultMetrics?: boolean; // Prefix default metrics with project_service_
customLabels?: Record<string, string>; // Additional service-specific labels
}
Production Deployment
1. Docker Compose (Monitoring Stack)
Deploy the centralized monitoring stack:
# Clone the monitoring setup
git clone https://github.com/unwrap-labs/monitoring-setup.git
cd monitoring-setup/centralized-stack
# Start the monitoring stack
docker-compose up -d
This provides:
- Prometheus (metrics): http://localhost:9090
- Grafana (dashboards): http://localhost:3000
- Loki (logs): http://localhost:3100
- AlertManager (alerts): http://localhost:9093
2. Application Configuration
// Production configuration
MonitoringSDK.setGlobalConfig({
lokiHost: process.env.LOKI_URL || 'http://monitoring-cluster:3100',
environment: 'production',
logLevel: 'info',
customLabels: {
cluster: process.env.CLUSTER_NAME
}
});
3. Environment Variables
# .env
LOKI_URL=http://your-monitoring-cluster:3100
NODE_ENV=production
LOG_LEVEL=info
CLUSTER_NAME=prod-cluster
Collected Metrics
HTTP Metrics
http_request_duration_milliseconds
- Request response timeshttp_requests_total
- Total request count by method, route, status
Cron Job Metrics
cron_job_duration_seconds
- Job execution timecron_job_executions_total
- Total job executionscron_job_failures_total
- Failed job count
System Metrics (when enabled)
- Node.js process metrics (memory, CPU, GC)
- Event loop lag
- Heap usage
Best Practices
- Set Global Config Once: Use
setGlobalConfig()
at application startup - Consistent Naming: Use kebab-case for project and service names
- Meaningful Labels: Add relevant labels to metrics for better filtering
- Error Handling: Always handle monitoring errors gracefully
- Resource Cleanup: Monitoring shouldn't impact application performance
Troubleshooting
Common Issues
- Loki Connection Failed: Ensure Loki host is accessible and port 3100 is open
- Metrics Not Appearing: Check if
/metrics
endpoint is properly exposed - High Memory Usage: Reduce metric cardinality by limiting label values
Debug Mode
MonitoringSDK.setGlobalConfig({
logLevel: 'debug',
// ... other config
});
Contributing
We welcome contributions! Please see our Contributing Guide for details.
License
MIT - see LICENSE file for details.
Support
📝 Examples
Check the examples/
directory for complete integration examples:
- Express.js:
examples/apps/express-example.ts
- NestJS:
examples/apps/nestjs-example.ts
- Node.js:
examples/apps/nodejs-example.ts
Each example shows how to integrate the monitoring SDK with different frameworks and use cases.
📁 Package Structure
monitoring-sdk/
├── src/ # Source code
│ ├── index.ts # Main entry point
│ ├── metrics.ts # Prometheus metrics
│ ├── logging.ts # Loki logging
│ ├── cron-monitor.ts # Cron job monitoring
│ └── middleware/ # Framework integrations
├── examples/ # Integration examples
│ └── apps/ # Framework-specific examples
├── dist/ # Compiled JavaScript
└── package.json # NPM configuration