@eqxjs/nest-logger 3.1.0-beta.13 โ†’ 3.1.0-beta.14

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 (32) hide show
  1. package/README.md +646 -78
  2. package/dist/constants/action-message.constant.d.ts +171 -0
  3. package/dist/constants/action-message.constant.js +171 -0
  4. package/dist/constants/action-message.constant.js.map +1 -1
  5. package/dist/core/formatters/logger.formatter.d.ts +107 -0
  6. package/dist/core/formatters/logger.formatter.js +107 -0
  7. package/dist/core/formatters/logger.formatter.js.map +1 -1
  8. package/dist/core/loggers/app.logger.d.ts +33 -0
  9. package/dist/core/loggers/app.logger.js +51 -0
  10. package/dist/core/loggers/app.logger.js.map +1 -1
  11. package/dist/core/loggers/custom.logger.d.ts +111 -0
  12. package/dist/core/loggers/custom.logger.js +119 -0
  13. package/dist/core/loggers/custom.logger.js.map +1 -1
  14. package/dist/helpers/datetime.helper.d.ts +23 -0
  15. package/dist/helpers/datetime.helper.js +23 -0
  16. package/dist/helpers/datetime.helper.js.map +1 -1
  17. package/dist/helpers/log.helper.d.ts +81 -0
  18. package/dist/helpers/log.helper.js +81 -0
  19. package/dist/helpers/log.helper.js.map +1 -1
  20. package/dist/helpers/logger-builder.helper.d.ts +207 -2
  21. package/dist/helpers/logger-builder.helper.js +207 -2
  22. package/dist/helpers/logger-builder.helper.js.map +1 -1
  23. package/dist/helpers/message-formatter.helper.d.ts +74 -7
  24. package/dist/helpers/message-formatter.helper.js +74 -7
  25. package/dist/helpers/message-formatter.helper.js.map +1 -1
  26. package/dist/helpers/time-performance.helper.d.ts +61 -0
  27. package/dist/helpers/time-performance.helper.js +62 -1
  28. package/dist/helpers/time-performance.helper.js.map +1 -1
  29. package/dist/models/logger.dto.d.ts +43 -0
  30. package/dist/models/logger.dto.js +43 -0
  31. package/dist/models/logger.dto.js.map +1 -1
  32. package/package.json +1 -1
package/README.md CHANGED
@@ -3,23 +3,28 @@
3
3
  A comprehensive, production-ready logging module for NestJS applications with built-in OpenTelemetry integration, structured logging, and support for multiple message formats.
4
4
 
5
5
  [![Version](https://img.shields.io/npm/v/@eqxjs/nest-logger)](https://www.npmjs.com/package/@eqxjs/nest-logger)
6
- [![Test Coverage](https://img.shields.io/badge/coverage-98.32%25-brightgreen)](./coverage)
6
+ [![Test Coverage](https://img.shields.io/badge/coverage-100%25%20lines-brightgreen)](./coverage)
7
7
  [![Node Version](https://img.shields.io/badge/node-%3E%3D22-brightgreen)](https://nodejs.org)
8
8
 
9
9
  ## Features
10
10
 
11
11
  โœจ **Key Features:**
12
12
 
13
- - ๐Ÿš€ **NestJS Integration** - Seamless integration with NestJS framework
14
- - ๐Ÿ“Š **OpenTelemetry Support** - Built-in metrics, traces, and spans
15
- - ๐Ÿท๏ธ **Structured Logging** - Consistent log format with rich metadata
16
- - ๐Ÿ”’ **Sensitive Data Masking** - Automatic masking of sensitive fields
17
- - ๐Ÿ“ **Multiple Log Levels** - Debug, Info, Warn, Error, Verbose support
18
- - ๐ŸŽฏ **Message Formats** - Support for M1, M2, and M3 message protocols
19
- - โšก **Performance Optimized** - Efficient logging with minimal overhead
20
- - ๐Ÿงช **Well Tested** - 98%+ test coverage with 292 test cases
21
- - ๐Ÿ” **Telemetry Metrics** - Counter and histogram metrics for observability
22
- - ๐Ÿ“ฆ **TypeScript** - Full TypeScript support with type definitions
13
+ - ๐Ÿš€ **NestJS Integration** - Seamless integration with NestJS framework (v11+)
14
+ - ๐Ÿ“Š **OpenTelemetry Support** - Built-in metrics, traces, and spans with distributed tracing
15
+ - ๐Ÿท๏ธ **Structured Logging** - Consistent log format with rich metadata (27+ fields)
16
+ - ๐Ÿ”’ **Sensitive Data Masking** - Automatic masking of sensitive fields (password, token, apiKey, etc.)
17
+ - ๐Ÿ“ **Multiple Log Levels** - Debug, Info, Log, Warn, Error, Verbose support with environment filtering
18
+ - ๐ŸŽฏ **Message Formats** - Support for M1 (broker/queue), M2 (HTTP/protocol), and M3 (service) message protocols
19
+ - โšก **Performance Optimized** - Efficient logging with caching, fast paths, and minimal overhead
20
+ - ๐Ÿงช **Well Tested** - 100% line coverage, 98%+ statement coverage with 297 test cases
21
+ - ๐Ÿ” **Telemetry Metrics** - Counter and histogram metrics for observability with configurable filtering
22
+ - ๐Ÿ“ฆ **TypeScript** - Full TypeScript support with comprehensive type definitions and JSDoc
23
+ - โฑ๏ธ **High-Resolution Timing** - Built-in TimeDiff class for precise performance measurements
24
+ - ๐ŸŽจ **Builder Pattern** - Fluent LoggerDtoBuilder for complex log construction
25
+ - ๐ŸŒ **UTC+7 Timezone** - Standardized timestamps with configurable timezone support
26
+ - ๐Ÿ”ง **Message Truncation** - Automatic message truncation (4096 chars) to prevent log overflow
27
+ - ๐Ÿ“‹ **14 Action Tags** - Predefined action constants for consistent categorization
23
28
 
24
29
  ## Installation
25
30
 
@@ -35,6 +40,46 @@ npm install @eqxjs/nest-logger
35
40
  - Node.js >= 22
36
41
  - NestJS >= 11
37
42
 
43
+ ## Feature Overview
44
+
45
+ ### Logger Types Comparison
46
+
47
+ | Feature | CustomLogger | BaseAppLogger | AppLogger | LoggerFormat (M1/M2/M3) |
48
+ |---------|--------------|---------------|-----------|-------------------------|
49
+ | **Basic Logging** | โœ… | โœ… | โœ… | โœ… |
50
+ | **Structured Metadata** | โŒ | โœ… | โœ… | โœ… |
51
+ | **OpenTelemetry** | โŒ | โœ… | โœ… | โœ… |
52
+ | **Message Formats** | โŒ | โŒ | โœ… | โœ… |
53
+ | **Summary Logs** | โŒ | โœ… | โœ… | โœ… |
54
+ | **Sensitive Masking** | โœ… | โœ… | โœ… | โœ… |
55
+ | **Use Case** | Simple apps | Advanced apps | Multi-format | Specific protocols |
56
+
57
+ ### Supported Log Levels
58
+
59
+ All loggers support these levels (controlled by `LOG_LEVEL` environment variable):
60
+
61
+ - **debug** - Detailed diagnostic information
62
+ - **info** - General informational messages
63
+ - **log** - Alias for info level
64
+ - **warn** - Warning messages for potentially harmful situations
65
+ - **error** - Error events that might still allow the app to continue
66
+ - **verbose** - Most detailed information for deep debugging
67
+
68
+
69
+ ### Metadata Fields
70
+
71
+ LoggerDto includes 27+ fields for comprehensive logging:
72
+
73
+ | Category | Fields |
74
+ |----------|--------|
75
+ | **Core** | level, timestamp, message, action |
76
+ | **Application** | appName, componentName, componentVersion |
77
+ | **Tracking** | sessionId, transactionId, recordName, guid |
78
+ | **Context** | channel, broker, device, user, public |
79
+ | **Use Case** | useCase, useCaseStep |
80
+ | **Result** | appResult, appResultCode, serviceTime, stack |
81
+ | **Infrastructure** | instance, originateServiceName, recordType |
82
+
38
83
  ## Quick Start
39
84
 
40
85
  ### 1. Import the Module
@@ -69,6 +114,116 @@ export class MyService {
69
114
  }
70
115
  ```
71
116
 
117
+ ## Message Protocol Data Structures
118
+
119
+ The logger supports three message protocols (M1, M2, M3), each with specific required properties:
120
+
121
+ ### DataM1I - Broker/Queue Messages
122
+
123
+ **Required Properties:**
124
+ - `header`: DataHeaderI - Message header with identity
125
+ - `protocol`: DataProtocolI - Protocol-specific information
126
+ - `body`: Record<string, unknown> - Message payload
127
+
128
+ ```typescript
129
+ import { DataM1I } from '@eqxjs/nest-logger';
130
+
131
+ const data: DataM1I = {
132
+ header: {
133
+ sessionId: 'session-123',
134
+ transactionId: 'txn-456',
135
+ broker: 'kafka',
136
+ channel: 'order-queue',
137
+ useCase: 'ProcessOrder',
138
+ identity: {
139
+ device: 'mobile-app',
140
+ user: 'user-123',
141
+ public: 'public-id'
142
+ }
143
+ },
144
+ protocol: {
145
+ topic: 'order.created',
146
+ command: 'PROCESS',
147
+ qos: '1'
148
+ },
149
+ body: {
150
+ orderId: '12345',
151
+ amount: 100.00
152
+ }
153
+ };
154
+ ```
155
+
156
+ ### DataM2I - HTTP/Protocol Messages
157
+
158
+ **Required Properties:**
159
+ - `header`: DataHeaderI - Message header with identity
160
+ - `body`: Record<string, unknown> - Message payload
161
+
162
+ **Optional Properties:**
163
+ - `protocol`: DataProtocolI - HTTP/protocol information
164
+
165
+ ```typescript
166
+ import { DataM2I } from '@eqxjs/nest-logger';
167
+
168
+ const data: DataM2I = {
169
+ header: {
170
+ sessionId: 'session-123',
171
+ transactionId: 'txn-456',
172
+ channel: 'web',
173
+ useCase: 'CreatePayment',
174
+ identity: {
175
+ user: 'user-123',
176
+ public: 'public-id'
177
+ }
178
+ },
179
+ body: {
180
+ paymentId: 'pay-123',
181
+ status: 'completed'
182
+ }
183
+ };
184
+ ```
185
+
186
+ ### DataM3I - Service/Database Messages
187
+
188
+ **Required Properties:**
189
+ - `service`: DataServiceI - Service-specific information with identity
190
+ - `body`: Record<string, unknown> - Message payload
191
+
192
+ **Optional Properties:**
193
+ - `header`: DataHeaderI - Message header with identity
194
+
195
+ ```typescript
196
+ import { DataM3I } from '@eqxjs/nest-logger';
197
+
198
+ const data: DataM3I = {
199
+ service: {
200
+ serviceName: 'PostgreSQL',
201
+ name: 'users-db',
202
+ invoke: 'SELECT',
203
+ identity: {
204
+ device: 'db-server-1',
205
+ user: 'db-user'
206
+ }
207
+ },
208
+ body: {
209
+ query: 'SELECT * FROM users WHERE id = $1',
210
+ resultCount: 1
211
+ }
212
+ };
213
+ ```
214
+
215
+ ### Identity Structure
216
+
217
+ All message types include an `identity` object with optional fields:
218
+
219
+ ```typescript
220
+ identity: {
221
+ device?: string | string[]; // Device identifier(s)
222
+ public?: string; // Public identifier
223
+ user?: string; // User identifier
224
+ }
225
+ ```
226
+
72
227
  ## Usage Examples
73
228
 
74
229
  ### Basic Logging
@@ -114,11 +269,11 @@ export class PaymentController {
114
269
  transactionId,
115
270
  channel: 'web',
116
271
  useCase: 'ProcessPayment',
272
+ identity: {},
117
273
  },
118
- protocol: {
119
- method: request.method,
120
- path: request.path,
121
- statusCode: 200,
274
+ body: {
275
+ amount: request.body.amount,
276
+ currency: request.body.currency,
122
277
  },
123
278
  };
124
279
 
@@ -182,6 +337,15 @@ export class OrderConsumer {
182
337
  channel: 'order-topic',
183
338
  useCase: 'ProcessOrder',
184
339
  useCaseStep: 'Consume',
340
+ identity: {},
341
+ },
342
+ protocol: {
343
+ topic: 'order.created',
344
+ command: 'CONSUME',
345
+ },
346
+ body: {
347
+ orderId: message.orderId,
348
+ customerId: message.customerId,
185
349
  },
186
350
  };
187
351
 
@@ -250,15 +414,16 @@ export class UserRepository {
250
414
  const timer = new TimeDiff();
251
415
 
252
416
  const data: DataM3I = {
253
- header: {
254
- sessionId,
255
- transactionId,
256
- useCase: 'GetUser',
257
- },
417
+
258
418
  service: {
259
419
  serviceName: 'PostgreSQL',
260
- operation: 'SELECT',
261
- table: 'users',
420
+ invoke: 'SELECT',
421
+ name: 'users',
422
+ identity: {},
423
+ },
424
+ body: {
425
+ userId: userId,
426
+ operation: 'findById',
262
427
  },
263
428
  };
264
429
 
@@ -320,12 +485,6 @@ export class NotificationService {
320
485
  const timer = new TimeDiff();
321
486
 
322
487
  const data: DataM3I = {
323
- header: {
324
- sessionId,
325
- transactionId,
326
- useCase: 'SendNotification',
327
- useCaseStep: 'SendEmail',
328
- },
329
488
  service: {
330
489
  serviceName: 'EmailService',
331
490
  operation: 'SEND',
@@ -644,6 +803,15 @@ export class KafkaConsumerService {
644
803
  broker: 'kafka',
645
804
  channel: 'queue',
646
805
  useCase: 'MessageProcessing',
806
+ identity: {},
807
+ },
808
+ protocol: {
809
+ topic: 'payment.topic',
810
+ command: 'PROCESS',
811
+ },
812
+ body: {
813
+ messageId: message.id,
814
+ payload: message.data,
647
815
  },
648
816
  };
649
817
 
@@ -681,12 +849,17 @@ export class HttpService {
681
849
  header: {
682
850
  sessionId: req.sessionId,
683
851
  transactionId: req.transactionId,
852
+ identity: {},
684
853
  },
685
854
  protocol: {
686
855
  requestId: req.id,
687
856
  method: req.method,
688
857
  path: req.path,
689
858
  },
859
+ body: {
860
+ endpoint: req.path,
861
+ params: req.params,
862
+ },
690
863
  };
691
864
 
692
865
  this.logger.loggerM2.info(
@@ -713,11 +886,17 @@ export class DatabaseService {
713
886
  header: {
714
887
  sessionId: 'session-123',
715
888
  transactionId: 'txn-456',
889
+ identity: {},
716
890
  },
717
891
  service: {
718
892
  serviceName: 'PostgreSQL',
719
- operation: 'SELECT',
720
- table: 'users',
893
+ invoke: 'SELECT',
894
+ name: 'users',
895
+ identity: {},
896
+ },
897
+ body: {
898
+ query: query,
899
+ database: 'users_db',
721
900
  },
722
901
  };
723
902
 
@@ -828,25 +1007,31 @@ const manualMask = JSON.stringify(sensitiveData, maskMessageReplacer);
828
1007
 
829
1008
  ### Environment Variables
830
1009
 
831
- ```bash
832
- # Log levels (comma-separated)
833
- LOG_LEVEL=debug,info,warn,error,verbose
1010
+ Configure the logger behavior using these environment variables:
834
1011
 
835
- # Sensitive field masking (comma-separated)
836
- LOG_MASK_KEYS=password,secret,token,apiKey
1012
+ | Variable | Type | Default | Description |
1013
+ |----------|------|---------|-------------|
1014
+ | `LOG_LEVEL` | string | - | Comma-separated list of enabled log levels: `debug,info,log,warn,error,verbose` |
1015
+ | `LOG_MASK_KEYS` | string | - | Comma-separated list of field names to mask (e.g., `password,token,apiKey,secret`) |
1016
+ | `APP_VERSION` | string | - | Application version included in telemetry and logs |
1017
+ | `DESTINATION` | string | - | Deployment destination/environment name |
1018
+ | `TELEMETRY_IGNORE_CODE` | string | - | Comma-separated list of result codes to exclude from telemetry metrics |
837
1019
 
838
- # Application version for telemetry
839
- APP_VERSION=1.0.0
1020
+ **Example Configuration:**
840
1021
 
841
- # Telemetry destination
1022
+ ```bash
1023
+ # .env file
1024
+ LOG_LEVEL=debug,info,warn,error,verbose
1025
+ LOG_MASK_KEYS=password,secret,token,apiKey,creditCard,ssn
1026
+ APP_VERSION=1.0.0
842
1027
  DESTINATION=production
843
-
844
- # Ignore specific result codes from telemetry
845
- TELEMETRY_IGNORE_CODE=404,401
1028
+ TELEMETRY_IGNORE_CODE=404,401,403
846
1029
  ```
847
1030
 
848
1031
  ### Log Level Filtering
849
1032
 
1033
+ Control which log levels are output by configuring the `LOG_LEVEL` environment variable:
1034
+
850
1035
  ```typescript
851
1036
  // Only logs matching the LOG_LEVEL env var will be output
852
1037
  process.env.LOG_LEVEL = 'info,error';
@@ -854,22 +1039,58 @@ process.env.LOG_LEVEL = 'info,error';
854
1039
  logger.debug('This will NOT be logged');
855
1040
  logger.info('This WILL be logged');
856
1041
  logger.error('This WILL be logged');
1042
+ logger.verbose('This will NOT be logged');
857
1043
  ```
858
1044
 
859
1045
  ### Sensitive Data Masking
860
1046
 
1047
+ Protect sensitive information by automatically masking specified fields:
1048
+
861
1049
  ```typescript
862
1050
  // Set masked fields via environment
863
- process.env.LOG_MASK_KEYS = 'password,creditCard,ssn';
1051
+ process.env.LOG_MASK_KEYS = 'password,creditCard,ssn,token';
864
1052
 
865
1053
  const userData = {
866
1054
  username: 'john',
867
1055
  password: 'secret123',
868
1056
  creditCard: '4111-1111-1111-1111',
1057
+ email: 'john@example.com',
1058
+ token: 'abc-def-123'
869
1059
  };
870
1060
 
871
1061
  logger.log(userData);
872
- // Output: { username: 'john', password: '*****', creditCard: '*****' }
1062
+ // Output: { username: 'john', password: '*****', creditCard: '*****', email: 'john@example.com', token: '*****' }
1063
+ ```
1064
+
1065
+ ### Telemetry Filtering
1066
+
1067
+ Exclude specific result codes from telemetry metrics to reduce noise:
1068
+
1069
+ ```typescript
1070
+ // Don't track 404 and 401 errors in telemetry
1071
+ process.env.TELEMETRY_IGNORE_CODE = '404,401';
1072
+
1073
+ // These won't be recorded in OpenTelemetry metrics
1074
+ logger.app.summaryError('Not found', '404', 100);
1075
+ logger.app.summaryError('Unauthorized', '401', 50);
1076
+
1077
+ // This will be recorded
1078
+ logger.app.summaryError('Server error', '500', 200);
1079
+ ```
1080
+
1081
+ ### Message Truncation
1082
+
1083
+ Long messages are automatically truncated to prevent log overflow:
1084
+
1085
+ ```typescript
1086
+ // Messages longer than 4096 characters are truncated
1087
+ const longMessage = 'a'.repeat(5000);
1088
+ logger.info(longMessage);
1089
+ // Logged message will be truncated to 4096 chars + '...'
1090
+
1091
+ // The limit is defined in DEFAULT_VALUES.MAX_MESSAGE_LENGTH
1092
+ import { DEFAULT_VALUES } from '@eqxjs/nest-logger';
1093
+ console.log(DEFAULT_VALUES.MAX_MESSAGE_LENGTH); // 4096
873
1094
  ```
874
1095
 
875
1096
  ## OpenTelemetry Integration
@@ -1323,41 +1544,388 @@ class LoggerDto {
1323
1544
 
1324
1545
  ## Best Practices
1325
1546
 
1326
- 1. **Use Appropriate Log Levels**
1327
- - `debug`: Detailed diagnostic information
1328
- - `info`: General informational messages
1329
- - `warn`: Warning messages for potentially harmful situations
1330
- - `error`: Error events that might still allow the application to continue
1331
- - `verbose`: Most detailed information
1332
-
1333
- 2. **Include Context**
1334
- ```typescript
1335
- // Good
1336
- logger.log('User created', 'UserService');
1337
-
1338
- // Better
1339
- logger.app.info(
1340
- 'User created successfully',
1341
- '[USER_CREATE]',
1342
- 'UserService',
1343
- 'user-123'
1344
- );
1345
- ```
1346
-
1347
- 3. **Use Summary Logging for Operations**
1348
- ```typescript
1349
- // Track operation duration and success/failure
1350
- const timer = new TimeDiff();
1351
- try {
1352
- await operation();
1353
- logger.app.summarySuccess('Success', '200', timer.diff());
1354
- } catch (error) {
1355
- logger.app.summaryError('Failed', '500', timer.diff(), ..., [error.stack]);
1356
- }
1357
- ```
1358
-
1359
- 4. **Leverage Message Formats**
1360
- - Use M1 for message queue/broker operations
1547
+ ### 1. Choose the Right Logger
1548
+
1549
+ ```typescript
1550
+ // For simple applications - use CustomLogger
1551
+ const logger = new CustomLogger('MyApp');
1552
+ logger.log('Simple message');
1553
+
1554
+ // For structured logging - use BaseAppLogger
1555
+ const appLogger = new BaseAppLogger('MyApp', 'UserService');
1556
+ appLogger.info('User action', '[USER_CREATE]');
1557
+
1558
+ // For multiple formats - use AppLogger
1559
+ const multiLogger = new AppLogger('MyApp');
1560
+ multiLogger.app.info('Standard log');
1561
+ multiLogger.loggerM1.info('kafka.topic', '[CONSUMING]', data);
1562
+ ```
1563
+
1564
+ ### 2. Use Appropriate Log Levels
1565
+
1566
+ Choose the right level based on the situation:
1567
+
1568
+ ```typescript
1569
+ // DEBUG - Detailed diagnostic information (development only)
1570
+ logger.debug('Request payload:', { userId: 123, action: 'create' });
1571
+
1572
+ // INFO - General informational messages (normal operations)
1573
+ logger.info('User logged in successfully', '[USER_LOGIN]');
1574
+
1575
+ // WARN - Potentially harmful situations (recoverable issues)
1576
+ logger.warn('API rate limit approaching 80%', '[RATE_LIMIT]');
1577
+
1578
+ // ERROR - Error events that might still allow the app to continue
1579
+ logger.error('Failed to send email notification', '[EMAIL_ERROR]');
1580
+
1581
+ // VERBOSE - Most detailed information (deep debugging only)
1582
+ logger.verbose('Internal state:', { state: complexObject });
1583
+ ```
1584
+
1585
+ ### 3. Include Meaningful Context
1586
+
1587
+ Always provide context to make logs searchable and traceable:
1588
+
1589
+ ```typescript
1590
+ // โŒ Bad - No context
1591
+ logger.log('User created');
1592
+
1593
+ // โœ… Good - With context
1594
+ logger.log('User created', 'UserService');
1595
+
1596
+ // โœ… Better - Structured with action tag
1597
+ logger.app.info(
1598
+ 'User created successfully',
1599
+ '[USER_CREATE]',
1600
+ 'UserService',
1601
+ 'user-123' // recordName
1602
+ );
1603
+
1604
+ // โœ… Best - Full metadata for distributed tracing
1605
+ logger.app.info(
1606
+ 'User created successfully',
1607
+ '[USER_CREATE]',
1608
+ 'UserService',
1609
+ 'user-123', // recordName
1610
+ 'sess-456', // sessionId
1611
+ 'txn-789', // transactionId
1612
+ 'mobile', // channel
1613
+ '1.0.0', // componentVersion
1614
+ 'CreateUser', // useCase
1615
+ 'Complete' // useCaseStep
1616
+ );
1617
+ ```
1618
+
1619
+ ### 4. Use Summary Logging for Operations
1620
+
1621
+ Track operation duration and outcomes with summary logs:
1622
+
1623
+ ```typescript
1624
+ // โœ… Best Practice - Track operation with telemetry
1625
+ const timer = new TimeDiff();
1626
+
1627
+ try {
1628
+ const result = await operation();
1629
+
1630
+ // Log success with metrics (automatically creates OpenTelemetry data)
1631
+ logger.app.summarySuccess(
1632
+ 'Operation completed',
1633
+ '200',
1634
+ timer.diff(),
1635
+ 'ServiceName',
1636
+ 'record-123',
1637
+ sessionId,
1638
+ transactionId
1639
+ );
1640
+
1641
+ return result;
1642
+ } catch (error) {
1643
+ // Log error with stack trace and metrics
1644
+ logger.app.summaryError(
1645
+ 'Operation failed',
1646
+ error.code || '500',
1647
+ timer.diff(),
1648
+ 'ServiceName',
1649
+ 'record-123',
1650
+ sessionId,
1651
+ transactionId,
1652
+ undefined,
1653
+ undefined,
1654
+ undefined,
1655
+ undefined,
1656
+ undefined,
1657
+ undefined,
1658
+ [error.stack] // Include stack trace
1659
+ );
1660
+
1661
+ throw error;
1662
+ }
1663
+ ```
1664
+
1665
+ ### 5. Leverage Message Formats
1666
+
1667
+ Use the appropriate format for your use case:
1668
+
1669
+ ```typescript
1670
+ // โœ… M1 for message broker/queue operations
1671
+ logger.loggerM1.info(
1672
+ 'order.created',
1673
+ ActionMessage.consume(),
1674
+ dataM1,
1675
+ 'Processing order message'
1676
+ );
1677
+
1678
+ // โœ… M2 for HTTP/protocol operations
1679
+ logger.loggerM2.info(
1680
+ 'api.users',
1681
+ ActionMessage.httpRequest(),
1682
+ dataM2,
1683
+ 'POST /api/users'
1684
+ );
1685
+
1686
+ // โœ… M3 for database/service operations
1687
+ logger.loggerM3.debug(
1688
+ 'db.users',
1689
+ ActionMessage.dbRequest(),
1690
+ dataM3,
1691
+ 'SELECT * FROM users WHERE id = ?'
1692
+ );
1693
+ ```
1694
+
1695
+ ### 6. Use Action Constants
1696
+
1697
+ Leverage predefined action tags for consistency:
1698
+
1699
+ ```typescript
1700
+ import { ActionMessage } from '@eqxjs/nest-logger';
1701
+
1702
+ // โœ… Use constants instead of strings
1703
+ logger.info('Message received', ActionMessage.consume());
1704
+ logger.info('Request sent', ActionMessage.httpRequest());
1705
+ logger.error('Exception occurred', ActionMessage.exception());
1706
+
1707
+ // โŒ Avoid - Manual strings (typos, inconsistency)
1708
+ logger.info('Message received', '[CONSUMMING]'); // Typo!
1709
+ logger.info('Request sent', '[HTTP-REQUEST]'); // Wrong format
1710
+ ```
1711
+
1712
+ ### 7. Mask Sensitive Data
1713
+
1714
+ Configure masking to protect sensitive information:
1715
+
1716
+ ```typescript
1717
+ // Set up masking in environment
1718
+ process.env.LOG_MASK_KEYS = 'password,apiKey,token,creditCard,ssn';
1719
+
1720
+ // โœ… All sensitive fields will be automatically masked
1721
+ const user = {
1722
+ username: 'john',
1723
+ password: 'secret123', // Will be masked
1724
+ email: 'john@example.com'
1725
+ };
1726
+
1727
+ logger.info('User data', user);
1728
+ // Output: { username: 'john', password: '*****', email: 'john@example.com' }
1729
+ ```
1730
+
1731
+ ### 8. Configure Environment Variables
1732
+
1733
+ Set up proper configuration for each environment:
1734
+
1735
+ ```typescript
1736
+ // Development
1737
+ process.env.LOG_LEVEL = 'debug,info,log,warn,error,verbose';
1738
+ process.env.LOG_MASK_KEYS = 'password,token';
1739
+ process.env.TELEMETRY_IGNORE_CODE = '';
1740
+
1741
+ // Production
1742
+ process.env.LOG_LEVEL = 'info,warn,error';
1743
+ process.env.LOG_MASK_KEYS = 'password,token,apiKey,secret,creditCard,ssn';
1744
+ process.env.TELEMETRY_IGNORE_CODE = '404,401,403';
1745
+ process.env.APP_VERSION = '1.0.0';
1746
+ process.env.DESTINATION = 'production';
1747
+ ```
1748
+
1749
+ ### 9. Use TimeDiff for Performance Tracking
1750
+
1751
+ Measure and log operation performance:
1752
+
1753
+ ```typescript
1754
+ import { TimeDiff } from '@eqxjs/nest-logger';
1755
+
1756
+ // โœ… Track operation duration
1757
+ async function processData() {
1758
+ const timer = TimeDiff.start();
1759
+
1760
+ // Step 1
1761
+ await step1();
1762
+ logger.debug(`Step 1 completed in ${timer.diff()}ms`);
1763
+
1764
+ // Step 2
1765
+ await step2();
1766
+ logger.debug(`Step 2 completed in ${timer.diff()}ms`);
1767
+
1768
+ // Total time
1769
+ const total = timer.end();
1770
+ logger.info(`Total processing time: ${total}ms`);
1771
+ }
1772
+ ```
1773
+
1774
+ ### 10. Handle Errors Consistently
1775
+
1776
+ Establish a consistent pattern for error handling:
1777
+
1778
+ ```typescript
1779
+ async function businessOperation() {
1780
+ const timer = new TimeDiff();
1781
+ const sessionId = 'sess-123';
1782
+ const transactionId = 'txn-456';
1783
+
1784
+ try {
1785
+ logger.app.info(
1786
+ 'Starting operation',
1787
+ ActionMessage.appLogic(),
1788
+ 'MyService',
1789
+ 'record-123',
1790
+ sessionId,
1791
+ transactionId
1792
+ );
1793
+
1794
+ const result = await performOperation();
1795
+
1796
+ logger.app.summarySuccess(
1797
+ 'Operation successful',
1798
+ '200',
1799
+ timer.diff(),
1800
+ 'MyService',
1801
+ 'record-123',
1802
+ sessionId,
1803
+ transactionId
1804
+ );
1805
+
1806
+ return result;
1807
+
1808
+ } catch (error) {
1809
+ logger.app.error(
1810
+ `Operation failed: ${error.message}`,
1811
+ ActionMessage.exception(),
1812
+ 'MyService',
1813
+ 'record-123',
1814
+ sessionId,
1815
+ transactionId
1816
+ );
1817
+
1818
+ logger.app.summaryError(
1819
+ 'Operation failed',
1820
+ error.code || '500',
1821
+ timer.diff(),
1822
+ 'MyService',
1823
+ 'record-123',
1824
+ sessionId,
1825
+ transactionId,
1826
+ undefined,
1827
+ undefined,
1828
+ undefined,
1829
+ undefined,
1830
+ undefined,
1831
+ undefined,
1832
+ [error.stack]
1833
+ );
1834
+
1835
+ throw error;
1836
+ }
1837
+ }
1838
+ ```
1839
+
1840
+ ## Performance Considerations
1841
+
1842
+ - **Caching**: Logger caches hostname and app version for performance
1843
+ - **Fast Paths**: String messages use optimized fast paths
1844
+ - **Message Truncation**: Long messages automatically truncated to 4096 chars
1845
+ - **Level Filtering**: Disabled log levels have minimal overhead (early return)
1846
+ - **Lazy Evaluation**: Complex operations only performed for enabled levels
1847
+
1848
+ ## Troubleshooting
1849
+
1850
+ ### Logs Not Appearing
1851
+
1852
+ Check that the log level is enabled:
1853
+
1854
+ ```typescript
1855
+ process.env.LOG_LEVEL = 'debug,info,warn,error,verbose';
1856
+ // Make sure the level you're using is in this list
1857
+ ```
1858
+
1859
+ ### Sensitive Data Still Visible
1860
+
1861
+ Ensure masking is configured:
1862
+
1863
+ ```typescript
1864
+ process.env.LOG_MASK_KEYS = 'password,token,apiKey,secret';
1865
+ // Add all field names that should be masked
1866
+ ```
1867
+
1868
+ ### Telemetry Not Working
1869
+
1870
+ Verify OpenTelemetry is configured in your application and the result codes aren't ignored:
1871
+
1872
+ ```typescript
1873
+ // Check if code is in ignore list
1874
+ process.env.TELEMETRY_IGNORE_CODE = '404,401';
1875
+ // These codes won't be tracked in telemetry
1876
+ ```
1877
+
1878
+ ### TypeScript Type Errors
1879
+
1880
+ Import the correct interfaces:
1881
+
1882
+ ```typescript
1883
+ import {
1884
+ DataM1I,
1885
+ DataM2I,
1886
+ DataM3I,
1887
+ LoggerOpt
1888
+ } from '@eqxjs/nest-logger';
1889
+ ```
1890
+
1891
+ ## Testing
1892
+
1893
+ The module includes comprehensive test coverage (100% lines):
1894
+
1895
+ ```bash
1896
+ # Run tests
1897
+ yarn test
1898
+
1899
+ # Run tests with coverage
1900
+ yarn test:cov
1901
+
1902
+ # Watch mode
1903
+ yarn test:watch
1904
+ ```
1905
+
1906
+ ## Development
1907
+
1908
+ Please see [docs/README.md](docs/README.md) for development guidelines.
1909
+
1910
+ ## Contributing
1911
+
1912
+ Please see [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines.
1913
+
1914
+ ## License
1915
+
1916
+ ISC
1917
+
1918
+ ## Support
1919
+
1920
+ For issues, questions, or contributions, please visit the [GitHub repository](https://github.com/eqxjs/nest-logger).
1921
+
1922
+ ## Changelog
1923
+
1924
+ See [CHANGELOG](CHANGELOG) for release notes and version history.
1925
+
1926
+ ---
1927
+
1928
+ **Made with โค๏ธ by the EQXJS Team**
1361
1929
  - Use M2 for HTTP/protocol-specific operations
1362
1930
  - Use M3 for service-to-service operations
1363
1931