@venizia/ignis-docs 0.2.0 → 0.2.1-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.
- package/README.md +14 -14
- package/content/best-practices/api-usage-examples.md +39 -19
- package/content/best-practices/architectural-patterns.md +24 -13
- package/content/best-practices/architecture-decisions.md +29 -16
- package/content/best-practices/code-style-standards/advanced-patterns.md +43 -31
- package/content/best-practices/code-style-standards/constants-configuration.md +19 -4
- package/content/best-practices/code-style-standards/control-flow.md +33 -1
- package/content/best-practices/code-style-standards/documentation.md +28 -8
- package/content/best-practices/code-style-standards/function-patterns.md +15 -4
- package/content/best-practices/code-style-standards/index.md +7 -2
- package/content/best-practices/code-style-standards/naming-conventions.md +27 -3
- package/content/best-practices/code-style-standards/route-definitions.md +9 -5
- package/content/best-practices/code-style-standards/tooling.md +14 -1
- package/content/best-practices/code-style-standards/type-safety.md +39 -6
- package/content/best-practices/common-pitfalls.md +59 -35
- package/content/best-practices/contribution-workflow.md +8 -4
- package/content/best-practices/data-modeling.md +78 -62
- package/content/best-practices/deployment-strategies.md +56 -19
- package/content/best-practices/error-handling.md +247 -153
- package/content/best-practices/index.md +6 -0
- package/content/best-practices/performance-optimization.md +26 -13
- package/content/best-practices/security-guidelines.md +35 -9
- package/content/best-practices/testing-strategies.md +7 -2
- package/content/best-practices/troubleshooting-tips.md +27 -17
- package/content/extensions/components/api-reference.md +109 -323
- package/content/extensions/components/authentication/api.md +489 -602
- package/content/extensions/components/authentication/errors.md +135 -498
- package/content/extensions/components/authentication/index.md +89 -801
- package/content/extensions/components/authentication/usage.md +231 -955
- package/content/extensions/components/authorization/api.md +991 -644
- package/content/extensions/components/authorization/errors.md +204 -208
- package/content/extensions/components/authorization/getting-started.md +227 -0
- package/content/extensions/components/authorization/index.md +88 -795
- package/content/extensions/components/authorization/usage.md +219 -528
- package/content/extensions/components/health-check.md +77 -243
- package/content/extensions/components/index.md +24 -90
- package/content/extensions/components/mail/api.md +553 -285
- package/content/extensions/components/mail/errors.md +76 -62
- package/content/extensions/components/mail/index.md +111 -463
- package/content/extensions/components/mail/usage.md +139 -173
- package/content/extensions/components/request-tracker.md +70 -173
- package/content/extensions/components/socket-io/api.md +462 -785
- package/content/extensions/components/socket-io/errors.md +49 -51
- package/content/extensions/components/socket-io/index.md +69 -372
- package/content/extensions/components/socket-io/usage.md +212 -105
- package/content/extensions/components/static-asset/api.md +461 -141
- package/content/extensions/components/static-asset/errors.md +121 -53
- package/content/extensions/components/static-asset/index.md +84 -606
- package/content/extensions/components/static-asset/usage.md +184 -299
- package/content/extensions/components/template/index.md +3 -3
- package/content/extensions/components/websocket/api.md +311 -404
- package/content/extensions/components/websocket/errors.md +47 -56
- package/content/extensions/components/websocket/index.md +75 -407
- package/content/extensions/components/websocket/usage.md +120 -338
- package/content/extensions/helpers/cron/index.md +52 -160
- package/content/extensions/helpers/crypto/index.md +67 -480
- package/content/extensions/helpers/crypto/reference.md +528 -0
- package/content/extensions/helpers/env/index.md +64 -178
- package/content/extensions/helpers/error/index.md +286 -196
- package/content/extensions/helpers/index.md +61 -47
- package/content/extensions/helpers/inversion/index.md +76 -550
- package/content/extensions/helpers/inversion/reference.md +530 -0
- package/content/extensions/helpers/kafka/admin.md +23 -3
- package/content/extensions/helpers/kafka/compile-binary.md +83 -52
- package/content/extensions/helpers/kafka/consumer.md +65 -28
- package/content/extensions/helpers/kafka/examples.md +46 -253
- package/content/extensions/helpers/kafka/index.md +55 -617
- package/content/extensions/helpers/kafka/producer.md +156 -22
- package/content/extensions/helpers/kafka/schema-registry.md +59 -79
- package/content/extensions/helpers/logger/hf-logger.md +220 -0
- package/content/extensions/helpers/logger/index.md +78 -552
- package/content/extensions/helpers/logger/pino.md +105 -0
- package/content/extensions/helpers/logger/reference.md +937 -0
- package/content/extensions/helpers/network/api.md +276 -195
- package/content/extensions/helpers/network/index.md +87 -524
- package/content/extensions/helpers/queue/index.md +80 -897
- package/content/extensions/helpers/queue/reference.md +494 -0
- package/content/extensions/helpers/redis/index.md +86 -640
- package/content/extensions/helpers/redis/reference.md +784 -0
- package/content/extensions/helpers/secrets/index.md +136 -0
- package/content/extensions/helpers/socket-io/api.md +325 -204
- package/content/extensions/helpers/socket-io/index.md +79 -429
- package/content/extensions/helpers/storage/api.md +584 -464
- package/content/extensions/helpers/storage/index.md +80 -573
- package/content/extensions/helpers/types/index.md +75 -495
- package/content/extensions/helpers/types/reference.md +689 -0
- package/content/extensions/helpers/uid/index.md +176 -189
- package/content/extensions/helpers/websocket/api.md +366 -214
- package/content/extensions/helpers/websocket/index.md +68 -503
- package/content/extensions/helpers/worker-thread/index.md +62 -396
- package/content/extensions/helpers/worker-thread/reference.md +428 -0
- package/content/extensions/index.md +38 -39
- package/content/extensions/src-details/mcp-server.md +96 -548
- package/content/guides/core-concepts/persistent/datasources.md +2 -2
- package/content/guides/core-concepts/persistent/index.md +5 -1
- package/content/guides/core-concepts/persistent/models.md +1 -1
- package/content/guides/core-concepts/persistent/pglite.md +218 -0
- package/content/guides/core-concepts/persistent/postgres-drivers.md +21 -15
- package/content/guides/core-concepts/persistent/search-meilisearch.md +22 -12
- package/content/guides/core-concepts/persistent/search-typesense.md +28 -16
- package/content/guides/core-concepts/persistent/sqlite.md +296 -0
- package/content/guides/core-concepts/persistent/transactions.md +12 -11
- package/content/guides/core-concepts/secrets-vault.md +177 -0
- package/content/guides/core-concepts/services.md +1 -1
- package/content/guides/get-started/5-minute-quickstart.md +59 -206
- package/content/guides/get-started/philosophy.md +135 -670
- package/content/guides/get-started/setup.md +53 -74
- package/content/guides/migrations/redis-helpers-migration.md +5 -4
- package/content/guides/migrations/scoped-rbac-migration.md +5 -5
- package/content/guides/migrations/unified-connectors-migration.md +8 -7
- package/content/guides/tutorials/ecommerce-api.md +3 -8
- package/content/guides/tutorials/realtime-chat.md +1 -1
- package/content/references/base/application.md +64 -22
- package/content/references/base/components.md +3 -3
- package/content/references/base/connectors.md +79 -136
- package/content/references/base/controllers.md +12 -12
- package/content/references/base/datasources-reference.md +600 -0
- package/content/references/base/datasources.md +84 -444
- package/content/references/base/dependency-injection.md +25 -46
- package/content/references/base/filter-system/application-usage.md +95 -123
- package/content/references/base/filter-system/array-operators.md +33 -43
- package/content/references/base/filter-system/comparison-operators.md +55 -63
- package/content/references/base/filter-system/default-filter.md +144 -350
- package/content/references/base/filter-system/fields-order-pagination.md +116 -148
- package/content/references/base/filter-system/index.md +114 -253
- package/content/references/base/filter-system/json-filtering.md +52 -181
- package/content/references/base/filter-system/list-operators.md +28 -44
- package/content/references/base/filter-system/logical-operators.md +69 -114
- package/content/references/base/filter-system/null-operators.md +41 -98
- package/content/references/base/filter-system/pattern-matching.md +48 -51
- package/content/references/base/filter-system/quick-reference.md +93 -196
- package/content/references/base/filter-system/range-operators.md +22 -38
- package/content/references/base/filter-system/tips.md +70 -133
- package/content/references/base/filter-system/use-cases.md +173 -232
- package/content/references/base/grpc-controllers.md +53 -17
- package/content/references/base/index.md +5 -3
- package/content/references/base/middlewares.md +43 -28
- package/content/references/base/models-reference.md +886 -0
- package/content/references/base/models.md +81 -1452
- package/content/references/base/providers.md +8 -8
- package/content/references/base/repositories/advanced.md +281 -419
- package/content/references/base/repositories/index.md +84 -644
- package/content/references/base/repositories/mixins.md +25 -21
- package/content/references/base/repositories/relations.md +194 -375
- package/content/references/base/repositories/soft-deletable.md +67 -55
- package/content/references/base/secrets.md +267 -0
- package/content/references/base/services.md +8 -6
- package/content/references/configuration/environment-variables.md +73 -21
- package/content/references/configuration/index.md +51 -31
- package/content/references/index.md +1 -1
- package/content/references/quick-reference.md +3 -16
- package/content/references/utilities/crypto.md +35 -76
- package/content/references/utilities/date.md +33 -73
- package/content/references/utilities/duration.md +85 -0
- package/content/references/utilities/index.md +6 -2
- package/content/references/utilities/jsx-reference.md +298 -0
- package/content/references/utilities/jsx.md +82 -525
- package/content/references/utilities/module.md +81 -61
- package/content/references/utilities/parse.md +34 -64
- package/content/references/utilities/performance.md +33 -58
- package/content/references/utilities/promise.md +28 -62
- package/content/references/utilities/request.md +58 -218
- package/content/references/utilities/retry.md +139 -0
- package/content/references/utilities/schema.md +43 -137
- package/content/references/utilities/statuses-reference.md +361 -0
- package/content/references/utilities/statuses.md +63 -667
- package/dist/mcp-server/index.js +0 -0
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.js +3 -3
- package/dist/mcp-server/tools/github/search-code.tool.js +1 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js +1 -1
- package/dist/mcp-server/tools/github/view-source-file.tool.js +1 -1
- package/package.json +24 -23
|
@@ -1,173 +1,69 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
|
1
|
+
---
|
|
2
|
+
title: Logger
|
|
3
|
+
description: Scoped, cached logging via LoggerFactory - Winston by default, with console, daily-rotating file, and UDP transports built in
|
|
4
|
+
difficulty: beginner
|
|
5
|
+
---
|
|
16
6
|
|
|
17
|
-
|
|
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
|
-
```
|
|
7
|
+
# Logger
|
|
43
8
|
|
|
44
|
-
|
|
9
|
+
IGNIS gives every helper a scoped `ILogger`. `LoggerFactory` builds it from one registered provider - Winston by default, with console, daily-rotating file, and UDP transports built in.
|
|
45
10
|
|
|
46
|
-
|
|
11
|
+
## In one example
|
|
47
12
|
|
|
48
|
-
|
|
13
|
+
The smallest real use: get a scoped logger and log with it.
|
|
49
14
|
|
|
50
15
|
```typescript
|
|
51
16
|
import { LoggerFactory } from '@venizia/ignis-helpers';
|
|
52
17
|
|
|
53
|
-
const logger = LoggerFactory.getLogger(['
|
|
54
|
-
logger.info('
|
|
55
|
-
// Output: [
|
|
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
|
|
18
|
+
const logger = LoggerFactory.getLogger(['UserService']);
|
|
19
|
+
logger.info('User created');
|
|
20
|
+
// Output: [UserService] User created
|
|
73
21
|
```
|
|
74
22
|
|
|
75
|
-
|
|
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
|
-
});
|
|
23
|
+
`LoggerFactory` is how `BaseHelper` creates its internal logger, so every helper in the framework gets a scoped logger the same way, for free.
|
|
87
24
|
|
|
88
|
-
|
|
89
|
-
```
|
|
25
|
+
## How it works
|
|
90
26
|
|
|
91
|
-
|
|
27
|
+
- **Typed against `ILogger`.** Every consumer - including `BaseHelper.logger` - gets the `ILogger` interface, never a concrete class. Winston is the default provider behind it, selected in `factory.ts`.
|
|
28
|
+
- **Provider-based.** `LoggerFactory.use({ provider })` selects the app's logger engine once, at the entrypoint. Winston is the default; [pino](/extensions/helpers/logger/pino) is the throughput option. Every factory-issued logger follows the registration, even one captured at import time.
|
|
29
|
+
- **Scoped and cached.** `LoggerFactory.getLogger(scopes)` joins the scopes with `-` and caches the result per scope. The same scope always returns the same instance. `BaseHelper` calls this in its constructor, so every helper's `this.logger` comes pre-scoped.
|
|
30
|
+
- **Custom-backed loggers are the exception.** `Logger.get(scope, customWinstonLogger)` (from the `/winston` sub-path) is NOT cached. Each call returns a fresh wrapper over the instance you passed in.
|
|
31
|
+
- **Method scoping.** `.for(methodName)` returns a child logger scoped to `<scope>-<methodName>` (also cached), so each line shows where it came from.
|
|
32
|
+
- **Level floor.** `APP_ENV_LOGGER_LEVEL` (default `debug`) sets the logger-level floor. Transports without their own level inherit it.
|
|
33
|
+
- **`debug()` is gated.** It emits only when `DEBUG=true` and `NODE_ENV` is unset or listed in `Environment.COMMON_ENVS`. Extend that set via `APP_ENV_EXTRA_LOG_ENVS`. The check runs once at module load - runtime env changes need a restart.
|
|
92
34
|
|
|
93
|
-
|
|
35
|
+
**Log levels**
|
|
94
36
|
|
|
95
|
-
|
|
37
|
+
Five levels, each with a direct method: `debug`, `info`, `warn`, `error`, `emerg`. The generic `.log(level, ...)` remains for picking the level dynamically. What each level means, and when to use it, is in the [level guide](/extensions/helpers/logger/reference#what-each-level-means).
|
|
96
38
|
|
|
97
|
-
|
|
98
|
-
const logger1 = Logger.get('MyService');
|
|
99
|
-
const logger2 = Logger.get('MyService');
|
|
100
|
-
// logger1 === logger2 (same instance)
|
|
101
|
-
```
|
|
39
|
+
**Transports**
|
|
102
40
|
|
|
103
|
-
|
|
41
|
+
| Transport | Turns on when |
|
|
42
|
+
|-----------|---------------|
|
|
43
|
+
| Console | Always |
|
|
44
|
+
| Daily-rotating file | `APP_ENV_LOGGER_FOLDER_PATH` is set |
|
|
45
|
+
| UDP (`DgramTransport`) | All four UDP `APP_ENV_LOGGER_DGRAM_*` variables are set |
|
|
104
46
|
|
|
105
|
-
`
|
|
106
|
-
|
|
107
|
-
```typescript
|
|
108
|
-
import { ApplicationLogger } from '@venizia/ignis-helpers';
|
|
47
|
+
Output shape (plain text or JSON) follows `APP_ENV_LOGGER_FORMAT`. Color codes appear only on the console, and only in a development `NODE_ENV` - file and UDP output never carries ANSI escapes. See [Color](./reference#color) to override.
|
|
109
48
|
|
|
110
|
-
|
|
111
|
-
```
|
|
49
|
+
For extreme hot paths, `HfLogger` is a separate ring-buffer logger outside this pipeline, with its own [usage guide](/extensions/helpers/logger/hf-logger). The [Full reference](/extensions/helpers/logger/reference) covers everything else, including the `ApplicationLogger` facade.
|
|
112
50
|
|
|
113
|
-
##
|
|
51
|
+
## Common tasks
|
|
114
52
|
|
|
115
|
-
###
|
|
53
|
+
### Get a scoped logger
|
|
116
54
|
|
|
117
|
-
|
|
55
|
+
Use `LoggerFactory.getLogger` with an array of scope segments, or `ApplicationLogger.get` with a single string. Both cache by scope and follow the registered provider.
|
|
118
56
|
|
|
119
57
|
```typescript
|
|
120
|
-
|
|
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
|
-
```
|
|
58
|
+
import { ApplicationLogger, LoggerFactory } from '@venizia/ignis-helpers';
|
|
127
59
|
|
|
128
|
-
|
|
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';
|
|
60
|
+
const scoped = LoggerFactory.getLogger(['Payment', 'Stripe']); // [Payment-Stripe]
|
|
61
|
+
const direct = ApplicationLogger.get('MyService'); // [MyService]
|
|
148
62
|
```
|
|
149
63
|
|
|
150
|
-
|
|
64
|
+
### Scope logs to a method
|
|
151
65
|
|
|
152
|
-
|
|
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.
|
|
66
|
+
`.for()` appends a method name to the current scope so every line in that method self-identifies.
|
|
171
67
|
|
|
172
68
|
```typescript
|
|
173
69
|
class UserService {
|
|
@@ -176,455 +72,85 @@ class UserService {
|
|
|
176
72
|
async createUser(data: CreateUserDto) {
|
|
177
73
|
this.logger.for('createUser').info('Creating user: %j', data);
|
|
178
74
|
// 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
75
|
}
|
|
189
76
|
}
|
|
190
77
|
```
|
|
191
78
|
|
|
192
|
-
###
|
|
79
|
+
### Log an Error with `%s`, never `%j`
|
|
193
80
|
|
|
194
|
-
`
|
|
81
|
+
`%s` routes the error through `ErrorPrettier`, which projects it down to identity, cause and frames. `%j` keeps every enumerable own property instead, so a driver error takes its whole query along and a `jose` error its whole payload. Always pair an `Error` argument with `%s`.
|
|
195
82
|
|
|
196
83
|
```typescript
|
|
197
|
-
|
|
198
|
-
logger.error('Failed to create user: %s', error);
|
|
199
|
-
|
|
200
|
-
// ❌ Bad - %j drops message and stack (non-enumerable on Error)
|
|
201
|
-
logger.error('Failed to create user: %j', error);
|
|
84
|
+
logger.error('Failed to create user: %s', error); // prints message + stack
|
|
202
85
|
```
|
|
203
86
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
Node hard-codes `depth: 0` for `%s` in `util.format` -- an object passed to `%s` collapses to `[Object]`, hiding the nested `extra` or `cause` a wrapped error carries. IGNIS's formatter (`formatLogMessage`/`deepSplat`) pre-inspects any object bound to a `%s` placeholder before handing the message to Winston, widening that depth so nested fields print instead of collapsing.
|
|
87
|
+
A mistaken `%j` is no longer a silent loss: the formatter projects `message` and `stack` in before `JSON.stringify` runs, which on its own would drop both (they are non-enumerable). It is still the wrong placeholder for an error.
|
|
207
88
|
|
|
208
|
-
|
|
209
|
-
logger.error('Failed: %s', error); // nested `error.cause` is now visible, not `[Object]`
|
|
210
|
-
```
|
|
89
|
+
### Keep a driver error readable with `ErrorPrettier`
|
|
211
90
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
```bash
|
|
215
|
-
APP_ENV_LOGGER_INSPECT_DEPTH=8
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
The value must be a non-negative integer. An absent, empty, negative, or unparseable value falls back to the default of `5` -- there is no "unlimited" setting.
|
|
219
|
-
|
|
220
|
-
### Log Formats
|
|
221
|
-
|
|
222
|
-
The logger supports two output formats, controlled by the `APP_ENV_LOGGER_FORMAT` environment variable (default: `text`).
|
|
223
|
-
|
|
224
|
-
The `LoggerFormats` class provides constants and validation:
|
|
91
|
+
`%s` prints the whole object. A `pg` or `drizzle` failure carries the statement in `message`, again in `stack`, and again in `query` - one failure floods the log with the same SQL several times. Wrap it:
|
|
225
92
|
|
|
226
93
|
```typescript
|
|
227
|
-
import {
|
|
228
|
-
import type { TLoggerFormat } from '@venizia/ignis-helpers';
|
|
229
|
-
|
|
230
|
-
LoggerFormats.JSON; // 'json'
|
|
231
|
-
LoggerFormats.TEXT; // 'text'
|
|
232
|
-
LoggerFormats.isValid('json'); // true
|
|
94
|
+
import { ErrorPrettier } from '@venizia/ignis-helpers';
|
|
233
95
|
|
|
234
|
-
|
|
96
|
+
logger.error('Failed to create user | %s', ErrorPrettier.format({ error }));
|
|
235
97
|
```
|
|
236
98
|
|
|
237
|
-
|
|
99
|
+
You get the identity, the root `cause` with its code, the driver's `hint`, the full message and the top stack frames - each on its own line, with the message's real newlines intact. The duplicated statement and the noisy driver internals are gone.
|
|
238
100
|
|
|
239
|
-
|
|
240
|
-
APP_ENV_LOGGER_FORMAT=json
|
|
241
|
-
```
|
|
101
|
+
Pass `includeStack: false` when the error is one you raised yourself and the frames add nothing. For a JSON sink, `ErrorPrettier.summarize({ error })` returns the same projection as a typed object instead of a string.
|
|
242
102
|
|
|
243
|
-
|
|
103
|
+
### Switch the output format
|
|
244
104
|
|
|
245
|
-
|
|
246
|
-
{"level":"info","message":"[UserService] User created","timestamp":"2024-01-11T10:30:00.000Z","label":"APP"}
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
#### Pretty Text Format (Default)
|
|
105
|
+
`APP_ENV_LOGGER_FORMAT` controls plain text (default) vs. JSON output.
|
|
250
106
|
|
|
251
107
|
```bash
|
|
252
|
-
APP_ENV_LOGGER_FORMAT=text
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
Output:
|
|
256
|
-
|
|
257
|
-
```
|
|
258
|
-
2024-01-11T10:30:00.000Z [APP] info: [UserService] User created
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
> [!NOTE]
|
|
262
|
-
> 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.
|
|
263
|
-
|
|
264
|
-
#### Custom Formatters
|
|
265
|
-
|
|
266
|
-
Build formatters directly using the exported helper functions:
|
|
267
|
-
|
|
268
|
-
```typescript
|
|
269
|
-
import {
|
|
270
|
-
defineLogFormatter,
|
|
271
|
-
defineJsonLoggerFormatter,
|
|
272
|
-
definePrettyLoggerFormatter,
|
|
273
|
-
} from '@venizia/ignis-helpers';
|
|
274
|
-
|
|
275
|
-
// Auto-detect from APP_ENV_LOGGER_FORMAT (or override with format option)
|
|
276
|
-
const formatter = defineLogFormatter({ label: 'my-app' });
|
|
277
|
-
const jsonFmt = defineLogFormatter({ label: 'my-app', format: 'json' });
|
|
278
|
-
|
|
279
|
-
// Or use specific formatters directly
|
|
280
|
-
const jsonFormatter = defineJsonLoggerFormatter({ label: 'my-app' });
|
|
281
|
-
const prettyFormatter = definePrettyLoggerFormatter({ label: 'my-app' });
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
### Transports
|
|
285
|
-
|
|
286
|
-
Every logger created by `defineCustomLogger` always includes a **Console** transport at the `debug` level. File and UDP transports are optional.
|
|
287
|
-
|
|
288
|
-
#### File Rotation (DailyRotateFile)
|
|
289
|
-
|
|
290
|
-
Configure file rotation through environment variables or programmatically via `IFileTransportOptions`.
|
|
291
|
-
|
|
292
|
-
**Environment variables:**
|
|
293
|
-
|
|
294
|
-
| Variable | Default | Description |
|
|
295
|
-
|----------|---------|-------------|
|
|
296
|
-
| `APP_ENV_LOGGER_FOLDER_PATH` | `./` | Log files directory |
|
|
297
|
-
| `APP_ENV_LOGGER_FILE_FREQUENCY` | `1h` | Rotation frequency |
|
|
298
|
-
| `APP_ENV_LOGGER_FILE_MAX_SIZE` | `100m` | Max file size before rotation |
|
|
299
|
-
| `APP_ENV_LOGGER_FILE_MAX_FILES` | `5d` | Retention period |
|
|
300
|
-
| `APP_ENV_LOGGER_FILE_DATE_PATTERN` | `YYYYMMDD_HH` | Date pattern in filename |
|
|
301
|
-
|
|
302
|
-
**Programmatic configuration:**
|
|
303
|
-
|
|
304
|
-
```typescript
|
|
305
|
-
import { defineCustomLogger, applicationLogFormatter } from '@venizia/ignis-helpers';
|
|
306
|
-
|
|
307
|
-
const customLogger = defineCustomLogger({
|
|
308
|
-
loggerFormatter: applicationLogFormatter,
|
|
309
|
-
transports: {
|
|
310
|
-
info: {
|
|
311
|
-
file: {
|
|
312
|
-
prefix: 'my-app',
|
|
313
|
-
folder: './logs',
|
|
314
|
-
frequency: '24h',
|
|
315
|
-
maxSize: '500m',
|
|
316
|
-
maxFiles: '30d',
|
|
317
|
-
datePattern: 'YYYYMMDD',
|
|
318
|
-
},
|
|
319
|
-
},
|
|
320
|
-
error: {
|
|
321
|
-
file: {
|
|
322
|
-
prefix: 'my-app-error',
|
|
323
|
-
folder: './logs',
|
|
324
|
-
maxFiles: '90d',
|
|
325
|
-
},
|
|
326
|
-
},
|
|
327
|
-
},
|
|
328
|
-
});
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
Generated filename pattern: `{folder}/{prefix}-info-{DATE}.log` or `{folder}/{prefix}-error-{DATE}.log`.
|
|
332
|
-
|
|
333
|
-
#### IFileTransportOptions
|
|
334
|
-
|
|
335
|
-
```typescript
|
|
336
|
-
interface IFileTransportOptions {
|
|
337
|
-
prefix: string; // Filename prefix (required)
|
|
338
|
-
folder: string; // Output directory (required)
|
|
339
|
-
frequency?: string; // Rotation frequency (default: '1h')
|
|
340
|
-
maxSize?: string; // Max file size (default: '100m')
|
|
341
|
-
maxFiles?: string; // Retention period (default: '5d')
|
|
342
|
-
datePattern?: string; // Date pattern in filename (default: 'YYYYMMDD_HH')
|
|
343
|
-
}
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
#### UDP Transport (DgramTransport)
|
|
347
|
-
|
|
348
|
-
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.
|
|
349
|
-
|
|
350
|
-
```typescript
|
|
351
|
-
import { DgramTransport } from '@venizia/ignis-helpers';
|
|
352
|
-
|
|
353
|
-
const transport = new DgramTransport({
|
|
354
|
-
label: 'my-app',
|
|
355
|
-
host: '127.0.0.1',
|
|
356
|
-
port: 5000,
|
|
357
|
-
levels: ['error', 'warn', 'info'],
|
|
358
|
-
socketOptions: { type: 'udp4' },
|
|
359
|
-
});
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
**Static factory with validation** -- returns `null` if any required field is missing:
|
|
363
|
-
|
|
364
|
-
```typescript
|
|
365
|
-
const transport = DgramTransport.fromPartial({
|
|
366
|
-
label: 'my-app',
|
|
367
|
-
host: '127.0.0.1',
|
|
368
|
-
port: 5000,
|
|
369
|
-
levels: ['error', 'warn'],
|
|
370
|
-
socketOptions: { type: 'udp4' },
|
|
371
|
-
});
|
|
372
|
-
// Returns null if label, host, port, levels (non-empty), or socketOptions is missing
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
The transport automatically re-establishes the UDP socket if it encounters an error.
|
|
376
|
-
|
|
377
|
-
**Environment variables for the default application logger:**
|
|
378
|
-
|
|
379
|
-
| Variable | Description |
|
|
380
|
-
|----------|-------------|
|
|
381
|
-
| `APP_ENV_LOGGER_DGRAM_HOST` | UDP log aggregator host |
|
|
382
|
-
| `APP_ENV_LOGGER_DGRAM_PORT` | UDP log aggregator port |
|
|
383
|
-
| `APP_ENV_LOGGER_DGRAM_LABEL` | Label to identify log source |
|
|
384
|
-
| `APP_ENV_LOGGER_DGRAM_LEVELS` | Comma-separated levels to send via UDP |
|
|
385
|
-
|
|
386
|
-
#### IDgramTransportOptions
|
|
387
|
-
|
|
388
|
-
```typescript
|
|
389
|
-
interface IDgramTransportOptions extends Transport.TransportStreamOptions {
|
|
390
|
-
label: string; // Label to identify log source
|
|
391
|
-
host: string; // UDP host
|
|
392
|
-
port: number; // UDP port
|
|
393
|
-
levels: Array<string>; // Levels to forward over UDP
|
|
394
|
-
socketOptions: dgram.SocketOptions; // Node.js dgram socket options
|
|
395
|
-
}
|
|
396
|
-
```
|
|
397
|
-
|
|
398
|
-
#### ICustomLoggerOptions
|
|
399
|
-
|
|
400
|
-
```typescript
|
|
401
|
-
interface ICustomLoggerOptions {
|
|
402
|
-
logLevels?: { [name: string | symbol]: number };
|
|
403
|
-
logColors?: { [name: string | symbol]: string };
|
|
404
|
-
loggerFormatter?: ReturnType<typeof winston.format.combine>;
|
|
405
|
-
transports: {
|
|
406
|
-
info: {
|
|
407
|
-
file?: IFileTransportOptions;
|
|
408
|
-
dgram?: Partial<IDgramTransportOptions>;
|
|
409
|
-
};
|
|
410
|
-
error: {
|
|
411
|
-
file?: IFileTransportOptions;
|
|
412
|
-
dgram?: Partial<IDgramTransportOptions>;
|
|
413
|
-
};
|
|
414
|
-
};
|
|
415
|
-
}
|
|
108
|
+
APP_ENV_LOGGER_FORMAT=text # 2024-01-11T10:30:00.000Z [APP] info: [UserService] User created
|
|
109
|
+
APP_ENV_LOGGER_FORMAT=json # {"level":"info","message":"[UserService] User created", ...}
|
|
416
110
|
```
|
|
417
111
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
### Debug Logging Behavior
|
|
112
|
+
The `[APP]` label comes from `APP_ENV_APPLICATION_NAME` (defaults to `'APP'`).
|
|
421
113
|
|
|
422
|
-
|
|
114
|
+
### Enable daily file rotation
|
|
423
115
|
|
|
424
|
-
|
|
425
|
-
2. `NODE_ENV` is either unset **or** is present in the `Environment.COMMON_ENVS` set
|
|
426
|
-
|
|
427
|
-
The `COMMON_ENVS` set includes: `local`, `debug`, `development`, `dev`, `sit`, `uat`, `alpha`, `beta`, `staging`, `production`. You can extend this set with `APP_ENV_EXTRA_LOG_ENVS`:
|
|
116
|
+
Point `APP_ENV_LOGGER_FOLDER_PATH` at a directory. Rotation frequency, size cap, and retention are also env-driven. Without this variable, no log files are written - console (and UDP, if configured) remain the only outputs.
|
|
428
117
|
|
|
429
118
|
```bash
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
APP_ENV_EXTRA_LOG_ENVS=qa,preview # Comma-separated additional environments
|
|
433
|
-
```
|
|
434
|
-
|
|
435
|
-
> [!IMPORTANT]
|
|
436
|
-
> 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.
|
|
437
|
-
|
|
438
|
-
### High-Frequency Logger (HfLogger)
|
|
439
|
-
|
|
440
|
-
For performance-critical applications (e.g., HFT systems, game servers), `HfLogger` provides zero-allocation logging via a lock-free ring buffer backed by `SharedArrayBuffer`.
|
|
441
|
-
|
|
442
|
-
```typescript
|
|
443
|
-
import { HfLogger, HfLogFlusher } from '@venizia/ignis-helpers';
|
|
444
|
-
|
|
445
|
-
// At initialization time (once):
|
|
446
|
-
const logger = HfLogger.get('OrderEngine');
|
|
447
|
-
const MSG_ORDER_SENT = HfLogger.encodeMessage('Order sent');
|
|
448
|
-
const MSG_ORDER_FILLED = HfLogger.encodeMessage('Order filled');
|
|
449
|
-
|
|
450
|
-
// Start background flusher
|
|
451
|
-
const flusher = new HfLogFlusher();
|
|
452
|
-
flusher.start(100); // Flush every 100ms
|
|
453
|
-
|
|
454
|
-
// In hot path (~100-300ns, zero allocation):
|
|
455
|
-
logger.log('info', MSG_ORDER_SENT);
|
|
456
|
-
logger.log('info', MSG_ORDER_FILLED);
|
|
119
|
+
APP_ENV_LOGGER_FOLDER_PATH=./app_data/logs
|
|
120
|
+
APP_ENV_LOGGER_FILE_MAX_FILES=30d
|
|
457
121
|
```
|
|
458
122
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
|
462
|
-
|
|
463
|
-
|
|
|
464
|
-
| `HfLogger.encodeMessage` | `(msg: string) => Uint8Array` | Pre-encode a message string to bytes (cached) |
|
|
465
|
-
| `logger.log` | `(level: THfLogLevel, messageBytes: Uint8Array) => void` | Write entry to ring buffer |
|
|
466
|
-
|
|
467
|
-
Supported levels: `debug` (0), `info` (1), `warn` (2), `error` (3), `emerg` (4).
|
|
123
|
+
| Setting | Default |
|
|
124
|
+
|---|---|
|
|
125
|
+
| Rotation frequency | `1h` |
|
|
126
|
+
| Max file size | `100m` |
|
|
127
|
+
| Retention | `5d` |
|
|
468
128
|
|
|
469
|
-
|
|
129
|
+
Full programmatic configuration - custom prefixes, custom retention - is in the [Full reference](/extensions/helpers/logger/reference).
|
|
470
130
|
|
|
471
|
-
|
|
472
|
-
|--------|-----------|-------------|
|
|
473
|
-
| `flusher.flush` | `() => Promise<void>` | Flush all buffered entries to output |
|
|
474
|
-
| `flusher.start` | `(intervalMs?: number) => void` | Start background flush loop (default: `100`ms) |
|
|
131
|
+
### Forward logs over UDP
|
|
475
132
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
Each entry occupies exactly 256 bytes in a 64K-entry (16MB) `SharedArrayBuffer`:
|
|
479
|
-
|
|
480
|
-
| Offset | Size | Field |
|
|
481
|
-
|--------|------|-------|
|
|
482
|
-
| 0-7 | 8 bytes | Timestamp (`BigInt64`, nanosecond precision) |
|
|
483
|
-
| 8 | 1 byte | Level (`0`=debug, `1`=info, `2`=warn, `3`=error, `4`=emerg) |
|
|
484
|
-
| 9-40 | 32 bytes | Scope (fixed-width, padded) |
|
|
485
|
-
| 41-255 | 215 bytes | Message (fixed-width, truncated if longer) |
|
|
486
|
-
|
|
487
|
-
The buffer wraps around at 65,536 entries using bitwise AND masking (`writeIndex & (BUFFER_SIZE - 1)`).
|
|
488
|
-
|
|
489
|
-
> [!WARNING]
|
|
490
|
-
> 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.
|
|
491
|
-
|
|
492
|
-
### Environment Variables
|
|
493
|
-
|
|
494
|
-
#### Core Configuration
|
|
495
|
-
|
|
496
|
-
| Variable | Default | Description |
|
|
497
|
-
|----------|---------|-------------|
|
|
498
|
-
| `APP_ENV_APPLICATION_NAME` | `APP` | Label prefix shown in all log output |
|
|
499
|
-
| `DEBUG` | `false` | Enable debug-level logging |
|
|
500
|
-
| `NODE_ENV` | _(unset)_ | Must be in `COMMON_ENVS` or unset for debug to activate |
|
|
501
|
-
| `APP_ENV_EXTRA_LOG_ENVS` | _(empty)_ | Comma-separated additional environments to allow debug |
|
|
502
|
-
| `APP_ENV_LOGGER_FORMAT` | `text` | Output format (`json` or `text`) |
|
|
503
|
-
| `APP_ENV_LOGGER_FOLDER_PATH` | `./` | Log files directory |
|
|
504
|
-
| `APP_ENV_LOGGER_INSPECT_DEPTH` | `5` | Object inspection depth for `%s` placeholders. Non-negative integer only; invalid or absent falls back to `5` |
|
|
505
|
-
|
|
506
|
-
#### File Rotation
|
|
507
|
-
|
|
508
|
-
| Variable | Default | Description |
|
|
509
|
-
|----------|---------|-------------|
|
|
510
|
-
| `APP_ENV_LOGGER_FILE_FREQUENCY` | `1h` | Rotation frequency |
|
|
511
|
-
| `APP_ENV_LOGGER_FILE_MAX_SIZE` | `100m` | Max file size before rotation |
|
|
512
|
-
| `APP_ENV_LOGGER_FILE_MAX_FILES` | `5d` | Retention period |
|
|
513
|
-
| `APP_ENV_LOGGER_FILE_DATE_PATTERN` | `YYYYMMDD_HH` | Date pattern in filename |
|
|
514
|
-
|
|
515
|
-
#### UDP Transport
|
|
516
|
-
|
|
517
|
-
| Variable | Description |
|
|
518
|
-
|----------|-------------|
|
|
519
|
-
| `APP_ENV_LOGGER_DGRAM_HOST` | UDP log aggregator host |
|
|
520
|
-
| `APP_ENV_LOGGER_DGRAM_PORT` | UDP log aggregator port |
|
|
521
|
-
| `APP_ENV_LOGGER_DGRAM_LABEL` | Label to identify log source |
|
|
522
|
-
| `APP_ENV_LOGGER_DGRAM_LEVELS` | Comma-separated levels to send via UDP |
|
|
523
|
-
|
|
524
|
-
#### Example `.env`
|
|
133
|
+
Set all four `APP_ENV_LOGGER_DGRAM_*` variables - the transport is silently skipped if any one is missing.
|
|
525
134
|
|
|
526
135
|
```bash
|
|
527
|
-
# Application
|
|
528
|
-
APP_ENV_APPLICATION_NAME=my-service
|
|
529
|
-
|
|
530
|
-
# Core
|
|
531
|
-
DEBUG=true
|
|
532
|
-
APP_ENV_LOGGER_FORMAT=json
|
|
533
|
-
APP_ENV_LOGGER_FOLDER_PATH=./app_data/logs
|
|
534
|
-
APP_ENV_LOGGER_INSPECT_DEPTH=5
|
|
535
|
-
|
|
536
|
-
# File rotation
|
|
537
|
-
APP_ENV_LOGGER_FILE_FREQUENCY=24h
|
|
538
|
-
APP_ENV_LOGGER_FILE_MAX_SIZE=500m
|
|
539
|
-
APP_ENV_LOGGER_FILE_MAX_FILES=30d
|
|
540
|
-
|
|
541
|
-
# UDP transport
|
|
542
136
|
APP_ENV_LOGGER_DGRAM_HOST=127.0.0.1
|
|
543
137
|
APP_ENV_LOGGER_DGRAM_PORT=5000
|
|
544
138
|
APP_ENV_LOGGER_DGRAM_LABEL=my-app
|
|
545
139
|
APP_ENV_LOGGER_DGRAM_LEVELS=error,warn,info
|
|
546
140
|
```
|
|
547
141
|
|
|
548
|
-
##
|
|
549
|
-
|
|
550
|
-
| Export | Kind | Description |
|
|
551
|
-
|--------|------|-------------|
|
|
552
|
-
| `Logger` | class | Scoped logger with caching, wraps a Winston logger instance |
|
|
553
|
-
| `ApplicationLogger` | value + type alias | Backward-compatible alias for `Logger` |
|
|
554
|
-
| `LoggerFactory` | class | Factory that creates `Logger` from scope arrays |
|
|
555
|
-
| `HfLogger` | class | Zero-allocation ring-buffer logger |
|
|
556
|
-
| `HfLogFlusher` | class | Background flusher for `HfLogger` |
|
|
557
|
-
| `LogLevels` | class (constants) | Log level constants (`ERROR`, `ALERT`, `EMERG`, `WARN`, `INFO`, `HTTP`, `VERBOSE`, `DEBUG`, `SILLY`) with `isValid()` |
|
|
558
|
-
| `LoggerFormats` | class (constants) | Format constants (`JSON`, `TEXT`) with `isValid()` |
|
|
559
|
-
| `defineCustomLogger` | `(opts: ICustomLoggerOptions) => winston.Logger` | Create a fully configured Winston logger |
|
|
560
|
-
| `defineLogFormatter` | `(opts: { label: string; format?: TLoggerFormat }) => winston.Logform.Format` | Create a formatter (auto-detects format from env) |
|
|
561
|
-
| `defineJsonLoggerFormatter` | `(opts: { label: string }) => winston.Logform.Format` | Create a JSON formatter |
|
|
562
|
-
| `definePrettyLoggerFormatter` | `(opts: { label: string }) => winston.Logform.Format` | Create a pretty text formatter |
|
|
563
|
-
| `applicationLogFormatter` | `winston.Logform.Format` | Pre-built formatter using `APP_ENV_APPLICATION_NAME` label |
|
|
564
|
-
| `applicationLogger` | `winston.Logger` | Pre-built default Winston logger instance |
|
|
565
|
-
| `DgramTransport` | class | Custom Winston transport for UDP logging |
|
|
566
|
-
| `TLogLevel` | type | Union of all log level string literals |
|
|
567
|
-
| `TLoggerFormat` | type | Union of `'json' \| 'text'` |
|
|
568
|
-
| `IFileTransportOptions` | interface | Options for daily-rotating file transport |
|
|
569
|
-
| `ICustomLoggerOptions` | interface | Options for `defineCustomLogger` |
|
|
570
|
-
| `IDgramTransportOptions` | interface | Options for `DgramTransport` |
|
|
571
|
-
|
|
572
|
-
## Troubleshooting
|
|
573
|
-
|
|
574
|
-
### Debug logs not appearing
|
|
575
|
-
|
|
576
|
-
**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.
|
|
577
|
-
|
|
578
|
-
**Fix:**
|
|
579
|
-
1. Verify `DEBUG=true` is set in your environment.
|
|
580
|
-
2. Verify `NODE_ENV` is set to one of: `local`, `debug`, `development`, `dev`, `sit`, `uat`, `alpha`, `beta`, `staging`, `production` -- or is unset entirely.
|
|
581
|
-
3. If you use a custom environment name (e.g. `qa`), add it to `APP_ENV_EXTRA_LOG_ENVS=qa`.
|
|
582
|
-
|
|
583
|
-
```bash
|
|
584
|
-
DEBUG=true NODE_ENV=development bun run server:dev
|
|
585
|
-
```
|
|
586
|
-
|
|
587
|
-
### "[defineLogger] Invalid logger format | format: {format} | valids: json,text"
|
|
588
|
-
|
|
589
|
-
**Cause:** The `format` option passed to `defineLogFormatter` (or the `APP_ENV_LOGGER_FORMAT` environment variable) is not `json` or `text`.
|
|
590
|
-
|
|
591
|
-
**Fix:** Set `APP_ENV_LOGGER_FORMAT` to either `json` or `text`:
|
|
592
|
-
|
|
593
|
-
```bash
|
|
594
|
-
APP_ENV_LOGGER_FORMAT=text
|
|
595
|
-
```
|
|
596
|
-
|
|
597
|
-
### UDP transport not sending logs
|
|
598
|
-
|
|
599
|
-
**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.
|
|
600
|
-
|
|
601
|
-
**Fix:**
|
|
602
|
-
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`.
|
|
603
|
-
2. `APP_ENV_LOGGER_DGRAM_LEVELS` must contain at least one level (e.g. `error,warn,info`). An empty value results in no transport.
|
|
604
|
-
3. Verify the UDP aggregator is reachable from your host (firewall, port binding).
|
|
605
|
-
|
|
606
|
-
### Log label shows "APP" instead of application name
|
|
607
|
-
|
|
608
|
-
**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'`.
|
|
609
|
-
|
|
610
|
-
**Fix:** Set `APP_ENV_APPLICATION_NAME` in your environment:
|
|
611
|
-
|
|
612
|
-
```bash
|
|
613
|
-
APP_ENV_APPLICATION_NAME=my-service
|
|
614
|
-
```
|
|
615
|
-
|
|
616
|
-
## See Also
|
|
617
|
-
|
|
618
|
-
- **Related Concepts:**
|
|
619
|
-
- [Services](/guides/core-concepts/services) -- Logging in services
|
|
620
|
-
- [Controllers](/guides/core-concepts/rest-controllers) -- Logging in controllers
|
|
142
|
+
## See also
|
|
621
143
|
|
|
622
|
-
-
|
|
623
|
-
|
|
144
|
+
- [Full reference](/extensions/helpers/logger/reference) - every export, transport option, log level, and edge case
|
|
145
|
+
- [Services](/guides/core-concepts/services) - logging in services
|
|
146
|
+
- [Controllers](/guides/core-concepts/rest-controllers) - logging in controllers
|
|
147
|
+
- [Helpers Overview](/extensions/helpers/) - all available helpers
|
|
148
|
+
- [Request Tracker Component](/extensions/components/request-tracker) - request logging
|
|
149
|
+
- [Winston documentation](https://github.com/winstonjs/winston) - underlying logging library
|
|
624
150
|
|
|
625
|
-
|
|
626
|
-
- [Request Tracker Component](/extensions/components/request-tracker) -- Request logging
|
|
151
|
+
**Files:**
|
|
627
152
|
|
|
628
|
-
-
|
|
629
|
-
|
|
630
|
-
|
|
153
|
+
- [`packages/helpers/src/modules/logger/common/types.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/logger/common/types.ts) - `ILogger`, the contract every consumer types against
|
|
154
|
+
- [`packages/helpers/src/modules/logger/winston/logger.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/logger/winston/logger.ts) - `WinstonLogger`, `Logger` alias
|
|
155
|
+
- [`packages/helpers/src/modules/logger/factory.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/logger/factory.ts) - `LoggerFactory`, `ApplicationLogger`
|
|
156
|
+
- [`packages/helpers/src/modules/logger/winston/define.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/logger/winston/define.ts) - Winston setup, transports, env configuration
|