@venizia/ignis-docs 0.0.5 → 0.0.6-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 (123) hide show
  1. package/package.json +1 -1
  2. package/wiki/best-practices/architectural-patterns.md +0 -2
  3. package/wiki/best-practices/architecture-decisions.md +0 -8
  4. package/wiki/best-practices/code-style-standards/control-flow.md +1 -1
  5. package/wiki/best-practices/code-style-standards/index.md +0 -1
  6. package/wiki/best-practices/code-style-standards/tooling.md +0 -3
  7. package/wiki/best-practices/contribution-workflow.md +12 -12
  8. package/wiki/best-practices/index.md +4 -14
  9. package/wiki/best-practices/performance-optimization.md +3 -3
  10. package/wiki/best-practices/security-guidelines.md +2 -2
  11. package/wiki/best-practices/troubleshooting-tips.md +1 -1
  12. package/wiki/guides/core-concepts/application/bootstrapping.md +6 -7
  13. package/wiki/guides/core-concepts/components-guide.md +1 -1
  14. package/wiki/guides/core-concepts/components.md +2 -2
  15. package/wiki/guides/core-concepts/dependency-injection.md +4 -5
  16. package/wiki/guides/core-concepts/persistent/datasources.md +4 -5
  17. package/wiki/guides/core-concepts/services.md +1 -1
  18. package/wiki/guides/get-started/5-minute-quickstart.md +4 -5
  19. package/wiki/guides/get-started/philosophy.md +12 -24
  20. package/wiki/guides/index.md +2 -9
  21. package/wiki/guides/reference/mcp-docs-server.md +13 -13
  22. package/wiki/guides/tutorials/building-a-crud-api.md +10 -10
  23. package/wiki/guides/tutorials/complete-installation.md +11 -12
  24. package/wiki/guides/tutorials/ecommerce-api.md +3 -3
  25. package/wiki/guides/tutorials/realtime-chat.md +6 -6
  26. package/wiki/guides/tutorials/testing.md +4 -5
  27. package/wiki/index.md +8 -14
  28. package/wiki/references/base/bootstrapping.md +0 -3
  29. package/wiki/references/base/components.md +2 -2
  30. package/wiki/references/base/controllers.md +0 -1
  31. package/wiki/references/base/datasources.md +1 -1
  32. package/wiki/references/base/dependency-injection.md +2 -2
  33. package/wiki/references/base/filter-system/default-filter.md +2 -3
  34. package/wiki/references/base/filter-system/index.md +1 -1
  35. package/wiki/references/base/filter-system/quick-reference.md +0 -14
  36. package/wiki/references/base/middlewares.md +0 -8
  37. package/wiki/references/base/providers.md +0 -9
  38. package/wiki/references/base/repositories/advanced.md +1 -1
  39. package/wiki/references/base/repositories/mixins.md +2 -3
  40. package/wiki/references/base/services.md +0 -1
  41. package/wiki/references/components/authentication/api.md +444 -0
  42. package/wiki/references/components/authentication/errors.md +177 -0
  43. package/wiki/references/components/authentication/index.md +571 -0
  44. package/wiki/references/components/authentication/usage.md +781 -0
  45. package/wiki/references/components/health-check.md +292 -103
  46. package/wiki/references/components/index.md +14 -12
  47. package/wiki/references/components/mail/api.md +505 -0
  48. package/wiki/references/components/mail/errors.md +176 -0
  49. package/wiki/references/components/mail/index.md +535 -0
  50. package/wiki/references/components/mail/usage.md +404 -0
  51. package/wiki/references/components/request-tracker.md +229 -25
  52. package/wiki/references/components/socket-io/api.md +1051 -0
  53. package/wiki/references/components/socket-io/errors.md +119 -0
  54. package/wiki/references/components/socket-io/index.md +410 -0
  55. package/wiki/references/components/socket-io/usage.md +322 -0
  56. package/wiki/references/components/static-asset/api.md +261 -0
  57. package/wiki/references/components/static-asset/errors.md +89 -0
  58. package/wiki/references/components/static-asset/index.md +617 -0
  59. package/wiki/references/components/static-asset/usage.md +364 -0
  60. package/wiki/references/components/swagger.md +390 -110
  61. package/wiki/references/components/template/api-page.md +125 -0
  62. package/wiki/references/components/template/errors-page.md +100 -0
  63. package/wiki/references/components/template/index.md +104 -0
  64. package/wiki/references/components/template/setup-page.md +134 -0
  65. package/wiki/references/components/template/single-page.md +132 -0
  66. package/wiki/references/components/template/usage-page.md +127 -0
  67. package/wiki/references/components/websocket/api.md +508 -0
  68. package/wiki/references/components/websocket/errors.md +123 -0
  69. package/wiki/references/components/websocket/index.md +453 -0
  70. package/wiki/references/components/websocket/usage.md +475 -0
  71. package/wiki/references/helpers/cron/index.md +224 -0
  72. package/wiki/references/helpers/crypto/index.md +537 -0
  73. package/wiki/references/helpers/env/index.md +214 -0
  74. package/wiki/references/helpers/error/index.md +232 -0
  75. package/wiki/references/helpers/index.md +16 -15
  76. package/wiki/references/helpers/inversion/index.md +608 -0
  77. package/wiki/references/helpers/logger/index.md +600 -0
  78. package/wiki/references/helpers/network/api.md +986 -0
  79. package/wiki/references/helpers/network/index.md +620 -0
  80. package/wiki/references/helpers/queue/index.md +589 -0
  81. package/wiki/references/helpers/redis/index.md +495 -0
  82. package/wiki/references/helpers/socket-io/api.md +497 -0
  83. package/wiki/references/helpers/socket-io/index.md +513 -0
  84. package/wiki/references/helpers/storage/api.md +705 -0
  85. package/wiki/references/helpers/storage/index.md +583 -0
  86. package/wiki/references/helpers/template/index.md +66 -0
  87. package/wiki/references/helpers/template/single-page.md +126 -0
  88. package/wiki/references/helpers/testing/index.md +510 -0
  89. package/wiki/references/helpers/types/index.md +512 -0
  90. package/wiki/references/helpers/uid/index.md +272 -0
  91. package/wiki/references/helpers/websocket/api.md +736 -0
  92. package/wiki/references/helpers/websocket/index.md +574 -0
  93. package/wiki/references/helpers/worker-thread/index.md +470 -0
  94. package/wiki/references/index.md +2 -9
  95. package/wiki/references/quick-reference.md +3 -18
  96. package/wiki/references/utilities/jsx.md +1 -8
  97. package/wiki/references/utilities/statuses.md +0 -7
  98. package/wiki/references/components/authentication.md +0 -476
  99. package/wiki/references/components/mail.md +0 -687
  100. package/wiki/references/components/socket-io.md +0 -562
  101. package/wiki/references/components/static-asset.md +0 -1277
  102. package/wiki/references/helpers/cron.md +0 -108
  103. package/wiki/references/helpers/crypto.md +0 -132
  104. package/wiki/references/helpers/env.md +0 -83
  105. package/wiki/references/helpers/error.md +0 -97
  106. package/wiki/references/helpers/inversion.md +0 -176
  107. package/wiki/references/helpers/logger.md +0 -296
  108. package/wiki/references/helpers/network.md +0 -396
  109. package/wiki/references/helpers/queue.md +0 -150
  110. package/wiki/references/helpers/redis.md +0 -142
  111. package/wiki/references/helpers/socket-io.md +0 -932
  112. package/wiki/references/helpers/storage.md +0 -665
  113. package/wiki/references/helpers/testing.md +0 -133
  114. package/wiki/references/helpers/types.md +0 -167
  115. package/wiki/references/helpers/uid.md +0 -167
  116. package/wiki/references/helpers/worker-thread.md +0 -178
  117. package/wiki/references/src-details/boot.md +0 -379
  118. package/wiki/references/src-details/core.md +0 -263
  119. package/wiki/references/src-details/dev-configs.md +0 -298
  120. package/wiki/references/src-details/docs.md +0 -71
  121. package/wiki/references/src-details/helpers.md +0 -211
  122. package/wiki/references/src-details/index.md +0 -86
  123. package/wiki/references/src-details/inversion.md +0 -340
@@ -0,0 +1,600 @@
1
+ # Logger
2
+
3
+ Winston-based logging with scoped prefixes, multiple transports (console, daily-rotating files, UDP), and a zero-allocation high-frequency logger for performance-critical paths.
4
+
5
+ ## Quick Reference
6
+
7
+ | Class | Extends | Use Case |
8
+ |-------|---------|----------|
9
+ | `Logger` | -- | General-purpose scoped logger with caching |
10
+ | `LoggerFactory` | -- | Factory that builds `Logger` instances from scope arrays |
11
+ | `HfLogger` | -- | Zero-allocation ring-buffer logger for hot paths (~100-300ns) |
12
+ | `HfLogFlusher` | -- | Background flusher for `HfLogger` entries |
13
+ | `DgramTransport` | `winston-transport.Transport` | Custom Winston transport that sends logs over UDP |
14
+
15
+ #### Import Paths
16
+
17
+ ```typescript
18
+ // Core classes
19
+ import { Logger, LoggerFactory, ApplicationLogger } from '@venizia/ignis-helpers';
20
+
21
+ // High-frequency logger
22
+ import { HfLogger, HfLogFlusher } from '@venizia/ignis-helpers';
23
+
24
+ // Constants & types
25
+ import { LogLevels, LoggerFormats } from '@venizia/ignis-helpers';
26
+ import type { TLogLevel, TLoggerFormat } from '@venizia/ignis-helpers';
27
+
28
+ // Custom logger utilities
29
+ import {
30
+ defineCustomLogger,
31
+ defineLogFormatter,
32
+ defineJsonLoggerFormatter,
33
+ definePrettyLoggerFormatter,
34
+ applicationLogFormatter,
35
+ applicationLogger,
36
+ } from '@venizia/ignis-helpers';
37
+ import type { IFileTransportOptions, ICustomLoggerOptions } from '@venizia/ignis-helpers';
38
+
39
+ // UDP transport
40
+ import { DgramTransport } from '@venizia/ignis-helpers';
41
+ import type { IDgramTransportOptions } from '@venizia/ignis-helpers';
42
+ ```
43
+
44
+ ## Creating an Instance
45
+
46
+ ### Using LoggerFactory (Recommended)
47
+
48
+ `LoggerFactory.getLogger` accepts an array of scope strings, joins them with `-`, and returns a cached `Logger` instance.
49
+
50
+ ```typescript
51
+ import { LoggerFactory } from '@venizia/ignis-helpers';
52
+
53
+ const logger = LoggerFactory.getLogger(['MyService']);
54
+ logger.info('Service initialized');
55
+ // Output: [MyService] Service initialized
56
+
57
+ const scopedLogger = LoggerFactory.getLogger(['Payment', 'Stripe']);
58
+ scopedLogger.info('Charge created');
59
+ // Output: [Payment-Stripe] Charge created
60
+ ```
61
+
62
+ > [!TIP]
63
+ > `LoggerFactory` is how `BaseHelper` creates its internal logger. Every helper in the framework gets a scoped logger automatically through this path.
64
+
65
+ ### Using Logger.get() Directly
66
+
67
+ ```typescript
68
+ import { Logger } from '@venizia/ignis-helpers';
69
+
70
+ const logger = Logger.get('MyService');
71
+ logger.info('Direct logger access');
72
+ // Output: [MyService] Direct logger access
73
+ ```
74
+
75
+ Pass a custom Winston logger instance as the second parameter to use your own transport configuration:
76
+
77
+ ```typescript
78
+ import { Logger, defineCustomLogger, applicationLogFormatter } from '@venizia/ignis-helpers';
79
+
80
+ const customWinstonLogger = defineCustomLogger({
81
+ loggerFormatter: applicationLogFormatter,
82
+ transports: {
83
+ info: { file: { prefix: 'custom', folder: './logs' } },
84
+ error: { file: { prefix: 'custom-error', folder: './logs' } },
85
+ },
86
+ });
87
+
88
+ const logger = Logger.get('MyService', customWinstonLogger);
89
+ ```
90
+
91
+ Custom loggers are cached under a separate key (`scope:custom`), so a default and custom logger for the same scope can coexist.
92
+
93
+ ### Logger Caching
94
+
95
+ Both methods use internal caching -- the same scope always returns the same `Logger` instance:
96
+
97
+ ```typescript
98
+ const logger1 = Logger.get('MyService');
99
+ const logger2 = Logger.get('MyService');
100
+ // logger1 === logger2 (same instance)
101
+ ```
102
+
103
+ ### ApplicationLogger Alias
104
+
105
+ `ApplicationLogger` is exported as both a value and a type alias for `Logger`, providing backward compatibility:
106
+
107
+ ```typescript
108
+ import { ApplicationLogger } from '@venizia/ignis-helpers';
109
+
110
+ const logger = ApplicationLogger.get('MyService');
111
+ ```
112
+
113
+ ## Usage
114
+
115
+ ### Log Levels
116
+
117
+ The `Logger` class exposes direct methods for `info`, `warn`, `error`, `emerg`, and `debug`. Other levels (`alert`, `http`, `verbose`, `silly`) are accessible through the generic `log()` method.
118
+
119
+ ```typescript
120
+ logger.info('User created');
121
+ logger.warn('Rate limit approaching');
122
+ logger.error('Failed to process payment');
123
+ logger.emerg('System out of memory');
124
+ logger.debug('Query took 12ms'); // Requires DEBUG=true
125
+ logger.log('alert', 'Threshold exceeded'); // Generic method for any level
126
+ ```
127
+
128
+ The `LogLevels` class defines all available levels and provides validation:
129
+
130
+ ```typescript
131
+ import { LogLevels } from '@venizia/ignis-helpers';
132
+ import type { TLogLevel } from '@venizia/ignis-helpers';
133
+
134
+ LogLevels.ERROR; // 'error'
135
+ LogLevels.ALERT; // 'alert'
136
+ LogLevels.EMERG; // 'emerg'
137
+ LogLevels.WARN; // 'warn'
138
+ LogLevels.INFO; // 'info'
139
+ LogLevels.HTTP; // 'http'
140
+ LogLevels.VERBOSE; // 'verbose'
141
+ LogLevels.DEBUG; // 'debug'
142
+ LogLevels.SILLY; // 'silly'
143
+
144
+ LogLevels.isValid('info'); // true
145
+ LogLevels.isValid('unknown'); // false
146
+
147
+ const level: TLogLevel = 'info';
148
+ ```
149
+
150
+ #### Winston Level Priority
151
+
152
+ The `defineCustomLogger` function configures Winston with these numeric priorities by default:
153
+
154
+ | Level | Priority | Color |
155
+ |-------|----------|-------|
156
+ | `error` | 0 | red |
157
+ | `alert` | 0 | red |
158
+ | `emerg` | 0 | red |
159
+ | `warn` | 1 | yellow |
160
+ | `info` | 2 | green |
161
+ | `http` | 3 | magenta |
162
+ | `verbose` | 4 | gray |
163
+ | `debug` | 5 | blue |
164
+ | `silly` | 6 | gray |
165
+
166
+ Lower numeric values have higher priority. `error`, `alert`, and `emerg` share priority `0`.
167
+
168
+ ### Method-Scoped Logging
169
+
170
+ The `.for()` method creates a sub-scoped logger for specific methods, appending the method name to the scope with a `-` separator. The resulting logger is also cached.
171
+
172
+ ```typescript
173
+ class UserService {
174
+ private logger = LoggerFactory.getLogger(['UserService']);
175
+
176
+ async createUser(data: CreateUserDto) {
177
+ this.logger.for('createUser').info('Creating user: %j', data);
178
+ // Output: [UserService-createUser] Creating user: {...}
179
+
180
+ try {
181
+ const user = await this.userRepo.create({ data });
182
+ this.logger.for('createUser').info('User created: %s', user.id);
183
+ return user;
184
+ } catch (error) {
185
+ this.logger.for('createUser').error('Failed to create user: %s', error);
186
+ throw error;
187
+ }
188
+ }
189
+ }
190
+ ```
191
+
192
+ ### Log Formats
193
+
194
+ The logger supports two output formats, controlled by the `APP_ENV_LOGGER_FORMAT` environment variable (default: `text`).
195
+
196
+ The `LoggerFormats` class provides constants and validation:
197
+
198
+ ```typescript
199
+ import { LoggerFormats } from '@venizia/ignis-helpers';
200
+ import type { TLoggerFormat } from '@venizia/ignis-helpers';
201
+
202
+ LoggerFormats.JSON; // 'json'
203
+ LoggerFormats.TEXT; // 'text'
204
+ LoggerFormats.isValid('json'); // true
205
+
206
+ const fmt: TLoggerFormat = 'text';
207
+ ```
208
+
209
+ #### JSON Format
210
+
211
+ ```bash
212
+ APP_ENV_LOGGER_FORMAT=json
213
+ ```
214
+
215
+ Output:
216
+
217
+ ```json
218
+ {"level":"info","message":"[UserService] User created","timestamp":"2024-01-11T10:30:00.000Z","label":"APP"}
219
+ ```
220
+
221
+ #### Pretty Text Format (Default)
222
+
223
+ ```bash
224
+ APP_ENV_LOGGER_FORMAT=text
225
+ ```
226
+
227
+ Output:
228
+
229
+ ```
230
+ 2024-01-11T10:30:00.000Z [APP] info: [UserService] User created
231
+ ```
232
+
233
+ > [!NOTE]
234
+ > The label shown in log output (e.g. `APP`) comes from `APP_ENV_APPLICATION_NAME` (defaults to `'APP'`). Set this env var to customize the label for your application.
235
+
236
+ #### Custom Formatters
237
+
238
+ Build formatters directly using the exported helper functions:
239
+
240
+ ```typescript
241
+ import {
242
+ defineLogFormatter,
243
+ defineJsonLoggerFormatter,
244
+ definePrettyLoggerFormatter,
245
+ } from '@venizia/ignis-helpers';
246
+
247
+ // Auto-detect from APP_ENV_LOGGER_FORMAT (or override with format option)
248
+ const formatter = defineLogFormatter({ label: 'my-app' });
249
+ const jsonFmt = defineLogFormatter({ label: 'my-app', format: 'json' });
250
+
251
+ // Or use specific formatters directly
252
+ const jsonFormatter = defineJsonLoggerFormatter({ label: 'my-app' });
253
+ const prettyFormatter = definePrettyLoggerFormatter({ label: 'my-app' });
254
+ ```
255
+
256
+ ### Transports
257
+
258
+ Every logger created by `defineCustomLogger` always includes a **Console** transport at the `debug` level. File and UDP transports are optional.
259
+
260
+ #### File Rotation (DailyRotateFile)
261
+
262
+ Configure file rotation through environment variables or programmatically via `IFileTransportOptions`.
263
+
264
+ **Environment variables:**
265
+
266
+ | Variable | Default | Description |
267
+ |----------|---------|-------------|
268
+ | `APP_ENV_LOGGER_FOLDER_PATH` | `./` | Log files directory |
269
+ | `APP_ENV_LOGGER_FILE_FREQUENCY` | `1h` | Rotation frequency |
270
+ | `APP_ENV_LOGGER_FILE_MAX_SIZE` | `100m` | Max file size before rotation |
271
+ | `APP_ENV_LOGGER_FILE_MAX_FILES` | `5d` | Retention period |
272
+ | `APP_ENV_LOGGER_FILE_DATE_PATTERN` | `YYYYMMDD_HH` | Date pattern in filename |
273
+
274
+ **Programmatic configuration:**
275
+
276
+ ```typescript
277
+ import { defineCustomLogger, applicationLogFormatter } from '@venizia/ignis-helpers';
278
+
279
+ const customLogger = defineCustomLogger({
280
+ loggerFormatter: applicationLogFormatter,
281
+ transports: {
282
+ info: {
283
+ file: {
284
+ prefix: 'my-app',
285
+ folder: './logs',
286
+ frequency: '24h',
287
+ maxSize: '500m',
288
+ maxFiles: '30d',
289
+ datePattern: 'YYYYMMDD',
290
+ },
291
+ },
292
+ error: {
293
+ file: {
294
+ prefix: 'my-app-error',
295
+ folder: './logs',
296
+ maxFiles: '90d',
297
+ },
298
+ },
299
+ },
300
+ });
301
+ ```
302
+
303
+ Generated filename pattern: `{folder}/{prefix}-info-{DATE}.log` or `{folder}/{prefix}-error-{DATE}.log`.
304
+
305
+ #### IFileTransportOptions
306
+
307
+ ```typescript
308
+ interface IFileTransportOptions {
309
+ prefix: string; // Filename prefix (required)
310
+ folder: string; // Output directory (required)
311
+ frequency?: string; // Rotation frequency (default: '1h')
312
+ maxSize?: string; // Max file size (default: '100m')
313
+ maxFiles?: string; // Retention period (default: '5d')
314
+ datePattern?: string; // Date pattern in filename (default: 'YYYYMMDD_HH')
315
+ }
316
+ ```
317
+
318
+ #### UDP Transport (DgramTransport)
319
+
320
+ The `DgramTransport` is a custom Winston transport that sends log entries over UDP. It supports level-based filtering -- only messages matching the configured `levels` set are forwarded.
321
+
322
+ ```typescript
323
+ import { DgramTransport } from '@venizia/ignis-helpers';
324
+
325
+ const transport = new DgramTransport({
326
+ label: 'my-app',
327
+ host: '127.0.0.1',
328
+ port: 5000,
329
+ levels: ['error', 'warn', 'info'],
330
+ socketOptions: { type: 'udp4' },
331
+ });
332
+ ```
333
+
334
+ **Static factory with validation** -- returns `null` if any required field is missing:
335
+
336
+ ```typescript
337
+ const transport = DgramTransport.fromPartial({
338
+ label: 'my-app',
339
+ host: '127.0.0.1',
340
+ port: 5000,
341
+ levels: ['error', 'warn'],
342
+ socketOptions: { type: 'udp4' },
343
+ });
344
+ // Returns null if label, host, port, levels (non-empty), or socketOptions is missing
345
+ ```
346
+
347
+ The transport automatically re-establishes the UDP socket if it encounters an error.
348
+
349
+ **Environment variables for the default application logger:**
350
+
351
+ | Variable | Description |
352
+ |----------|-------------|
353
+ | `APP_ENV_LOGGER_DGRAM_HOST` | UDP log aggregator host |
354
+ | `APP_ENV_LOGGER_DGRAM_PORT` | UDP log aggregator port |
355
+ | `APP_ENV_LOGGER_DGRAM_LABEL` | Label to identify log source |
356
+ | `APP_ENV_LOGGER_DGRAM_LEVELS` | Comma-separated levels to send via UDP |
357
+
358
+ #### IDgramTransportOptions
359
+
360
+ ```typescript
361
+ interface IDgramTransportOptions extends Transport.TransportStreamOptions {
362
+ label: string; // Label to identify log source
363
+ host: string; // UDP host
364
+ port: number; // UDP port
365
+ levels: Array<string>; // Levels to forward over UDP
366
+ socketOptions: dgram.SocketOptions; // Node.js dgram socket options
367
+ }
368
+ ```
369
+
370
+ #### ICustomLoggerOptions
371
+
372
+ ```typescript
373
+ interface ICustomLoggerOptions {
374
+ logLevels?: { [name: string | symbol]: number };
375
+ logColors?: { [name: string | symbol]: string };
376
+ loggerFormatter?: ReturnType<typeof winston.format.combine>;
377
+ transports: {
378
+ info: {
379
+ file?: IFileTransportOptions;
380
+ dgram?: Partial<IDgramTransportOptions>;
381
+ };
382
+ error: {
383
+ file?: IFileTransportOptions;
384
+ dgram?: Partial<IDgramTransportOptions>;
385
+ };
386
+ };
387
+ }
388
+ ```
389
+
390
+ Both `info` and `error` transport groups support optional `file` (DailyRotateFile) and `dgram` (UDP) transports. A console transport is always included. Error file transports are also registered as exception handlers.
391
+
392
+ ### Debug Logging Behavior
393
+
394
+ Debug logs require **both** conditions to be met:
395
+
396
+ 1. `DEBUG=true` environment variable is set (parsed via `toBoolean`)
397
+ 2. `NODE_ENV` is either unset **or** is present in the `Environment.COMMON_ENVS` set
398
+
399
+ The `COMMON_ENVS` set includes: `local`, `debug`, `development`, `alpha`, `beta`, `staging`, `production`. You can extend this set with `APP_ENV_EXTRA_LOG_ENVS`:
400
+
401
+ ```bash
402
+ DEBUG=true
403
+ NODE_ENV=development
404
+ APP_ENV_EXTRA_LOG_ENVS=qa,preview # Comma-separated additional environments
405
+ ```
406
+
407
+ > [!IMPORTANT]
408
+ > The debug flag check is pre-computed at module load time. Changing `DEBUG` or `NODE_ENV` at runtime has no effect -- the values are captured once when the module is first imported.
409
+
410
+ ### High-Frequency Logger (HfLogger)
411
+
412
+ For performance-critical applications (e.g., HFT systems, game servers), `HfLogger` provides zero-allocation logging via a lock-free ring buffer backed by `SharedArrayBuffer`.
413
+
414
+ ```typescript
415
+ import { HfLogger, HfLogFlusher } from '@venizia/ignis-helpers';
416
+
417
+ // At initialization time (once):
418
+ const logger = HfLogger.get('OrderEngine');
419
+ const MSG_ORDER_SENT = HfLogger.encodeMessage('Order sent');
420
+ const MSG_ORDER_FILLED = HfLogger.encodeMessage('Order filled');
421
+
422
+ // Start background flusher
423
+ const flusher = new HfLogFlusher();
424
+ flusher.start(100); // Flush every 100ms
425
+
426
+ // In hot path (~100-300ns, zero allocation):
427
+ logger.log('info', MSG_ORDER_SENT);
428
+ logger.log('info', MSG_ORDER_FILLED);
429
+ ```
430
+
431
+ #### HfLogger API
432
+
433
+ | Method | Signature | Description |
434
+ |--------|-----------|-------------|
435
+ | `HfLogger.get` | `(scope: string) => HfLogger` | Get or create a cached logger instance |
436
+ | `HfLogger.encodeMessage` | `(msg: string) => Uint8Array` | Pre-encode a message string to bytes (cached) |
437
+ | `logger.log` | `(level: THfLogLevel, messageBytes: Uint8Array) => void` | Write entry to ring buffer |
438
+
439
+ Supported levels: `debug` (0), `info` (1), `warn` (2), `error` (3), `emerg` (4).
440
+
441
+ #### HfLogFlusher API
442
+
443
+ | Method | Signature | Description |
444
+ |--------|-----------|-------------|
445
+ | `flusher.flush` | `() => Promise<void>` | Flush all buffered entries to output |
446
+ | `flusher.start` | `(intervalMs?: number) => void` | Start background flush loop (default: `100`ms) |
447
+
448
+ #### Ring Buffer Entry Format
449
+
450
+ Each entry occupies exactly 256 bytes in a 64K-entry (16MB) `SharedArrayBuffer`:
451
+
452
+ | Offset | Size | Field |
453
+ |--------|------|-------|
454
+ | 0-7 | 8 bytes | Timestamp (`BigInt64`, nanosecond precision) |
455
+ | 8 | 1 byte | Level (`0`=debug, `1`=info, `2`=warn, `3`=error, `4`=emerg) |
456
+ | 9-40 | 32 bytes | Scope (fixed-width, padded) |
457
+ | 41-255 | 215 bytes | Message (fixed-width, truncated if longer) |
458
+
459
+ The buffer wraps around at 65,536 entries using bitwise AND masking (`writeIndex & (BUFFER_SIZE - 1)`).
460
+
461
+ > [!WARNING]
462
+ > Pre-encode messages at initialization time using `HfLogger.encodeMessage()`. Calling it in the hot path defeats the zero-allocation purpose because it triggers string encoding on every log call.
463
+
464
+ ### Environment Variables
465
+
466
+ #### Core Configuration
467
+
468
+ | Variable | Default | Description |
469
+ |----------|---------|-------------|
470
+ | `APP_ENV_APPLICATION_NAME` | `APP` | Label prefix shown in all log output |
471
+ | `DEBUG` | `false` | Enable debug-level logging |
472
+ | `NODE_ENV` | _(unset)_ | Must be in `COMMON_ENVS` or unset for debug to activate |
473
+ | `APP_ENV_EXTRA_LOG_ENVS` | _(empty)_ | Comma-separated additional environments to allow debug |
474
+ | `APP_ENV_LOGGER_FORMAT` | `text` | Output format (`json` or `text`) |
475
+ | `APP_ENV_LOGGER_FOLDER_PATH` | `./` | Log files directory |
476
+
477
+ #### File Rotation
478
+
479
+ | Variable | Default | Description |
480
+ |----------|---------|-------------|
481
+ | `APP_ENV_LOGGER_FILE_FREQUENCY` | `1h` | Rotation frequency |
482
+ | `APP_ENV_LOGGER_FILE_MAX_SIZE` | `100m` | Max file size before rotation |
483
+ | `APP_ENV_LOGGER_FILE_MAX_FILES` | `5d` | Retention period |
484
+ | `APP_ENV_LOGGER_FILE_DATE_PATTERN` | `YYYYMMDD_HH` | Date pattern in filename |
485
+
486
+ #### UDP Transport
487
+
488
+ | Variable | Description |
489
+ |----------|-------------|
490
+ | `APP_ENV_LOGGER_DGRAM_HOST` | UDP log aggregator host |
491
+ | `APP_ENV_LOGGER_DGRAM_PORT` | UDP log aggregator port |
492
+ | `APP_ENV_LOGGER_DGRAM_LABEL` | Label to identify log source |
493
+ | `APP_ENV_LOGGER_DGRAM_LEVELS` | Comma-separated levels to send via UDP |
494
+
495
+ #### Example `.env`
496
+
497
+ ```bash
498
+ # Application
499
+ APP_ENV_APPLICATION_NAME=my-service
500
+
501
+ # Core
502
+ DEBUG=true
503
+ APP_ENV_LOGGER_FORMAT=json
504
+ APP_ENV_LOGGER_FOLDER_PATH=./app_data/logs
505
+
506
+ # File rotation
507
+ APP_ENV_LOGGER_FILE_FREQUENCY=24h
508
+ APP_ENV_LOGGER_FILE_MAX_SIZE=500m
509
+ APP_ENV_LOGGER_FILE_MAX_FILES=30d
510
+
511
+ # UDP transport
512
+ APP_ENV_LOGGER_DGRAM_HOST=127.0.0.1
513
+ APP_ENV_LOGGER_DGRAM_PORT=5000
514
+ APP_ENV_LOGGER_DGRAM_LABEL=my-app
515
+ APP_ENV_LOGGER_DGRAM_LEVELS=error,warn,info
516
+ ```
517
+
518
+ ## API Summary
519
+
520
+ | Export | Kind | Description |
521
+ |--------|------|-------------|
522
+ | `Logger` | class | Scoped logger with caching, wraps a Winston logger instance |
523
+ | `ApplicationLogger` | value + type alias | Backward-compatible alias for `Logger` |
524
+ | `LoggerFactory` | class | Factory that creates `Logger` from scope arrays |
525
+ | `HfLogger` | class | Zero-allocation ring-buffer logger |
526
+ | `HfLogFlusher` | class | Background flusher for `HfLogger` |
527
+ | `LogLevels` | class (constants) | Log level constants (`ERROR`, `ALERT`, `EMERG`, `WARN`, `INFO`, `HTTP`, `VERBOSE`, `DEBUG`, `SILLY`) with `isValid()` |
528
+ | `LoggerFormats` | class (constants) | Format constants (`JSON`, `TEXT`) with `isValid()` |
529
+ | `defineCustomLogger` | `(opts: ICustomLoggerOptions) => winston.Logger` | Create a fully configured Winston logger |
530
+ | `defineLogFormatter` | `(opts: { label: string; format?: TLoggerFormat }) => winston.Logform.Format` | Create a formatter (auto-detects format from env) |
531
+ | `defineJsonLoggerFormatter` | `(opts: { label: string }) => winston.Logform.Format` | Create a JSON formatter |
532
+ | `definePrettyLoggerFormatter` | `(opts: { label: string }) => winston.Logform.Format` | Create a pretty text formatter |
533
+ | `applicationLogFormatter` | `winston.Logform.Format` | Pre-built formatter using `APP_ENV_APPLICATION_NAME` label |
534
+ | `applicationLogger` | `winston.Logger` | Pre-built default Winston logger instance |
535
+ | `DgramTransport` | class | Custom Winston transport for UDP logging |
536
+ | `TLogLevel` | type | Union of all log level string literals |
537
+ | `TLoggerFormat` | type | Union of `'json' \| 'text'` |
538
+ | `IFileTransportOptions` | interface | Options for daily-rotating file transport |
539
+ | `ICustomLoggerOptions` | interface | Options for `defineCustomLogger` |
540
+ | `IDgramTransportOptions` | interface | Options for `DgramTransport` |
541
+
542
+ ## Troubleshooting
543
+
544
+ ### Debug logs not appearing
545
+
546
+ **Cause:** Debug logging requires both `DEBUG=true` AND a `NODE_ENV` that is either unset or present in the `COMMON_ENVS` set. These values are pre-computed at module load time.
547
+
548
+ **Fix:**
549
+ 1. Verify `DEBUG=true` is set in your environment.
550
+ 2. Verify `NODE_ENV` is set to one of: `local`, `debug`, `development`, `alpha`, `beta`, `staging`, `production` -- or is unset entirely.
551
+ 3. If you use a custom environment name (e.g. `qa`), add it to `APP_ENV_EXTRA_LOG_ENVS=qa`.
552
+
553
+ ```bash
554
+ DEBUG=true NODE_ENV=development bun run server:dev
555
+ ```
556
+
557
+ ### "[defineLogger] Invalid logger format | format: {format} | valids: json,text"
558
+
559
+ **Cause:** The `format` option passed to `defineLogFormatter` (or the `APP_ENV_LOGGER_FORMAT` environment variable) is not `json` or `text`.
560
+
561
+ **Fix:** Set `APP_ENV_LOGGER_FORMAT` to either `json` or `text`:
562
+
563
+ ```bash
564
+ APP_ENV_LOGGER_FORMAT=text
565
+ ```
566
+
567
+ ### UDP transport not sending logs
568
+
569
+ **Cause:** `DgramTransport.fromPartial()` returns `null` if any required option is missing (`label`, `host`, `port`, `levels` with at least one entry, or `socketOptions`). The transport is silently not registered.
570
+
571
+ **Fix:**
572
+ 1. Ensure **all four** dgram env vars are set: `APP_ENV_LOGGER_DGRAM_HOST`, `APP_ENV_LOGGER_DGRAM_PORT`, `APP_ENV_LOGGER_DGRAM_LABEL`, and `APP_ENV_LOGGER_DGRAM_LEVELS`.
573
+ 2. `APP_ENV_LOGGER_DGRAM_LEVELS` must contain at least one level (e.g. `error,warn,info`). An empty value results in no transport.
574
+ 3. Verify the UDP aggregator is reachable from your host (firewall, port binding).
575
+
576
+ ### Log label shows "APP" instead of application name
577
+
578
+ **Cause:** The default label comes from `Defaults.APPLICATION_NAME`, which reads `APP_ENV_APPLICATION_NAME`. If the env var is not set, it falls back to `'APP'`.
579
+
580
+ **Fix:** Set `APP_ENV_APPLICATION_NAME` in your environment:
581
+
582
+ ```bash
583
+ APP_ENV_APPLICATION_NAME=my-service
584
+ ```
585
+
586
+ ## See Also
587
+
588
+ - **Related Concepts:**
589
+ - [Services](/guides/core-concepts/services) -- Logging in services
590
+ - [Controllers](/guides/core-concepts/controllers) -- Logging in controllers
591
+
592
+ - **Other Helpers:**
593
+ - [Helpers Index](../index) -- All available helpers
594
+
595
+ - **References:**
596
+ - [Request Tracker Component](/references/components/request-tracker) -- Request logging
597
+
598
+ - **External Resources:**
599
+ - [Winston Documentation](https://github.com/winstonjs/winston) -- Winston logging library
600
+ - [winston-daily-rotate-file](https://github.com/winstonjs/winston-daily-rotate-file) -- File rotation transport