@hemantwasthere/monitoring-sdk
Version:
Centralized monitoring SDK for Node.js applications with Prometheus, Loki, and Grafana integration
397 lines (306 loc) ⢠11 kB
Markdown
# @hemantwasthere/monitoring-sdk
> Comprehensive monitoring SDK for Node.js applications with Prometheus, Loki, and Grafana integration
## š Quick Start
```bash
npm install @hemantwasthere/monitoring-sdk
```
```typescript
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:
```bash
# 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:
```typescript
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:
```typescript
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
```typescript
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
```typescript
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
```typescript
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
```typescript
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
```typescript
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
```typescript
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
```typescript
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:
```bash
# 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
```typescript
// 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
```bash
# .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 times
- `http_requests_total` - Total request count by method, route, status
### Cron Job Metrics
- `cron_job_duration_seconds` - Job execution time
- `cron_job_executions_total` - Total job executions
- `cron_job_failures_total` - Failed job count
### System Metrics (when enabled)
- Node.js process metrics (memory, CPU, GC)
- Event loop lag
- Heap usage
## Best Practices
1. **Set Global Config Once**: Use `setGlobalConfig()` at application startup
2. **Consistent Naming**: Use kebab-case for project and service names
3. **Meaningful Labels**: Add relevant labels to metrics for better filtering
4. **Error Handling**: Always handle monitoring errors gracefully
5. **Resource Cleanup**: Monitoring shouldn't impact application performance
## Troubleshooting
### Common Issues
1. **Loki Connection Failed**: Ensure Loki host is accessible and port 3100 is open
2. **Metrics Not Appearing**: Check if `/metrics` endpoint is properly exposed
3. **High Memory Usage**: Reduce metric cardinality by limiting label values
### Debug Mode
```typescript
MonitoringSDK.setGlobalConfig({
logLevel: 'debug',
// ... other config
});
```
## Contributing
We welcome contributions! Please see our [Contributing Guide](https://github.com/unwrap-labs/monitoring-setup/blob/main/CONTRIBUTING.md) for details.
## License
MIT - see [LICENSE](LICENSE) file for details.
## Support
- š [Documentation](https://github.com/unwrap-labs/monitoring-setup)
- š [Issue Tracker](https://github.com/unwrap-labs/monitoring-setup/issues)
- š¬ [Discussions](https://github.com/unwrap-labs/monitoring-setup/discussions)
## š 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
```text
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
```