zario 0.3.1 → 0.3.6

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 (46) hide show
  1. package/README.md +164 -4
  2. package/dist/cjs/aggregation/LogAggregator.js +131 -0
  3. package/dist/cjs/aggregation/index.js +17 -0
  4. package/dist/cjs/core/Formatter.js +3 -4
  5. package/dist/cjs/core/Logger.js +100 -4
  6. package/dist/cjs/filters/Filter.js +90 -0
  7. package/dist/cjs/filters/index.js +17 -0
  8. package/dist/cjs/index.js +20 -1
  9. package/dist/cjs/structured/StructuredExtensions.js +112 -0
  10. package/dist/cjs/structured/index.js +17 -0
  11. package/dist/cjs/transports/FilterableTransport.js +39 -0
  12. package/dist/cjs/transports/index.js +1 -0
  13. package/dist/cjs/utils/index.js +78 -0
  14. package/dist/esm/aggregation/LogAggregator.d.ts +37 -0
  15. package/dist/esm/aggregation/LogAggregator.js +125 -0
  16. package/dist/esm/aggregation/index.d.ts +1 -0
  17. package/dist/esm/aggregation/index.js +1 -0
  18. package/dist/esm/core/Formatter.js +1 -2
  19. package/dist/esm/core/Logger.d.ts +35 -1
  20. package/dist/esm/core/Logger.js +99 -3
  21. package/dist/esm/filters/Filter.d.ts +49 -0
  22. package/dist/esm/filters/Filter.js +79 -0
  23. package/dist/esm/filters/index.d.ts +1 -0
  24. package/dist/esm/filters/index.js +1 -0
  25. package/dist/esm/index.d.ts +7 -3
  26. package/dist/esm/index.js +14 -2
  27. package/dist/esm/structured/StructuredExtensions.d.ts +31 -0
  28. package/dist/esm/structured/StructuredExtensions.js +74 -0
  29. package/dist/esm/structured/index.d.ts +1 -0
  30. package/dist/esm/structured/index.js +1 -0
  31. package/dist/esm/transports/FilterableTransport.d.ts +14 -0
  32. package/dist/esm/transports/FilterableTransport.js +35 -0
  33. package/dist/esm/transports/index.d.ts +1 -0
  34. package/dist/esm/transports/index.js +1 -0
  35. package/dist/esm/utils/index.d.ts +15 -0
  36. package/dist/esm/utils/index.js +72 -0
  37. package/package.json +11 -6
  38. package/dist/cjs/utils/ColorUtil.js +0 -42
  39. package/dist/cjs/utils/TimeUtil.js +0 -26
  40. package/dist/cjs/utils/Timerutil.js +0 -22
  41. package/dist/esm/utils/ColorUtil.d.ts +0 -4
  42. package/dist/esm/utils/ColorUtil.js +0 -38
  43. package/dist/esm/utils/TimeUtil.d.ts +0 -3
  44. package/dist/esm/utils/TimeUtil.js +0 -22
  45. package/dist/esm/utils/Timerutil.d.ts +0 -8
  46. package/dist/esm/utils/Timerutil.js +0 -18
package/README.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  A minimal, fast logging library for Node.js with TypeScript support.
4
4
 
5
+ ## What's New in 0.3.5
6
+
7
+ - Added advanced filtering capabilities with LevelFilter, PrefixFilter, MetadataFilter, CompositeFilter, OrFilter, and PredicateFilter
8
+ - Added structured logging extensions with LogEnrichmentPipeline and MetadataEnricher
9
+ - Added TimeBasedAggregator.stop() method for proper timer cleanup
10
+ - Improved error handling for aggregators and filters with try-catch protection
11
+ - Enhanced thread safety with defensive copying of filters during iteration
12
+ - Fixed enricher inheritance in child loggers
13
+ - Added documentation for empty array behavior in CompositeFilter (allows all) and OrFilter (blocks all)
14
+ - Added note about strict equality in MetadataFilter for complex objects
15
+
5
16
  ## What's New in 0.2.11
6
17
 
7
18
  - Added HTTP transport support with new HttpTransport class
@@ -46,6 +57,9 @@ logger.error("❌ Database connection failed", { code: 500 });
46
57
  | **transports** | `array` | Where logs are written (with transport-specific options like `path`, `maxSize`, `maxFiles`, `compression`, `batchInterval`, `compressOldFiles` for file transport) |
47
58
  | **customLevels** | `object` | Define custom log levels and their priorities |
48
59
  | **customColors** | `object` | Assign colors to custom log levels |
60
+ | **filters** | `Filter[]` | Array of filters to apply before logging (LevelFilter, PrefixFilter, MetadataFilter, CompositeFilter, OrFilter, PredicateFilter) |
61
+ | **aggregators** | `LogAggregator[]` | Array of log aggregators (BatchAggregator, TimeBasedAggregator, CompositeAggregator) |
62
+ | **enrichers** | `LogEnrichmentPipeline` | Pipeline for structured logging extensions |
49
63
 
50
64
  ### Log Levels
51
65
 
@@ -112,16 +126,162 @@ const logger = new Logger({
112
126
  });
113
127
  ```
114
128
 
129
+ ### Advanced Filtering
130
+
131
+ Filter logs based on various criteria using built-in filter classes:
132
+
133
+ ```js
134
+ import {
135
+ Logger,
136
+ ConsoleTransport,
137
+ LevelFilter,
138
+ PrefixFilter,
139
+ MetadataFilter,
140
+ CompositeFilter,
141
+ OrFilter,
142
+ PredicateFilter
143
+ } from "zario";
144
+
145
+ // Level filter - only allow specific log levels
146
+ const levelFilter = new LevelFilter(['info', 'error']);
147
+
148
+ // Prefix filter - only allow logs with specific prefixes
149
+ const prefixFilter = new PrefixFilter(['[API]', '[DB]']);
150
+
151
+ // Metadata filter - only allow logs with specific metadata
152
+ const metadataFilter = new MetadataFilter({ userId: 123 });
153
+
154
+ // Composite filter - combines multiple filters with AND logic
155
+ // Note: With an empty array, CompositeFilter allows all logs (vacuous truth)
156
+ const compositeFilter = new CompositeFilter([levelFilter, prefixFilter]);
157
+
158
+ // Or filter - combines multiple filters with OR logic
159
+ // Note: With an empty array, OrFilter blocks all logs (no matching conditions)
160
+ const orFilter = new OrFilter([levelFilter, metadataFilter]);
161
+
162
+ // Predicate filter - custom filtering function
163
+ const predicateFilter = new PredicateFilter((logData) => {
164
+ return logData.level !== 'debug'; // Filter out debug messages
165
+ });
166
+
167
+ // Create logger with filters
168
+ const filteredLogger = new Logger({
169
+ level: 'debug',
170
+ transports: [new ConsoleTransport()],
171
+ filters: [compositeFilter, predicateFilter] // Apply multiple filters
172
+ });
173
+ ```
174
+
175
+ ### Structured Logging Extensions
176
+
177
+ Enhance your logs with additional metadata using structured logging extensions:
178
+
179
+ ```js
180
+ import {
181
+ Logger,
182
+ ConsoleTransport,
183
+ LogEnrichmentPipeline,
184
+ MetadataEnricher
185
+ } from "zario";
186
+
187
+ // Create enrichers to add metadata to logs
188
+ const staticEnricher = MetadataEnricher.addStaticFields({
189
+ service: 'user-service',
190
+ version: '1.0.0'
191
+ });
192
+
193
+ const dynamicEnricher = MetadataEnricher.addDynamicFields(() => ({
194
+ processId: process.pid,
195
+ memoryUsage: process.memoryUsage().heapUsed
196
+ }));
197
+
198
+ const processEnricher = MetadataEnricher.addProcessInfo();
199
+ const envEnricher = MetadataEnricher.addEnvironmentInfo();
200
+
201
+ // Create a pipeline with multiple enrichers
202
+ const enricherPipeline = new LogEnrichmentPipeline([
203
+ staticEnricher,
204
+ dynamicEnricher,
205
+ processEnricher,
206
+ envEnricher
207
+ ]);
208
+
209
+ // Create logger with enrichers
210
+ const enrichedLogger = new Logger({
211
+ level: 'info',
212
+ transports: [new ConsoleTransport()],
213
+ enrichers: enricherPipeline
214
+ });
215
+
216
+ enrichedLogger.info('User login', { userId: 123 });
217
+ // Output will include additional metadata fields
218
+
219
+ // Add enrichers dynamically
220
+ enrichedLogger.addEnricher((logData) => {
221
+ return {
222
+ ...logData,
223
+ timestamp: new Date().toISOString(),
224
+ additionalField: 'some-value'
225
+ };
226
+ });
227
+ ```
228
+
229
+ ### Log Aggregation
230
+
231
+ Aggregate logs in batches or based on time intervals:
232
+
233
+ ```js
234
+ import {
235
+ Logger,
236
+ ConsoleTransport,
237
+ BatchAggregator,
238
+ TimeBasedAggregator,
239
+ CompositeAggregator
240
+ } from "zario";
241
+
242
+ // Batch aggregator - flushes when batch size is reached
243
+ const batchAggregator = new BatchAggregator(10, (logs) => {
244
+ // Process batch of 10 logs
245
+ console.log(`Processing ${logs.length} logs`);
246
+ });
247
+
248
+ // Time-based aggregator - flushes after time interval
249
+ const timeAggregator = new TimeBasedAggregator(5000, (logs) => {
250
+ // Process logs every 5 seconds
251
+ console.log(`Processing ${logs.length} logs`);
252
+ });
253
+
254
+ // Create logger with aggregators
255
+ const aggregatedLogger = new Logger({
256
+ level: 'info',
257
+ transports: [new ConsoleTransport()],
258
+ aggregators: [batchAggregator]
259
+ });
260
+
261
+ // Manually flush aggregators
262
+ aggregatedLogger.flushAggregators();
263
+
264
+ // Stop time-based aggregator timer
265
+ // timeAggregator.stop(); // Available for TimeBasedAggregator
266
+ ```
267
+
115
268
  ### Methods
116
269
 
117
- - `logger.debug(message, metadata?)` - Debug level logging
118
- - `logger.info(message, metadata?)` - Info level logging
119
- - `logger.warn(message, metadata?)` - Warning level logging
120
- - `logger.error(message, metadata?)` - Error level logging
270
+ - `logger.debug(message, metadata?)` - Debug-level logging
271
+ - `logger.info(message, metadata?)` - Info-level logging
272
+ - `logger.warn(message, metadata?)` - Warning-level logging
273
+ - `logger.error(message, metadata?)` - Error-level logging
121
274
  - `logger.logWithLevel(level, message, metadata?)` - Log a message at an arbitrary/custom level
122
275
  - `logger.createChild(options)` - Creates a child logger with inherited settings
123
276
  - `logger.setLevel(level)` - Change the logger level at runtime
124
277
  - `logger.setFormat(format)` - Set the output format to text or json
278
+ - `logger.addFilter(filter)` - Add a filter to the logger (LevelFilter, PrefixFilter, MetadataFilter, etc.)
279
+ - `logger.removeFilter(filter)` - Remove a filter from the logger
280
+ - `logger.addAggregator(aggregator)` - Add an aggregator to the logger (BatchAggregator, TimeBasedAggregator, etc.)
281
+ - `logger.removeAggregator(aggregator)` - Remove an aggregator from the logger
282
+ - `logger.flushAggregators()` - Manually flush all aggregators
283
+ - `logger.addEnricher(enricher)` - Add an enricher to the logger for structured logging
284
+ - `logger.startTimer(name)` - Create a performance timer
125
285
 
126
286
  ## Usage Examples
127
287
 
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CompositeAggregator = exports.TimeBasedAggregator = exports.BatchAggregator = void 0;
4
+ //Aggregates logs in memory and flushes them in batches
5
+ class BatchAggregator {
6
+ constructor(maxSize = 100, flushCallback) {
7
+ this.logs = [];
8
+ this.pendingFlush = null;
9
+ this.maxSize = maxSize;
10
+ this.flushCallback = flushCallback;
11
+ }
12
+ aggregate(logData, formatter) {
13
+ this.logs.push({ logData, formatter });
14
+ if (this.logs.length >= this.maxSize && !this.pendingFlush) {
15
+ const result = this.flush();
16
+ if (result instanceof Promise) {
17
+ this.pendingFlush = result.finally(() => {
18
+ this.pendingFlush = null;
19
+ });
20
+ }
21
+ }
22
+ }
23
+ flush() {
24
+ if (this.pendingFlush) {
25
+ return this.pendingFlush;
26
+ }
27
+ if (this.logs.length === 0) {
28
+ return;
29
+ }
30
+ const logsToFlush = [...this.logs];
31
+ const originalLogs = [...this.logs];
32
+ this.logs = [];
33
+ try {
34
+ const callbackResult = this.flushCallback(logsToFlush);
35
+ if (callbackResult instanceof Promise) {
36
+ return callbackResult.catch((error) => {
37
+ this.logs = originalLogs;
38
+ throw error;
39
+ });
40
+ }
41
+ }
42
+ catch (error) {
43
+ this.logs = originalLogs;
44
+ throw error;
45
+ }
46
+ }
47
+ }
48
+ exports.BatchAggregator = BatchAggregator;
49
+ //Aggregates logs based on a time interval
50
+ class TimeBasedAggregator {
51
+ constructor(flushInterval, flushCallback) {
52
+ this.logs = [];
53
+ this.timer = null;
54
+ this.flushInterval = flushInterval;
55
+ this.flushCallback = flushCallback;
56
+ }
57
+ aggregate(logData, formatter) {
58
+ this.logs.push({ logData, formatter });
59
+ // Start the timer if it's not already running
60
+ if (!this.timer) {
61
+ this.timer = setTimeout(() => {
62
+ const result = this.flush();
63
+ // Handle the case where flush returns a Promise (async flushCallback)
64
+ if (result instanceof Promise) {
65
+ result.catch((error) => {
66
+ console.error("Error in TimeBasedAggregator flush callback:", error);
67
+ });
68
+ }
69
+ }, this.flushInterval);
70
+ }
71
+ }
72
+ flush() {
73
+ if (this.logs.length > 0) {
74
+ // Clear the timer if it exists
75
+ if (this.timer) {
76
+ clearTimeout(this.timer);
77
+ this.timer = null;
78
+ }
79
+ const logsToFlush = [...this.logs];
80
+ const originalLogs = [...this.logs];
81
+ this.logs = [];
82
+ try {
83
+ const callbackResult = this.flushCallback(logsToFlush);
84
+ if (callbackResult instanceof Promise) {
85
+ return callbackResult.catch((error) => {
86
+ this.logs = originalLogs;
87
+ throw error;
88
+ });
89
+ }
90
+ }
91
+ catch (error) {
92
+ this.logs = originalLogs;
93
+ throw error;
94
+ }
95
+ }
96
+ }
97
+ //Stop the aggregator and cancel any pending timer without flushing
98
+ stop() {
99
+ if (this.timer) {
100
+ clearTimeout(this.timer);
101
+ this.timer = null;
102
+ }
103
+ }
104
+ }
105
+ exports.TimeBasedAggregator = TimeBasedAggregator;
106
+ //Combines multiple aggregators
107
+ class CompositeAggregator {
108
+ constructor(aggregators) {
109
+ this.aggregators = aggregators;
110
+ }
111
+ aggregate(logData, formatter) {
112
+ for (const aggregator of this.aggregators) {
113
+ aggregator.aggregate(logData, formatter);
114
+ }
115
+ }
116
+ flush() {
117
+ const results = [];
118
+ for (const aggregator of this.aggregators) {
119
+ const result = aggregator.flush();
120
+ if (result) {
121
+ results.push(result);
122
+ }
123
+ }
124
+ // If any aggregator returns a promise, wait for all of them
125
+ if (results.some((r) => r instanceof Promise)) {
126
+ const promiseResults = results.filter((r) => r instanceof Promise);
127
+ return Promise.all(promiseResults).then(() => { });
128
+ }
129
+ }
130
+ }
131
+ exports.CompositeAggregator = CompositeAggregator;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./LogAggregator.js"), exports);
@@ -1,8 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Formatter = void 0;
4
- const TimeUtil_js_1 = require("../utils/TimeUtil.js");
5
- const ColorUtil_js_1 = require("../utils/ColorUtil.js");
4
+ const index_js_1 = require("../utils/index.js");
6
5
  class Formatter {
7
6
  constructor(options = {}) {
8
7
  const { colorize = true, json = false, timestampFormat = "YYYY-MM-DD HH:mm:ss", timestamp = false, customColors = {}, } = options;
@@ -37,7 +36,7 @@ class Formatter {
37
36
  formatAsText(data) {
38
37
  let output = "";
39
38
  if (this.timestamp) {
40
- output += `[${TimeUtil_js_1.TimeUtil.format(data.timestamp, this.timestampFormat)}] `;
39
+ output += `[${index_js_1.TimeUtil.format(data.timestamp, this.timestampFormat)}] `;
41
40
  }
42
41
  if (data.prefix) {
43
42
  output += `${data.prefix} `;
@@ -45,7 +44,7 @@ class Formatter {
45
44
  let level = data.level.toUpperCase();
46
45
  if (this.colorize) {
47
46
  const color = this.customColors[data.level] || data.level;
48
- level = ColorUtil_js_1.ColorUtil.colorize(level, color);
47
+ level = index_js_1.ColorUtil.colorize(level, color);
49
48
  }
50
49
  output += `[${level}] ${data.message}`;
51
50
  if (data.metadata) {
@@ -3,14 +3,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Logger = void 0;
4
4
  const Formatter_js_1 = require("./Formatter.js");
5
5
  const ConsoleTransport_js_1 = require("../transports/ConsoleTransport.js");
6
+ const StructuredExtensions_js_1 = require("../structured/StructuredExtensions.js");
7
+ const index_js_1 = require("../utils/index.js");
6
8
  class Logger {
7
9
  constructor(options = {}) {
8
10
  this.transports = [];
9
- const { level, colorize, json, transports = [], timestampFormat = "YYYY-MM-DD HH:mm:ss", prefix, timestamp, context = {}, parent, asyncMode, customLevels = {}, customColors = {}, } = options;
11
+ this.filters = [];
12
+ this.aggregators = [];
13
+ const { level, colorize, json, transports = [], timestampFormat = "YYYY-MM-DD HH:mm:ss", prefix, timestamp, context = {}, parent, asyncMode, customLevels = {}, customColors = {}, filters = [], aggregators = [], enrichers, } = options;
10
14
  this.parent = parent; // Set parent
11
15
  this.context = { ...context }; // Init context
12
16
  this.customLevels = customLevels; // custom log store
13
17
  this.asyncMode = false;
18
+ this.filters = [...filters]; // Copy filters
19
+ this.aggregators = [...aggregators]; // Copy aggregators
20
+ this.enrichers = enrichers ?? new StructuredExtensions_js_1.LogEnrichmentPipeline(); // Set enrichers, default to new instance
14
21
  if (this.parent) {
15
22
  this.level = level ?? this.parent.level;
16
23
  this.prefix = prefix ?? this.parent.prefix;
@@ -36,6 +43,21 @@ class Logger {
36
43
  this.context = { ...this.parent.context, ...this.context };
37
44
  // Merge custom levels with parent's custom levels
38
45
  this.customLevels = { ...this.parent.customLevels, ...customLevels };
46
+ // Merge filters with parent's filters
47
+ this.filters = [...this.parent.filters, ...filters];
48
+ // Merge aggregators with parent's aggregators
49
+ this.aggregators = [...this.parent.aggregators, ...aggregators];
50
+ // If child logger doesn't provide its own enrichers, use parent's
51
+ // If child logger provides enrichers, merge parent and child enrichers
52
+ if (enrichers) {
53
+ // Create a new pipeline that combines parent and child enrichers
54
+ const parentEnrichers = this.parent.enrichers.getEnrichers();
55
+ const childEnrichers = enrichers.getEnrichers();
56
+ this.enrichers = new StructuredExtensions_js_1.LogEnrichmentPipeline([...parentEnrichers, ...childEnrichers]);
57
+ }
58
+ else {
59
+ this.enrichers = this.parent.enrichers;
60
+ }
39
61
  }
40
62
  else {
41
63
  // Auto-configure based on environment
@@ -140,7 +162,7 @@ class Logger {
140
162
  finalMetadata = metadata;
141
163
  }
142
164
  // Only add metadata if it's not empty after merging
143
- const logData = {
165
+ let logData = {
144
166
  level,
145
167
  message,
146
168
  timestamp,
@@ -149,6 +171,17 @@ class Logger {
149
171
  : undefined,
150
172
  prefix: this.prefix,
151
173
  };
174
+ // Apply enrichers to the log data
175
+ logData = this.enrichers.process(logData);
176
+ // Check if the log should be emitted based on filters
177
+ // Use a copy to prevent concurrent modification issues if filters are modified during logging
178
+ const currentFilters = [...this.filters];
179
+ if (currentFilters.length > 0) {
180
+ const shouldEmit = currentFilters.every(filter => filter.shouldEmit(logData));
181
+ if (!shouldEmit) {
182
+ return; // Don't emit if any filter rejects the log
183
+ }
184
+ }
152
185
  if (this.asyncMode) {
153
186
  for (const transport of this.transports) {
154
187
  if (transport.writeAsync) {
@@ -168,6 +201,17 @@ class Logger {
168
201
  transport.write(logData, this.formatter);
169
202
  }
170
203
  }
204
+ // Send to aggregators if any exist
205
+ if (this.aggregators.length > 0) {
206
+ for (const aggregator of this.aggregators) {
207
+ try {
208
+ aggregator.aggregate(logData, this.formatter);
209
+ }
210
+ catch (error) {
211
+ console.error('Error in aggregator:', error);
212
+ }
213
+ }
214
+ }
171
215
  }
172
216
  debug(message, metadata) {
173
217
  this.log("debug", message, metadata);
@@ -218,8 +262,60 @@ class Logger {
218
262
  return new Logger({ ...options, parent: this });
219
263
  }
220
264
  startTimer(name) {
221
- const { Timer } = require("../utils/Timerutil");
222
- return new Timer(name, (message) => this.info(message));
265
+ return new index_js_1.Timer(name, (message) => this.info(message));
266
+ }
267
+ /**
268
+ * Add a filter to the logger
269
+ */
270
+ addFilter(filter) {
271
+ this.filters.push(filter);
272
+ }
273
+ /**
274
+ * Remove a filter from the logger
275
+ */
276
+ removeFilter(filter) {
277
+ const index = this.filters.indexOf(filter);
278
+ if (index !== -1) {
279
+ this.filters.splice(index, 1);
280
+ return true;
281
+ }
282
+ return false;
283
+ }
284
+ /**
285
+ * Add an aggregator to the logger
286
+ */
287
+ addAggregator(aggregator) {
288
+ this.aggregators.push(aggregator);
289
+ }
290
+ /**
291
+ * Remove an aggregator from the logger
292
+ */
293
+ removeAggregator(aggregator) {
294
+ const index = this.aggregators.indexOf(aggregator);
295
+ if (index !== -1) {
296
+ this.aggregators.splice(index, 1);
297
+ return true;
298
+ }
299
+ return false;
300
+ }
301
+ /**
302
+ * Add an enricher to the logger
303
+ */
304
+ addEnricher(enricher) {
305
+ this.enrichers.add(enricher);
306
+ }
307
+ /**
308
+ * Flush all aggregators
309
+ */
310
+ async flushAggregators() {
311
+ const flushPromises = [];
312
+ for (const aggregator of this.aggregators) {
313
+ const result = aggregator.flush();
314
+ if (result instanceof Promise) {
315
+ flushPromises.push(result);
316
+ }
317
+ }
318
+ await Promise.all(flushPromises);
223
319
  }
224
320
  }
225
321
  exports.Logger = Logger;
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FieldFilter = exports.MetadataFilter = exports.PrefixFilter = exports.LevelFilter = exports.PredicateFilter = exports.NotFilter = exports.OrFilter = exports.CompositeFilter = void 0;
4
+ class CompositeFilter {
5
+ constructor(filters) {
6
+ this.filters = filters;
7
+ }
8
+ shouldEmit(logData) {
9
+ return this.filters.every(filter => filter.shouldEmit(logData));
10
+ }
11
+ }
12
+ exports.CompositeFilter = CompositeFilter;
13
+ class OrFilter {
14
+ constructor(filters) {
15
+ this.filters = filters;
16
+ }
17
+ shouldEmit(logData) {
18
+ return this.filters.some(filter => filter.shouldEmit(logData));
19
+ }
20
+ }
21
+ exports.OrFilter = OrFilter;
22
+ class NotFilter {
23
+ constructor(filter) {
24
+ this.filter = filter;
25
+ }
26
+ shouldEmit(logData) {
27
+ return !this.filter.shouldEmit(logData);
28
+ }
29
+ }
30
+ exports.NotFilter = NotFilter;
31
+ class PredicateFilter {
32
+ constructor(predicate) {
33
+ this.predicate = predicate;
34
+ }
35
+ shouldEmit(logData) {
36
+ return this.predicate(logData);
37
+ }
38
+ }
39
+ exports.PredicateFilter = PredicateFilter;
40
+ class LevelFilter {
41
+ constructor(allowedLevels) {
42
+ this.allowedLevels = new Set(allowedLevels);
43
+ }
44
+ shouldEmit(logData) {
45
+ return this.allowedLevels.has(logData.level);
46
+ }
47
+ }
48
+ exports.LevelFilter = LevelFilter;
49
+ class PrefixFilter {
50
+ constructor(allowedPrefixes) {
51
+ this.allowedPrefixes = new Set(allowedPrefixes);
52
+ }
53
+ shouldEmit(logData) {
54
+ if (!logData.prefix) {
55
+ return this.allowedPrefixes.has('');
56
+ }
57
+ return this.allowedPrefixes.has(logData.prefix);
58
+ }
59
+ }
60
+ exports.PrefixFilter = PrefixFilter;
61
+ class MetadataFilter {
62
+ constructor(requiredMetadata) {
63
+ this.requiredMetadata = requiredMetadata;
64
+ }
65
+ shouldEmit(logData) {
66
+ if (!logData.metadata) {
67
+ return Object.keys(this.requiredMetadata).length === 0;
68
+ }
69
+ for (const [key, value] of Object.entries(this.requiredMetadata)) {
70
+ if (logData.metadata[key] !== value) {
71
+ return false;
72
+ }
73
+ }
74
+ return true;
75
+ }
76
+ }
77
+ exports.MetadataFilter = MetadataFilter;
78
+ class FieldFilter {
79
+ constructor(fieldName, expectedValue) {
80
+ this.fieldName = fieldName;
81
+ this.expectedValue = expectedValue;
82
+ }
83
+ shouldEmit(logData) {
84
+ if (!logData.metadata) {
85
+ return false;
86
+ }
87
+ return logData.metadata[this.fieldName] === this.expectedValue;
88
+ }
89
+ }
90
+ exports.FieldFilter = FieldFilter;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./Filter.js"), exports);
package/dist/cjs/index.js CHANGED
@@ -1,12 +1,31 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.HttpTransport = exports.FileTransport = exports.ConsoleTransport = exports.Logger = void 0;
3
+ exports.Timer = exports.LogEnrichmentPipeline = exports.MetadataEnricher = exports.CompositeAggregator = exports.TimeBasedAggregator = exports.BatchAggregator = exports.FieldFilter = exports.MetadataFilter = exports.PrefixFilter = exports.LevelFilter = exports.PredicateFilter = exports.NotFilter = exports.OrFilter = exports.CompositeFilter = exports.FilterableTransport = exports.HttpTransport = exports.FileTransport = exports.ConsoleTransport = exports.Logger = void 0;
4
4
  const Logger_js_1 = require("./core/Logger.js");
5
5
  Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return Logger_js_1.Logger; } });
6
6
  const index_js_1 = require("./transports/index.js");
7
7
  Object.defineProperty(exports, "ConsoleTransport", { enumerable: true, get: function () { return index_js_1.ConsoleTransport; } });
8
8
  Object.defineProperty(exports, "FileTransport", { enumerable: true, get: function () { return index_js_1.FileTransport; } });
9
9
  Object.defineProperty(exports, "HttpTransport", { enumerable: true, get: function () { return index_js_1.HttpTransport; } });
10
+ Object.defineProperty(exports, "FilterableTransport", { enumerable: true, get: function () { return index_js_1.FilterableTransport; } });
11
+ const index_js_2 = require("./filters/index.js");
12
+ Object.defineProperty(exports, "CompositeFilter", { enumerable: true, get: function () { return index_js_2.CompositeFilter; } });
13
+ Object.defineProperty(exports, "OrFilter", { enumerable: true, get: function () { return index_js_2.OrFilter; } });
14
+ Object.defineProperty(exports, "NotFilter", { enumerable: true, get: function () { return index_js_2.NotFilter; } });
15
+ Object.defineProperty(exports, "PredicateFilter", { enumerable: true, get: function () { return index_js_2.PredicateFilter; } });
16
+ Object.defineProperty(exports, "LevelFilter", { enumerable: true, get: function () { return index_js_2.LevelFilter; } });
17
+ Object.defineProperty(exports, "PrefixFilter", { enumerable: true, get: function () { return index_js_2.PrefixFilter; } });
18
+ Object.defineProperty(exports, "MetadataFilter", { enumerable: true, get: function () { return index_js_2.MetadataFilter; } });
19
+ Object.defineProperty(exports, "FieldFilter", { enumerable: true, get: function () { return index_js_2.FieldFilter; } });
20
+ const index_js_3 = require("./aggregation/index.js");
21
+ Object.defineProperty(exports, "BatchAggregator", { enumerable: true, get: function () { return index_js_3.BatchAggregator; } });
22
+ Object.defineProperty(exports, "TimeBasedAggregator", { enumerable: true, get: function () { return index_js_3.TimeBasedAggregator; } });
23
+ Object.defineProperty(exports, "CompositeAggregator", { enumerable: true, get: function () { return index_js_3.CompositeAggregator; } });
24
+ const index_js_4 = require("./structured/index.js");
25
+ Object.defineProperty(exports, "MetadataEnricher", { enumerable: true, get: function () { return index_js_4.MetadataEnricher; } });
26
+ Object.defineProperty(exports, "LogEnrichmentPipeline", { enumerable: true, get: function () { return index_js_4.LogEnrichmentPipeline; } });
27
+ const index_js_5 = require("./utils/index.js");
28
+ Object.defineProperty(exports, "Timer", { enumerable: true, get: function () { return index_js_5.Timer; } });
10
29
  // Configure default transports to maintain backward compatibility
11
30
  Logger_js_1.Logger.defaultTransportsFactory = (isProd) => {
12
31
  if (isProd) {