@onlineapps/monitoring-core
v1.0.8
Published
Full monitoring stack (logs, metrics, traces) for OA Drive microservices
Downloads
1,153
Readme
@onlineapps/monitoring-core
Core monitoring infrastructure for OA Drive microservices using OpenTelemetry.
Architecture Pattern
This library uses a Factory Pattern instead of singleton to allow:
- Multiple independent instances with different configurations
- Better testability and isolation
- Parallel running of services
- Clean separation between service instances
Installation
npm install @onlineapps/monitoring-coreUsage
Factory Pattern (Recommended)
Create independent instances for each service:
const { init } = require('@onlineapps/monitoring-core');
// Create new instance with factory
const monitoring = await init({
serviceName: 'my-service',
serviceVersion: '1.0.0',
mode: 'light', // off | light | full | debug
logLevel: 'INFO'
});
// Use the instance
monitoring.logger.info('Service started');
monitoring.startWorkflow('wf-1', 'process');Multiple Instances
Each service can have its own configuration:
// Service 1
const service1 = await init({
serviceName: 'api-gateway',
mode: 'full'
});
// Service 2 - independent configuration
const service2 = await init({
serviceName: 'worker',
mode: 'light'
});Direct Module Usage
For simple logging without full telemetry:
const { createLogger, WorkflowTracker } = require('@onlineapps/monitoring-core');
// Standalone logger
const logger = createLogger({
serviceName: 'simple-service',
mode: 'off'
});
// Standalone workflow tracker
const tracker = new WorkflowTracker('my-service');Configuration Modes
| Mode | Use Case | Features | Performance Impact |
|------|----------|----------|-------------------|
| off | Testing, Development | Console logging only | Minimal |
| light | Production | Logs + Basic metrics | Low |
| full | Staging | Logs + Metrics + Traces | Medium |
| debug | Debugging | Everything + Debug info | High |
API Reference
init(options)
Factory function to create new monitoring instance.
const monitoring = await init({
serviceName: 'my-service', // Required
serviceVersion: '1.0.0', // Optional
mode: 'light', // Optional (default: 'off')
logLevel: 'INFO', // Optional (default: 'INFO')
environment: 'production', // Optional
samplingRatio: 1.0, // Optional (0-1)
rabbitmq: { // Optional
url: 'amqp://localhost:5672',
exchange: 'telemetry.exchange'
}
});Logger Methods
monitoring.logger.debug('Debug message', { data });
monitoring.logger.info('Info message', { data });
monitoring.logger.warn('Warning message', { data });
monitoring.logger.error('Error message', { error });Workflow Tracking
// Start workflow
monitoring.startWorkflow('wf-123', 'process-type', {
userId: '456',
source: 'api'
});
// Add workflow step
monitoring.stepWorkflow('wf-123', 'validation', {
status: 'success'
});
// End workflow
monitoring.endWorkflow('wf-123', 'completed', {
recordsProcessed: 100
});Metrics
// Counter
const counter = monitoring.createCounter('requests_total', {
description: 'Total requests'
});
counter.add(1, { endpoint: '/api/users' });
// Histogram
const histogram = monitoring.createHistogram('response_time', {
description: 'Response time in ms',
unit: 'ms'
});
histogram.record(235, { endpoint: '/api/users' });Testing
The factory pattern makes testing much easier:
describe('MyService', () => {
let monitoring;
beforeEach(async () => {
// Fresh instance for each test
monitoring = await init({
serviceName: 'test-service',
mode: 'off' // No external connections
});
});
afterEach(async () => {
await monitoring.shutdown();
});
test('should log messages', () => {
monitoring.logger.info('Test message');
// No singleton state pollution
});
});Environment Variables
MONITORING_MODE- Override configuration modeOTEL_EXPORTER_OTLP_ENDPOINT- OpenTelemetry collector endpointMONITORING_LOG_LEVEL- Override log level
Migration from Singleton
If you have old code using singleton pattern:
// Old (singleton)
const monitoring = require('@onlineapps/monitoring-core');
monitoring.init({ serviceName: 'old-way' });
// New (factory)
const { init } = require('@onlineapps/monitoring-core');
const monitoring = await init({ serviceName: 'new-way' });API Design Decisions
activeWorkflows Map Encapsulation
The WorkflowTracker class maintains an internal activeWorkflows Map for tracking currently running workflows. This is intentionally NOT exposed directly in the public API.
Why it's private:
- Internal implementation detail that may change
- Direct access breaks encapsulation
- Could lead to state inconsistencies if modified externally
Public API alternatives provided:
// Check if specific workflow is active
tracker.isWorkflowActive(workflowId) // returns boolean
// Get count of active workflows (for monitoring)
tracker.getActiveWorkflowCount() // returns number
// Get workflow info (read-only copy)
tracker.getWorkflowInfo(workflowId) // returns object or nullThese methods provide controlled access for testing and monitoring without exposing internal state.
Performance Considerations
- Use
mode: 'light'for production (5MB overhead) - Use
mode: 'off'for unit tests (0MB overhead) - Each instance has its own telemetry pipeline
- Batching reduces network overhead
Test Coverage
Current test coverage: 45.26%
- Logger: 80.48%
- Workflow: 100%
- Core modules tested with 77 passing tests
License
MIT
