Commit Graph

2227 Commits

Author SHA1 Message Date
Claude 6f057b8895 fix(metrics,retry): address gold standard code review
Prometheus Metrics:
- Add METRICS_LABELS fallback for defaultLabels env config
- Separate includeSystem from collectDefaultMetrics with own env var
- Parse URL in /metrics endpoint to support querystrings and trailing slashes
- Sort keys in labelsToKey for stable/deterministic lookups
- Update documentation with all environment variables

Retry Utils:
- Remove abort listener on sleep completion to prevent memory leak
- Apply maxDelay cap AFTER jitter to guarantee max delay limit
- Validate/normalize attempt parameter in calculateDelay
- Count retries only when attempt > 1 (actual retry, not first try)
- Use metrics.retryExhausted instead of generic errors for exhausted retries

Tests:
- Add consistency tests to verify retryConfigs.rsocket matches constants
2026-01-20 19:37:19 +00:00
Claude 1944645556 fix(metrics): fix configureRegistry call signature
Update configureRegistry call to match new signature that accepts
only defaultLabels parameter instead of config object.
2026-01-20 14:44:53 +00:00
Claude baf9123d0c fix(retry): address PR #15 code review feedback
- Re-export RETRY_BACKOFF_DELAYS and RETRY_JITTER_FACTOR from Defaults
  for backwards compatibility with existing imports
- Add 'as const' to RETRY_JITTER_FACTOR for type consistency
- Improve documentation explaining why values are hardcoded in retryConfigs
  (ESM initialization order issues with indirect circular imports)
2026-01-20 14:34:47 +00:00
Claude 890a80da48 fix(retry): use literal values in retryConfigs to fix ESM initialization
Hardcode values in retryConfigs.rsocket instead of referencing
RETRY_BACKOFF_DELAYS and RETRY_JITTER_FACTOR to avoid
"Cannot access before initialization" error in ESM module loading.
2026-01-20 14:25:56 +00:00
Claude cf979d6b6d fix(retry): resolve RETRY_BACKOFF_DELAYS initialization order error
- Remove duplicate RETRY_BACKOFF_DELAYS and RETRY_JITTER_FACTOR from Defaults/index.ts
- Export constants from retry-utils.ts as single source of truth
- Add 'as const' for better type inference
- Fixes "Cannot access 'RETRY_BACKOFF_DELAYS' before initialization" error
2026-01-20 14:17:18 +00:00
Claude 37fdce4bf3 fix(metrics): address PR #14 code review feedback
- Add registryConfigured flag to ensure single execution of configureRegistry
- Fix race condition by moving setMetricPrefix/configureRegistry before Promise
- Remove unused prefix parameter from configureRegistry function
- Consolidate prefix to single source of truth (configuredPrefix global)
- Allow clearing default labels by passing empty object
- Add resetMetricsConfiguration() and getConfiguredPrefix() for testing
2026-01-20 13:45:26 +00:00
Claude af4563ee6a Merge remote-tracking branch 'origin/master' into claude/prom-client-nglwZ 2026-01-20 13:27:02 +00:00
Claude 82dce29dbd fix(metrics): address PR #13 code review feedback
- Apply configured prefix to all metric names via getFullMetricName()
- Configure customRegistry with defaultLabels at initialization
- Prevent memory leak: collectDefaultMetrics only called once via flag
- collectDefaultMetrics now uses customRegistry instead of global
- Initialize prefix/defaultLabels before creating baileysMetrics

All metrics now properly include prefix (e.g., baileys_connection_attempts)
and inherit defaultLabels configured via environment variables.
2026-01-20 13:25:21 +00:00
Renato Alcara 168de69e73 fix(metrics): address PR #11 code review feedback
fix(metrics): address PR #11 code review feedback
2026-01-20 10:20:18 -03:00
Claude 4924912f85 fix(metrics): address PR #11 code review feedback
Major improvements to prometheus-metrics.ts:
- Use custom registry instead of global promClient.register (isolation)
- Remove duplicate localValues - prom-client is now single source of truth
- Fix reset(labels) to respect labels param using remove() instead of reset()
- Migrate Summary class to use prom-client internally
- getMetricsOutput() now uses customRegistry for proper isolation

Fix misleading comments in retry-utils.ts:
- Change "exponential backoff" to "custom progressive backoff"
- Fix comment claiming constants are "from Defaults" (now local)

Breaking changes to getValues()/get() - now async as they query prom-client
2026-01-20 13:16:43 +00:00
Renato Alcara 833d6b14af b719349 fix(retry): address PR #12 code review feedback
b719349 fix(retry): address PR #12 code review feedback
2026-01-20 10:12:03 -03:00
Claude b719349c57 fix(retry): address PR #12 code review feedback
- Add 'stepped' backoff strategy that uses RETRY_BACKOFF_DELAYS directly
- Update rsocket config to use 'stepped' instead of 'exponential'
- Clarify maxWebSocketListeners calculation (8 core + 10 dynamic + 2 buffer)
- Document maxSocketClientListeners calculation (20 core + 20 dynamic + 10 buffer)
- Change 'exponential backoff' to 'custom progressive backoff' in docs
- Add comprehensive tests for getRetryDelayWithJitter and getAllRetryDelaysWithJitter
- Fix existing test type errors (onRetry mock, always/never predicates)
2026-01-20 13:05:13 +00:00
Renato Alcara b21847addb Merge branch 'WhiskeySockets:master' into master 2026-01-20 09:58:02 -03:00
Claude 2d84da8bd7 fix(retry): resolve circular dependency with Defaults module
Define RETRY_BACKOFF_DELAYS and RETRY_JITTER_FACTOR locally in
retry-utils.ts to avoid circular dependency that caused
"Cannot access 'RETRY_BACKOFF_DELAYS' before initialization" error.
2026-01-20 12:37:18 +00:00
Claude 43ece09fe9 feat(metrics): integrate prom-client for native Prometheus support
- Add prom-client ^15.1.3 as production dependency
- Migrate Counter class to use prom-client internally
- Migrate Gauge class to use prom-client internally
- Migrate Histogram class to use prom-client internally
- Update getMetricsOutput() to use prom-client's native metrics()
- Update contentType() to use prom-client's contentType
- Enable collectDefaultMetrics() for Node.js system metrics
- Maintain backward compatibility with existing API

Benefits:
- Native OpenMetrics format export
- Proper histogram bucket handling
- Default Node.js metrics (memory, CPU, event loop, GC)
- Better integration with Grafana/Prometheus ecosystem
2026-01-20 12:37:17 +00:00
Claude e605a02528 fix(defaults): address PR #10 code review feedback
- Integrate RETRY_BACKOFF_DELAYS and RETRY_JITTER_FACTOR into retry-utils.ts
  - Add retryConfigs.rsocket using the default delays
  - Add getRetryDelayWithJitter() helper function
  - Add getAllRetryDelaysWithJitter() for planning
- Document DEFAULT_CACHE_MAX_KEYS with usage example
- Adjust INITIAL_PREKEY_COUNT from 30 to 200 (moderate value)
- Adjust MIN_UPLOAD_INTERVAL from 60s to 10s (balance rate limiting/responsiveness)
- Revert syncFullHistory to true (avoid breaking change)
2026-01-20 12:36:52 +00:00
Claude 6f75e5ac21 feat(socket): add configurable maxListeners to prevent memory leaks
Based on RSocket's battle-tested configuration:

- Add maxWebSocketListeners config option (default: 20)
  - 8 base WS events + 10 dynamic listeners + 2 buffer slots
- Add maxSocketClientListeners config option (default: 50)
- Replace dangerous setMaxListeners(0) with configurable limits
- Add warning log if user explicitly sets limit to 0

BREAKING: Previous behavior used setMaxListeners(0) which removed
all limits. Now defaults to safe limits but can be overridden via config.
2026-01-20 12:36:51 +00:00
Claude 682b62acbf feat(defaults): apply RSocket's battle-tested configurations
- Add DEFAULT_CACHE_MAX_KEYS with limits per store type (prevents memory leaks)
- Add RETRY_BACKOFF_DELAYS [1s, 2s, 5s, 10s, 20s] for exponential backoff
- Add RETRY_JITTER_FACTOR (0.15) to prevent thundering herd
- Change INITIAL_PREKEY_COUNT from 812 to 30 (safer for rate limiting)
- Change MIN_UPLOAD_INTERVAL from 5s to 60s (avoids rate limiting)
- Change syncFullHistory default to false (conservative approach)

Based on RSocket fork's production-tested configuration.
2026-01-20 12:36:51 +00:00
Renato Alcara 1e534bb7a8 feat(defaults): apply RSocket battle-tested configurations for stability
feat(defaults): apply RSocket battle-tested configurations for stability
2026-01-20 08:44:14 -03:00
Rajeh Taher b6b708ddfe chore(tests): lint 2026-01-20 12:47:05 +02:00
Enzo Nascimento a1d69f72c9 fix(utils.normalizeMessageContent): add associatedChildMessage as one of the options to normalize (#1874)
Co-authored-by: Rajeh Taher <rajeh@reforward.dev>
2026-01-20 12:46:03 +02:00
Rajeh Taher 90e8ba82f4 Cache the children after a getBinaryNodeChild/ren call to avoid traversing arrays (#2093)
* generic-utils: cache the get

* generic-utils: increased type safety

* chore: lint
2026-01-20 12:43:27 +02:00
David ??? d36d9c194c Add groupStatusMessage checks in message handling (#2258) 2026-01-20 12:41:33 +02:00
João Lucas de Oliveira Lopes 8ff01b8bb3 fix: store LID-PN mapping from contactAction sync (#2266)
* fix: store LID-PN mapping from contactAction sync

* chore: improve testing of sync actions
2026-01-20 12:39:41 +02:00
João Lucas de Oliveira Lopes a89736f89d fix: extract LID-PN mappings from history sync phoneNumberToLidMappings (#2268) 2026-01-20 12:39:29 +02:00
Luiz Braga 32134a870e chore: Add messageTimestamp to message updates in messages-recv when receiving a message status update (#2277) 2026-01-20 12:37:34 +02:00
João Lucas de Oliveira Lopes 5887551d68 fix: resolve race condition in decodeFrame handling and improve encryption integrity (#2182)
* fix: resolve race condition in decodeFrame handling and improve encryption integrity

* chore: pr feedback
2026-01-20 12:37:04 +02:00
github-actions[bot] 4bdcedf96b chore: update WhatsApp Web version (#2269)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-20 12:35:35 +02:00
Claude 4a2731fbbd fix(defaults): address PR #10 code review feedback
- Integrate RETRY_BACKOFF_DELAYS and RETRY_JITTER_FACTOR into retry-utils.ts
  - Add retryConfigs.rsocket using the default delays
  - Add getRetryDelayWithJitter() helper function
  - Add getAllRetryDelaysWithJitter() for planning
- Document DEFAULT_CACHE_MAX_KEYS with usage example
- Adjust INITIAL_PREKEY_COUNT from 30 to 200 (moderate value)
- Adjust MIN_UPLOAD_INTERVAL from 60s to 10s (balance rate limiting/responsiveness)
- Revert syncFullHistory to true (avoid breaking change)
2026-01-20 05:33:03 +00:00
Claude 3afb8b80c5 feat(socket): add configurable maxListeners to prevent memory leaks
Based on RSocket's battle-tested configuration:

- Add maxWebSocketListeners config option (default: 20)
  - 8 base WS events + 10 dynamic listeners + 2 buffer slots
- Add maxSocketClientListeners config option (default: 50)
- Replace dangerous setMaxListeners(0) with configurable limits
- Add warning log if user explicitly sets limit to 0

BREAKING: Previous behavior used setMaxListeners(0) which removed
all limits. Now defaults to safe limits but can be overridden via config.
2026-01-20 05:19:22 +00:00
Claude 4f623b4942 feat(defaults): apply RSocket's battle-tested configurations
- Add DEFAULT_CACHE_MAX_KEYS with limits per store type (prevents memory leaks)
- Add RETRY_BACKOFF_DELAYS [1s, 2s, 5s, 10s, 20s] for exponential backoff
- Add RETRY_JITTER_FACTOR (0.15) to prevent thundering herd
- Change INITIAL_PREKEY_COUNT from 812 to 30 (safer for rate limiting)
- Change MIN_UPLOAD_INTERVAL from 5s to 60s (avoids rate limiting)
- Change syncFullHistory default to false (conservative approach)

Based on RSocket fork's production-tested configuration.
2026-01-20 05:12:05 +00:00
Renato Alcara aa2ff855bd feat(lid-mapping): enhance with enterprise-grade features
feat(lid-mapping): enhance with enterprise-grade features
2026-01-20 02:06:23 -03:00
Claude 4e68f9885c fix(lid-mapping): address PR #9 code review feedback
- Add bounds validation for config values (prevent DoS via env vars)
- Replace ?? false with || false in isValidMapping (correct operator)
- Rename deleteMapping to deleteMappingFromCache (clarify behavior)
- Keep deleteMapping as deprecated alias for backward compatibility
- Document destroyed state handling in read-only methods
- Document async metrics module loading race condition
- Document storeLIDPNMappings return type change
- Add failure tracking and warning in getLIDsForPNs
- Document exponential backoff retry pattern in config and method
2026-01-20 05:04:25 +00:00
Claude ab96bb69db feat(structured-logger): enhance with enterprise-grade features
- Add environment variable configuration (BAILEYS_LOG_*)
- Implement log buffering for batch writes with configurable flush interval
- Add rate limiting using token bucket algorithm to prevent log flooding
- Implement async logging queue for non-blocking operations
- Add circuit breaker pattern for external hook failures
- Add destroy() method for proper resource cleanup
- Add comprehensive statistics tracking (metrics)
- Add Prometheus metrics integration support
- Improve type safety with ResolvedLoggerConfig type
2026-01-20 04:57:41 +00:00
Claude 0688a5ec4a feat(lid-mapping): enhance with enterprise-grade features
Major improvements to LIDMappingStore:

Configuration (BAILEYS_LID_* env vars):
- BAILEYS_LID_CACHE_TTL_MS: Cache TTL (default: 3 days)
- BAILEYS_LID_MAX_CACHE_SIZE: Max cache entries (default: 50000)
- BAILEYS_LID_BATCH_SIZE: Batch size for bulk ops (default: 100)
- BAILEYS_LID_RETRY_ATTEMPTS: Retry attempts (default: 3)
- BAILEYS_LID_RETRY_DELAY_MS: Retry delay (default: 1000)
- BAILEYS_LID_METRICS: Enable Prometheus metrics
- BAILEYS_LID_DEBUG: Enable debug logging

New Features:
- Comprehensive statistics tracking (getStatistics())
- Cache warming capability (warmCache())
- Cache management (clearCache(), getCacheInfo())
- Batch operations for bulk mappings
- Retry logic with exponential backoff
- Custom error types (LIDMappingError, LIDMappingErrorCode)
- Proper resource cleanup (destroy())
- hasMappingForPN() for existence checks
- deleteMapping() for cache invalidation

Enterprise Patterns:
- Environment variable configuration
- Statistics and metrics integration
- Retry with exponential backoff
- Destroyed state protection
- Batch processing for performance
- Detailed error codes and messages
2026-01-20 04:42:08 +00:00
Renato Alcara b700073a23 Merge pull request #8
fix(metrics): clear startPromise on stop() to allow restart
2026-01-20 01:30:37 -03:00
Claude 33b44ff19d fix(metrics): clear startPromise on stop() to allow restart
FIX: startPromise was never cleared after stop(), causing start()
to return the old resolved promise instead of creating a new server.

This broke any flow that stops and restarts metrics (config reloads, tests).

Now stop() clears startPromise, allowing proper server restart.
2026-01-20 04:26:27 +00:00
Renato Alcara ea96be2bc9 Merge pull request #7
fix(metrics): address PR #6 code review feedback
2026-01-20 01:23:47 -03:00
Claude 21b632592a fix(metrics): address PR #6 code review feedback
Fixes based on Copilot AI and Codex code review comments:

1. Race Condition Fix (lines 1065-1069):
   - BEFORE: setTimeout(100ms) was incomplete - callers could resolve
     before server was actually ready
   - FIX: Cache the Promise from first start() call using startPromise
   - All concurrent calls now return the same Promise
   - Properly handles both success and error cases

2. CPU Percentage Calculation (lines 993-996):
   - BEFORE: Division by cpuCount gave artificially low values
     (e.g., 25% instead of 100% on 4-core for single-threaded process)
   - FIX: Removed cpuCount division
   - Now follows Unix/Prometheus standard: 100% = 1 core fully used
   - Values can exceed 100% on multi-core (200% = 2 cores at 100%)
   - Updated metric description to clarify this behavior
2026-01-20 04:22:00 +00:00
Renato Alcara 90f310b52d Merge pull request #6
fix(metrics): address PR #4 code review feedback
2026-01-20 01:14:33 -03:00
Claude 834cb75ba4 fix(metrics): address PR #4 code review feedback
Fixes based on Copilot AI and Codex code review comments:

1. CPU Usage Metric (line ~930-933):
   - FIX: process.cpuUsage() now calculates delta between measurements
   - Returns actual percentage (0-100) instead of cumulative seconds
   - Normalized across CPU cores

2. Duplicate SystemMetricsCollector (line ~1353-1355):
   - FIX: Removed duplicate instantiation from PrometheusMetricsManager
   - Now uses MetricsServer's collector via getSystemCollector()

3. Collection Interval (line ~1006-1008):
   - FIX: Added collectIntervalMs to MetricsConfig
   - Configurable via BAILEYS_PROMETHEUS_COLLECT_INTERVAL_MS

4. Error Handling (line ~1021-1022):
   - FIX: Enhanced error messages with structured JSON response
   - Includes error message, timestamp, and logs to console

5. Server Binding Security (line ~1034-1038):
   - FIX: Default host changed from 0.0.0.0 to 127.0.0.1
   - Configurable via BAILEYS_PROMETHEUS_HOST
   - Warning shown if exposed on all interfaces

6. Race Condition (line ~998-1001):
   - FIX: Added isStarting flag to prevent concurrent initialization
   - Multiple concurrent start() calls now handled safely
2026-01-20 04:12:58 +00:00
Renato Alcara b5d69fa693 feat(event-buffer): enhance with enterprise-grade features
feat(event-buffer): enhance with enterprise-grade features
2026-01-20 01:09:37 -03:00
Claude 11e7c71fd1 feat(event-buffer): enhance with enterprise-grade features
- Add environment variable configuration (BAILEYS_BUFFER_*)
- Implement destroy() method for proper resource cleanup
- Add force flush capability with flush(force) parameter
- Implement buffer overflow detection and prevention
- Add adaptive timeout algorithm based on event rate
- Replace historyCache.clear() with LRU cache cleanup
- Integrate Prometheus metrics for buffer monitoring
- Add isDestroyed state protection
- Fix createBufferedFunction to prevent orphaned timers
- Add comprehensive statistics tracking (getStatistics())
- Add configuration accessor (getConfig())

Enterprise features:
- Configurable buffer size limits (maxBufferSize)
- Configurable timeout ranges (min/max)
- LRU cleanup ratio configuration
- Buffer overflow warning threshold
- Adaptive timeout based on event rate
2026-01-20 03:45:52 +00:00
Renato Alcara b2a54d41c5 feat: Enterprise-grade observability with Circuit Breaker and Prometheus Metrics
## Summary
- Integrate Circuit Breaker pattern into Socket operations for resilience
- Enhance Prometheus Metrics to enterprise-grade (60+ metrics)
- Add environment variable configuration for metrics

## Changes

### Circuit Breaker Integration
- 3 Circuit Breakers: `query`, `connection`, `preKey`
- Automatic failure detection and recovery
- Configurable thresholds and timeouts
- `getCircuitBreakerStats()` and `resetCircuitBreakers()` utilities

### Prometheus Metrics Enhancement  
- Increased from 18 to 60+ metrics
- HTTP server endpoint at `:9092/metrics`
- System metrics (CPU, memory, load average)
- Event Buffer, Cache, Retry, Socket metrics
- Environment configuration via `BAILEYS_PROMETHEUS_*`

### Configuration
```env
BAILEYS_PROMETHEUS_ENABLED=true
BAILEYS_PROMETHEUS_PORT=9092
BAILEYS_PROMETHEUS_PREFIX=baileys
BAILEYS_PROMETHEUS_LABELS={"environment":"production","service":"whatsapp-api"}
2026-01-20 00:35:19 -03:00
Claude 8a705e5a1e fix(metrics): update env vars to match BAILEYS_PROMETHEUS_* convention
- Support BAILEYS_PROMETHEUS_ENABLED, BAILEYS_PROMETHEUS_PORT, etc.
- Add support for BAILEYS_PROMETHEUS_LABELS JSON configuration
- Maintain backward compatibility with METRICS_* prefix
- Update default port to 9092 (matching user's .env)
- Enable by opt-in (enabled=false by default)
- Improved startup log with labels info
2026-01-20 03:19:32 +00:00
Claude 0c173212fd feat(metrics): enhance Prometheus metrics with enterprise-grade features
- Add HTTP server for /metrics endpoint with configurable port
- Add environment variable configuration (METRICS_ENABLED, METRICS_PORT, etc.)
- Add SystemMetricsCollector for process/system metrics (CPU, memory, load avg)
- Add Event Buffer metrics (size, capacity, utilization, flushes, overflows)
- Add Adaptive Flush metrics (interval, adjustments, throughput, backpressure)
- Add Circuit Breaker metrics (state, trips, recoveries, rejections)
- Add Query metrics (latency, count, timeouts)
- Add Presence and Group metrics
- Add History Sync metrics
- Add helper functions (trackDuration, trackDurationAsync, trackOperation)
- Add Express middleware support
- Add global metrics manager with initialize/shutdown lifecycle
- Total metrics increased from 18 to 50+
2026-01-20 03:14:44 +00:00
Renato Alcara bc6d97400b feat(socket): integrate circuit breaker with Socket operations
This PR integrates the circuit breaker pattern with Socket operations for improved resilience.

### Changes

- **SocketConfig** - Added circuit breaker configuration options:
  - `enableCircuitBreaker` - Enable/disable circuit breaker (default: true)
  - `queryCircuitBreaker` - Config for query operations
  - `connectionCircuitBreaker` - Config for connection operations
  - `preKeyCircuitBreaker` - Config for pre-key operations

- **Socket Integration** - Circuit breakers protect:
  - `query()` - All WhatsApp queries (most critical)
  - `sendRawMessage()` - Low-level WebSocket sends
  - `uploadPreKeys()` - Pre-key upload operations

- **New Socket Methods**:
  - `circuitBreakers` - Access to circuit breaker instances
  - `getCircuitBreakerStats()` - Get statistics for all breakers
  - `resetCircuitBreakers()` - Reset all breakers to closed state

### Circuit Breaker Features

- Sliding window failure tracking
- Automatic state transitions (closed → open → half-open)
- Configurable thresholds and timeouts
- Prometheus metrics integration
- Event callbacks for monitoring
- Automatic cleanup on connection close
2026-01-19 23:41:45 -03:00
Claude 5714e8e940 merge: resolve conflicts with master 2026-01-20 02:38:37 +00:00
Claude f1bee96e68 chore: update lock files 2026-01-20 02:32:15 +00:00
Claude 61f5f76ef0 feat(socket): integrate circuit breaker with Socket operations
- Add circuit breaker configuration options to SocketConfig type
- Initialize circuit breakers for query, connection, and pre-key operations
- Wrap query() with circuit breaker protection for all WhatsApp queries
- Wrap sendRawMessage() with connection circuit breaker
- Integrate pre-key circuit breaker with uploadPreKeys()
- Add circuit breaker utilities to socket return object (stats, reset)
- Clean up circuit breakers on connection close
- Fix TypeScript errors in utility files (prometheus-metrics, logger-adapter, etc.)

Circuit breakers provide:
- Sliding window failure tracking
- Automatic state transitions (closed -> open -> half-open)
- Configurable thresholds and timeouts
- Prometheus metrics integration
- Event callbacks for monitoring
2026-01-20 02:31:23 +00:00