npm package: @onlineapps/monitoring-core
Description: Full monitoring stack (logs, metrics, traces) for OA Drive microservices
Latest version: 1.0.21

# @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

```bash
npm install @onlineapps/monitoring-core
```

## Usage

### Factory Pattern (Recommended)

Create independent instances for each service:

```javascript
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:

```javascript
// 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:

```javascript
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.

```javascript
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://127.0.0.1:5672',
    exchange: 'telemetry.exchange'
  }
});
```

### Logger Methods

```javascript
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

```javascript
// 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

```javascript
// 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:

```javascript
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 mode
- `OTEL_EXPORTER_OTLP_ENDPOINT` - OpenTelemetry collector endpoint
- `MONITORING_LOG_LEVEL` - Override log level

## Migration from Singleton

If you have old code using singleton pattern:

```javascript
// 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:**
```javascript
// 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 null
```

These 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