queen-mq 0.2.23 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +162 -136
  2. package/client-js/client-v2/LOGGING.md +240 -0
  3. package/client-js/client-v2/Queen.js +389 -0
  4. package/client-js/client-v2/README.md +1883 -0
  5. package/client-js/client-v2/buffer/BufferManager.js +215 -0
  6. package/client-js/client-v2/buffer/MessageBuffer.js +132 -0
  7. package/client-js/client-v2/builders/QueueBuilder.js +724 -0
  8. package/client-js/client-v2/builders/TransactionBuilder.js +110 -0
  9. package/client-js/client-v2/consumer/ConsumerManager.js +390 -0
  10. package/client-js/client-v2/http/HttpClient.js +215 -0
  11. package/client-js/client-v2/http/LoadBalancer.js +50 -0
  12. package/client-js/client-v2/index.js +7 -0
  13. package/client-js/client-v2/utils/defaults.js +54 -0
  14. package/client-js/client-v2/utils/logger.js +54 -0
  15. package/client-js/client-v2/utils/validation.js +31 -0
  16. package/client-js/test-v2/AI_TEST_SUMMARY.md +226 -0
  17. package/client-js/test-v2/GETTING_STARTED.md +154 -0
  18. package/client-js/test-v2/ai_buffering.js +194 -0
  19. package/client-js/test-v2/ai_error_handling.js +223 -0
  20. package/client-js/test-v2/ai_lease_renewal.js +206 -0
  21. package/client-js/test-v2/ai_mixed_scenarios.js +278 -0
  22. package/client-js/test-v2/ai_priority.js +169 -0
  23. package/client-js/test-v2/ai_resources.js +217 -0
  24. package/client-js/test-v2/ai_ttl_retention.js +170 -0
  25. package/client-js/test-v2/complete.js +59 -0
  26. package/client-js/test-v2/consume.js +655 -0
  27. package/client-js/test-v2/dlq.js +82 -0
  28. package/client-js/test-v2/load.js +177 -0
  29. package/client-js/test-v2/pop.js +114 -0
  30. package/client-js/test-v2/push.js +333 -0
  31. package/client-js/test-v2/queue.js +39 -0
  32. package/client-js/test-v2/run.js +187 -0
  33. package/client-js/test-v2/subscription.js +354 -0
  34. package/client-js/test-v2/transaction.js +443 -0
  35. package/package.json +2 -2
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE.md)
8
8
  [![Node](https://img.shields.io/badge/node-%3E%3D22.0.0-brightgreen.svg)](https://nodejs.org/)
9
9
 
10
- [Quick Start](#js-client-usage) • [Examples](#-examples) • [Webapp](#webapp) • [Server Setup](#install-server-and-configure-it) • [HTTP API](#raw-http-api)
10
+ [Quick Start](#js-client-usage-v2) • [Complete V2 Guide](client-js/client-v2/README.md) • [Examples](#-examples) • [Webapp](#webapp) • [Server Setup](#install-server-and-configure-it) • [HTTP API](#raw-http-api)
11
11
 
12
12
  <p align="center">
13
13
  <img src="assets/queen-logo-rose.svg" alt="Queen Logo" width="120" />
@@ -17,163 +17,173 @@
17
17
 
18
18
  ---
19
19
 
20
- ## Introduction
21
-
22
- QueenMQ is a queue system written in C++ and backed by Postgres. Supports queues and consumer groups.
23
-
24
- ## JS Client usage
25
-
26
- ```js
27
- import { Queen } from 'queen-mq'
28
-
29
- const client = new Queen({
30
- baseUrls: ['http://localhost:6632'],
31
- timeout: 30000,
32
- retryAttempts: 3
33
- });
34
-
35
- const queue = 'html-processing'
36
-
37
- // Create a queue
38
- await client.queue(queue, { leaseTime: 30 });
20
+ Why "Queen"? Because years ago, when I first read the word "queue" in my mind, I read it as "queen".
39
21
 
40
- // Push some data, specifyng the partition
41
- await client.push(`${queue}/customer-1828`, [ { id: 1 } ]);
42
-
43
- // Consume data with iterators
44
- for await (const msg of client.take(queue, { limit: 1 })) {
45
- console.log(msg.data.id)
46
- await client.ack(msg) // OR await client.ack(msg, false) for nack
47
- }
48
-
49
- // Consume data with iterators, getting the entire batch
50
- for await (const messages of client.takeBatch(queue, { limit: 1, batch: 10, wait: true, timeout: 2000 })) {
51
- const newMex = messages.map(x => x.data.id * 2)
52
- await client.ack(messages) // OR await client.ack(messages, false) for nack
53
- }
54
-
55
- // Consume data with a consumer group
56
- for await (const msg of client.take(`${queue}@analytics-data`, { limit: 2, batch: 2 })) {
57
- // Do your computation and than ack with consumer group
58
- await client.ack(msg, true, { group: 'analytics-data' });
59
- }
60
-
61
- // Consume data from any partition of the queue, continusly
62
- // This "pipeline" is useful for doing exactly one processing
63
- await client
64
- .pipeline(queue)
65
- .withAutoRenewal({
66
- interval: 5000 // Renew lease every 5 seconds
67
- })
68
- .withConcurrency(5) // Five parallel promises
69
- .take(10, {
70
- wait: true, // Use long polling
71
- timeout: 30000 // Long polling length in millisconds
72
- })
73
- .processBatch(async (messages) => {
74
- return messages.map(x => x.data.id * 2);
75
- })
76
- .atomically((tx, originalMessages, processedMessages) => { // ack and push are transactional inside atomically
77
- tx.ack(originalMessages);
78
- tx.push('another-queue', processedMessages);
79
- })
80
- .repeat({ continuous: true })
81
- .execute();
82
- ```
83
-
84
- ## 📚 Examples
22
+ ---
85
23
 
86
- ### Basic Usage
87
- - **[Basic Queue Operations](examples/01-basic-usage.js)** - Create queue, push, take, and ack messages
88
- - **[Batch Operations](examples/02-batch-operations.js)** - Push and consume messages in batches
24
+ ## Introduction
89
25
 
90
- ### Advanced Features
91
- - **[Queue Configuration](examples/06-queue-configuration.js)** - Configure maxSize, windowBuffer, delay, retryLimit, and priority
92
- - **[Delayed Processing](examples/04-delayed-processing.js)** - Process messages after a delay
93
- - **[Window Buffer](examples/05-window-buffer.js)** - Delay message availability after push
26
+ QueenMQ is a queue system written in C++ and backed by PostgreSQL, born from the need to manage many FIFO partitions for Smartchat with solid guarantees around delivery and failure handling. During the initial development, I realized that with a few simple additions to the original design, I could build a very powerful and flexible queue system. This project is almost entirely written by AI, with my supervision—only the test files (or a good part of them) are manually written.
94
27
 
95
- ### Filtering & Routing
96
- - **[Namespace & Task Filtering](examples/07-namespace-task-filtering.js)** - Route and filter messages by namespace and task
97
- - **[Consumer Groups](examples/08-consumer-groups.js)** - Multiple consumer groups processing same messages
28
+ Here are the main features:
29
+ - Unlimited FIFO partitions within queues
30
+ - Queue semantics like RabbitMQ
31
+ - Consumer groups over queues like Kafka
32
+ - QoS levels: Exactly-once delivery (with transactionId), at-least-once delivery, and at-most-once delivery
33
+ - Subscription modes for replay (new messages only or from a specific timestamp) and message history control
34
+ - Transactions between operations (push and ack mainly) for atomicity
35
+ - Dead letter queue for failure handling
36
+ - Lease renewal for long-running tasks
37
+ - Message tracing for debugging workflows
38
+ - Encryption of messages at DB level
98
39
 
99
- ### Pipelines
100
- - **[Transactional Pipelines](examples/03-transactional-pipeline.js)** - Atomic processing with ack and push in a transaction
40
+ The system consists of a PostgreSQL database, a replicated server that can be scaled horizontally (though it won't be the bottleneck), and a client library for interacting with the server. All client-server communication happens over HTTP, and the client library is written in JavaScript (support for other languages is planned). There's also a modern Vue 3 web app for monitoring and managing the system.
101
41
 
102
- ### Event Streaming (QoS 0)
103
- - **[Event Streaming](examples/09-event-streaming.js)** - At-most-once delivery with buffering and auto-ack
42
+ With proper batching, the system can handle +100k **messages** per second (not req/s) on modest hardware.
104
43
 
105
- ## QoS 0: At-Most-Once Event Streaming
44
+ Main documentation:
45
+ - [Client Guide](client-js/client-v2/README.md)
46
+ - [Server Guide](server/README.md)
47
+ - [API Reference](API.md)
48
+ - [Webapp](webapp/README.md)
106
49
 
107
- For high-throughput event streams, Queen supports **at-most-once delivery** with server-side buffering and auto-acknowledgment.
108
50
 
109
- ### Server-Side Buffering
51
+ ## JS Client Usage
110
52
 
111
- Batch events on the server for 10-100x reduction in database writes:
53
+ > 📖 **[Complete Guide: client-js/client-v2/README.md](client-js/client-v2/README.md)** - Full tutorial with all features!
112
54
 
113
55
  ```javascript
114
- // Push with buffering (QoS 0)
115
- await client.push('metrics', { cpu: 45, memory: 67 }, {
116
- bufferMs: 100, // Server batches for 100ms
117
- bufferMax: 100 // Or until 100 events
118
- });
119
-
120
- // Result: 1000 events = ~10 DB writes (instead of 1000)
121
- ```
56
+ import { Queen } from 'queen-mq'
122
57
 
123
- ### Auto-Acknowledgment
58
+ // Connect to Queen
59
+ const queen = new Queen('http://localhost:6632')
124
60
 
125
- Skip manual ack for fire-and-forget consumption:
61
+ // Create a queue
62
+ await queen.queue('tasks').create()
63
+
64
+ // Push messages
65
+ await queen.queue('tasks').push([
66
+ { data: { job: 'send-email', to: 'alice@example.com' } },
67
+ { data: { job: 'process-image', id: 123 } }
68
+ ])
69
+
70
+ // Consume messages (auto-ack on success, auto-nack on error)
71
+ await queen.queue('tasks').consume(async (message) => {
72
+ console.log('Processing:', message.data)
73
+ // If this succeeds → message completed ✅
74
+ // If this throws → message retried 🔄
75
+ })
126
76
 
127
- ```javascript
128
- // Consume with auto-ack
129
- for await (const msg of client.take('metrics', { autoAck: true })) {
130
- updateDashboard(msg.data);
131
- // No ack() needed - automatically acknowledged!
77
+ // Pop messages manually
78
+ const messages = await queen.queue('tasks').batch(10).pop()
79
+ for (const msg of messages) {
80
+ try {
81
+ await processMessage(msg.data)
82
+ await queen.ack(msg, true) // Success
83
+ } catch (error) {
84
+ await queen.ack(msg, false) // Retry
85
+ }
132
86
  }
133
- ```
134
-
135
- ### Fan-Out Pattern (Consumer Groups)
136
-
137
- Combine buffering + auto-ack + consumer groups for pub/sub:
138
-
139
- ```javascript
140
- // Publisher (buffered)
141
- await client.push('events', { action: 'login' }, { bufferMs: 100 });
142
87
 
143
- // Multiple subscribers (each group gets all messages)
144
- for await (const e of client.take('events@dashboard', { autoAck: true })) {
145
- updateUI(e.data);
146
- }
88
+ // Partitions (for ordering)
89
+ await queen
90
+ .queue('user-events')
91
+ .partition('user-123')
92
+ .push([{ data: { event: 'login' } }])
93
+
94
+ // Consumer groups (for scaling)
95
+ await queen
96
+ .queue('emails')
97
+ .group('processors')
98
+ .concurrency(5)
99
+ .consume(async (message) => {
100
+ await sendEmail(message.data)
101
+ })
102
+
103
+ // Subscription modes (control message history)
104
+ // Skip historical messages, only process new ones
105
+ await queen
106
+ .queue('events')
107
+ .group('realtime-monitor')
108
+ .subscriptionMode('new')
109
+ .consume(async (message) => {
110
+ console.log('New event only:', message.data)
111
+ })
112
+
113
+ // Start from a specific timestamp
114
+ const timestamp = '2025-10-28T10:00:00.000Z'
115
+ await queen
116
+ .queue('events')
117
+ .group('replay-from-timestamp')
118
+ .subscriptionFrom(timestamp)
119
+ .consume(async (message) => {
120
+ console.log('Replaying from 10am:', message.data)
121
+ })
122
+
123
+ // Transactions (atomic ack + push)
124
+ const [msg] = await queen.queue('input').pop()
125
+ await queen
126
+ .transaction()
127
+ .ack(msg)
128
+ .queue('output')
129
+ .push([{ data: { processed: true } }])
130
+ .commit()
131
+
132
+ // Client-side buffering (for high throughput)
133
+ await queen
134
+ .queue('logs')
135
+ .buffer({ messageCount: 100, timeMillis: 1000 })
136
+ .push([{ data: { level: 'info', message: 'Server started' } }])
137
+
138
+ // Message tracing (for debugging and monitoring)
139
+ await queen.queue('orders').consume(async (msg) => {
140
+ await msg.trace({
141
+ traceName: ['tenant-acme', 'order-flow-123'],
142
+ data: { text: 'Processing started', orderId: msg.data.id }
143
+ })
144
+
145
+ // Process order...
146
+
147
+ await msg.trace({
148
+ traceName: ['tenant-acme', 'order-flow-123'],
149
+ data: { text: 'Order completed' }
150
+ })
151
+ })
147
152
 
148
- for await (const e of client.take('events@analytics', { autoAck: true })) {
149
- trackEvent(e.data);
150
- }
153
+ // Graceful shutdown
154
+ await queen.close()
151
155
  ```
152
156
 
153
- ### PostgreSQL Failover
157
+ **Key Features:**
158
+ - ✅ Fluent, chainable API
159
+ - ✅ Auto-acknowledgment (or manual control)
160
+ - ✅ Partitions for ordered processing
161
+ - ✅ Consumer groups for scaling
162
+ - ✅ **Subscription modes (new messages only or from timestamp)**
163
+ - ✅ Transactions for atomicity
164
+ - ✅ Client-side buffering for speed
165
+ - ✅ Dead letter queue for failures
166
+ - ✅ Lease renewal for long tasks
167
+ - ✅ **Message tracing for debugging workflows**
168
+ - ✅ Graceful shutdown with buffer flush
154
169
 
155
- Queen automatically buffers messages to disk when PostgreSQL is unavailable - **zero message loss**:
156
-
157
- - Normal pushes go directly to PostgreSQL (FIFO preserved)
158
- - If PostgreSQL is down, messages buffered to file (macOS: `/tmp/queen`, Linux: `/var/lib/queen/buffers`)
159
- - Automatic replay when PostgreSQL recovers
160
- - Survives server crashes and restarts
161
- - Directory auto-created on first run
170
+ ## 📚 Examples
162
171
 
163
- **No configuration needed** - failover is automatic!
172
+ ### Client
164
173
 
165
- **Custom directory:**
166
- ```bash
167
- FILE_BUFFER_DIR=/custom/path ./bin/queen-server
168
- ```
174
+ See the **[Complete V2 Guide](client-js/client-v2/README.md)** with 14 parts covering everything from basics to advanced features:
175
+ - Queue creation, push, and consume
176
+ - Partitions and consumer groups
177
+ - **Subscription modes (new messages, timestamps)**
178
+ - Transactions and buffering
179
+ - Dead letter queues
180
+ - Lease renewal
181
+ - Message tracing
182
+ - Complete real-world pipeline example
183
+ - And much more!
169
184
 
170
- ### When to Use
185
+ **Test Files** (94 working examples): [client-js/test-v2/](client-js/test-v2/)
171
186
 
172
- | Feature | Use For | Don't Use For |
173
- |---------|---------|---------------|
174
- | **Buffering** | Metrics, logs, analytics, UI updates | Critical tasks, payments |
175
- | **Auto-Ack** | Fire-and-forget events, notifications | Tasks requiring retry logic |
176
- | **Failover** | Everything (automatic) | N/A - always beneficial |
177
187
 
178
188
  ## Architecture
179
189
 
@@ -206,6 +216,23 @@ Queen uses a high-performance **acceptor/worker pattern** with uWebSockets, comb
206
216
 
207
217
  This architecture provides high concurrency, efficient connection pooling, and minimal latency for both immediate and long-polling requests.
208
218
 
219
+ ### PostgreSQL Failover
220
+
221
+ Queen automatically buffers messages to disk when PostgreSQL is unavailable - **zero message loss**:
222
+
223
+ - Normal pushes go directly to PostgreSQL (FIFO preserved)
224
+ - If PostgreSQL is down, messages buffered to file (macOS: `/tmp/queen`, Linux: `/var/lib/queen/buffers`)
225
+ - Automatic replay when PostgreSQL recovers
226
+ - Survives server crashes and restarts
227
+ - Directory auto-created on first run
228
+
229
+ **No configuration needed** - failover is automatic!
230
+
231
+ **Custom directory:**
232
+ ```bash
233
+ FILE_BUFFER_DIR=/custom/path ./bin/queen-server
234
+ ```
235
+
209
236
  ## Webapp
210
237
 
211
238
  A modern Vue 3 web interface for managing and monitoring Queen MQ.
@@ -215,7 +242,8 @@ A modern Vue 3 web interface for managing and monitoring Queen MQ.
215
242
  - 📈 Message throughput visualization
216
243
  - 🔍 Queue management and monitoring
217
244
  - 👥 Consumer group tracking
218
- - 💬 Message browser
245
+ - 💬 Message browser with trace timeline
246
+ - 🔎 **Trace explorer for debugging distributed workflows**
219
247
  - 📉 Analytics and insights
220
248
  - 🌓 Dark/light theme support
221
249
 
@@ -285,7 +313,5 @@ You can use Queen directly from HTTP without the JS client.
285
313
 
286
314
  ### Other TODO Items
287
315
  - retention jobs
288
- - reconsume
289
- - new client
290
316
  - auth
291
317
  - streaming engine
@@ -0,0 +1,240 @@
1
+ # Queen Client V2 - Logging Documentation
2
+
3
+ ## Overview
4
+
5
+ The Queen Client V2 includes comprehensive operation logging that captures every significant action performed by the client. Logging is **disabled by default** and can be enabled via the `QUEEN_CLIENT_LOG` environment variable.
6
+
7
+ ## Enabling Logging
8
+
9
+ ```bash
10
+ export QUEEN_CLIENT_LOG=true
11
+ node your-app.js
12
+ ```
13
+
14
+ Or inline:
15
+ ```bash
16
+ QUEEN_CLIENT_LOG=true node your-app.js
17
+ ```
18
+
19
+ ## Log Format
20
+
21
+ All logs follow this format:
22
+ ```
23
+ [TIMESTAMP] [LEVEL] [OPERATION] DETAILS
24
+ ```
25
+
26
+ - **TIMESTAMP**: ISO 8601 format (e.g., `2025-10-28T10:30:45.123Z`)
27
+ - **LEVEL**: `INFO`, `WARN`, or `ERROR`
28
+ - **OPERATION**: Component and method (e.g., `Queen.push`, `HttpClient.request`)
29
+ - **DETAILS**: JSON object with relevant context
30
+
31
+ ### Example Log Output
32
+
33
+ ```
34
+ [2025-10-28T10:30:45.123Z] [INFO] [Queen.constructor] {"status":"initialized","urls":1}
35
+ [2025-10-28T10:30:45.234Z] [INFO] [QueueBuilder.push] {"queue":"tasks","partition":"Default","count":5,"buffered":true}
36
+ [2025-10-28T10:30:45.456Z] [INFO] [BufferManager.addMessage] {"queueAddress":"tasks/Default","messageCount":5}
37
+ [2025-10-28T10:30:46.789Z] [INFO] [HttpClient.request] {"method":"POST","url":"http://localhost:6632/api/v1/push","hasBody":true,"timeout":30000}
38
+ [2025-10-28T10:30:46.890Z] [INFO] [HttpClient.response] {"method":"POST","url":"http://localhost:6632/api/v1/push","status":200}
39
+ [2025-10-28T10:30:47.123Z] [INFO] [BufferManager.flushBuffer] {"queueAddress":"tasks/Default","status":"success","messagesSent":5}
40
+ ```
41
+
42
+ ## Logged Operations
43
+
44
+ ### Queen (Main Client)
45
+
46
+ | Operation | Logged Details |
47
+ |-----------|---------------|
48
+ | `Queen.constructor` | Configuration summary, URL count |
49
+ | `Queen.ack` | Batch/single, message count, status, context |
50
+ | `Queen.renew` | Lease ID count, success/failure per lease |
51
+ | `Queen.flushAllBuffers` | Start and completion status |
52
+ | `Queen.getBufferStats` | Buffer statistics |
53
+ | `Queen.close` | Shutdown phases, errors |
54
+
55
+ ### QueueBuilder (Queue Operations)
56
+
57
+ | Operation | Logged Details |
58
+ |-----------|---------------|
59
+ | `QueueBuilder.create` | Queue name, namespace, task |
60
+ | `QueueBuilder.delete` | Queue name |
61
+ | `QueueBuilder.push` | Queue, partition, count, buffered flag |
62
+ | `QueueBuilder.pop` | Queue, partition, batch size, wait mode, result count |
63
+ | `QueueBuilder.flushBuffer` | Queue address |
64
+ | `QueueBuilder.dlq` | Queue, consumer group, partition |
65
+
66
+ ### HttpClient (Network Operations)
67
+
68
+ | Operation | Logged Details |
69
+ |-----------|---------------|
70
+ | `HttpClient.constructor` | Configuration (timeout, retries, failover) |
71
+ | `HttpClient.request` | Method, URL, body presence, timeout |
72
+ | `HttpClient.response` | Method, URL, HTTP status |
73
+ | `HttpClient.retry` | Attempt number, delay, error message |
74
+ | `HttpClient.failover` | Server count, attempted URLs, failures |
75
+
76
+ ### BufferManager (Client-Side Buffering)
77
+
78
+ | Operation | Logged Details |
79
+ |-----------|---------------|
80
+ | `BufferManager.createBuffer` | Queue address, buffer options |
81
+ | `BufferManager.addMessage` | Queue address, current message count |
82
+ | `BufferManager.flushBuffer` | Queue address, message count, status |
83
+ | `BufferManager.flushAllBuffers` | Buffer count, pending flushes |
84
+ | `BufferManager.getStats` | Active buffers, total messages, oldest age |
85
+ | `BufferManager.cleanup` | Buffer count being cleaned |
86
+
87
+ ### ConsumerManager (Message Consumption)
88
+
89
+ | Operation | Logged Details |
90
+ |-----------|---------------|
91
+ | `ConsumerManager.start` | Queue, concurrency, batch size, auto-ack |
92
+ | `ConsumerManager.worker` | Worker ID, lifecycle events, processed count |
93
+ | `ConsumerManager.processMessage` | Transaction ID, ack/nack status, errors |
94
+ | `ConsumerManager.processBatch` | Message count, ack/nack status, errors |
95
+
96
+ ### TransactionBuilder (Atomic Operations)
97
+
98
+ | Operation | Logged Details |
99
+ |-----------|---------------|
100
+ | `TransactionBuilder.ack` | Message count, status |
101
+ | `TransactionBuilder.queue.push` | Queue name, item count |
102
+ | `TransactionBuilder.commit` | Operation count, required leases, success/failure |
103
+
104
+ ### Other Builders
105
+
106
+ | Operation | Logged Details |
107
+ |-----------|---------------|
108
+ | `OperationBuilder.execute` | Method, path, success/failure |
109
+ | `PushBuilder.execute` | Queue, partition, count, buffered flag, results |
110
+ | `DLQBuilder.get` | Queue, consumer group, limit, offset, results |
111
+
112
+ ## Use Cases
113
+
114
+ ### 1. Debugging
115
+
116
+ Use logging to trace through client operations and identify where issues occur:
117
+
118
+ ```bash
119
+ QUEEN_CLIENT_LOG=true node my-app.js 2>&1 | grep ERROR
120
+ ```
121
+
122
+ ### 2. Performance Analysis
123
+
124
+ Monitor HTTP request/response times and buffer flush patterns:
125
+
126
+ ```bash
127
+ QUEEN_CLIENT_LOG=true node my-app.js 2>&1 | grep HttpClient
128
+ ```
129
+
130
+ ### 3. Audit Trail
131
+
132
+ Create an audit log of all queue operations:
133
+
134
+ ```bash
135
+ QUEEN_CLIENT_LOG=true node my-app.js 2>&1 | tee audit.log
136
+ ```
137
+
138
+ ### 4. Development
139
+
140
+ Enable logging during development to understand client behavior:
141
+
142
+ ```javascript
143
+ // In .env file
144
+ QUEEN_CLIENT_LOG=true
145
+ ```
146
+
147
+ ### 5. Production Troubleshooting
148
+
149
+ Temporarily enable logging in production to diagnose issues:
150
+
151
+ ```bash
152
+ # Enable for one process
153
+ QUEEN_CLIENT_LOG=true pm2 restart my-app --update-env
154
+
155
+ # Disable after troubleshooting
156
+ pm2 restart my-app
157
+ ```
158
+
159
+ ## Performance Impact
160
+
161
+ - **Disabled (default)**: Zero performance impact - all logging calls are no-ops
162
+ - **Enabled**: Minimal impact - logging is asynchronous and uses `console.log/warn/error`
163
+
164
+ ## Log Levels
165
+
166
+ - **INFO**: Normal operations (most logs)
167
+ - **WARN**: Recoverable issues (retries, failover, network errors)
168
+ - **ERROR**: Operation failures (push failed, ack failed, etc.)
169
+
170
+ ## Filtering Logs
171
+
172
+ ### By Component
173
+ ```bash
174
+ QUEEN_CLIENT_LOG=true node app.js 2>&1 | grep "HttpClient"
175
+ QUEEN_CLIENT_LOG=true node app.js 2>&1 | grep "BufferManager"
176
+ QUEEN_CLIENT_LOG=true node app.js 2>&1 | grep "ConsumerManager"
177
+ ```
178
+
179
+ ### By Level
180
+ ```bash
181
+ QUEEN_CLIENT_LOG=true node app.js 2>&1 | grep "ERROR"
182
+ QUEEN_CLIENT_LOG=true node app.js 2>&1 | grep "WARN"
183
+ ```
184
+
185
+ ### By Operation
186
+ ```bash
187
+ QUEEN_CLIENT_LOG=true node app.js 2>&1 | grep "push"
188
+ QUEEN_CLIENT_LOG=true node app.js 2>&1 | grep "ack"
189
+ QUEEN_CLIENT_LOG=true node app.js 2>&1 | grep "pop"
190
+ ```
191
+
192
+ ## Integration with Log Aggregation
193
+
194
+ The structured JSON format makes it easy to integrate with log aggregation tools:
195
+
196
+ ### Winston
197
+ ```javascript
198
+ import winston from 'winston'
199
+
200
+ // Redirect console.log to Winston
201
+ console.log = winston.info
202
+ console.error = winston.error
203
+ console.warn = winston.warn
204
+ ```
205
+
206
+ ### Pino
207
+ ```javascript
208
+ import pino from 'pino'
209
+ const logger = pino()
210
+
211
+ console.log = (msg) => logger.info(msg)
212
+ console.error = (msg) => logger.error(msg)
213
+ console.warn = (msg) => logger.warn(msg)
214
+ ```
215
+
216
+ ### Datadog, CloudWatch, etc.
217
+
218
+ The ISO 8601 timestamps and JSON format are compatible with most log aggregation services.
219
+
220
+ ## Best Practices
221
+
222
+ 1. **Disable in Production**: Only enable when needed for troubleshooting
223
+ 2. **Use Log Rotation**: If keeping logs enabled, use log rotation to manage disk space
224
+ 3. **Filter Sensitive Data**: Payloads are NOT logged - only metadata
225
+ 4. **Monitor Log Volume**: High-throughput applications generate many logs when enabled
226
+ 5. **Use Structured Search**: Leverage JSON format for precise filtering
227
+
228
+ ## Implementation Details
229
+
230
+ The logging system is implemented in `utils/logger.js` and imported by all major components:
231
+
232
+ - `Queen.js` - Main client operations
233
+ - `HttpClient.js` - Network layer
234
+ - `BufferManager.js` - Client-side buffering
235
+ - `ConsumerManager.js` - Message consumption
236
+ - `QueueBuilder.js` - Queue operations
237
+ - `TransactionBuilder.js` - Atomic transactions
238
+
239
+ All logging calls check the `QUEEN_CLIENT_LOG` environment variable and are no-ops when disabled, ensuring zero performance impact by default.
240
+