@decaf-ts/logging 0.3.6 → 0.3.7
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 +223 -307
- package/dist/logging.cjs +87 -25
- package/dist/logging.esm.cjs +87 -26
- package/lib/LoggedClass.cjs +39 -1
- package/lib/LoggedClass.d.ts +38 -0
- package/lib/constants.cjs +2 -1
- package/lib/constants.d.ts +1 -0
- package/lib/decorators.cjs +11 -7
- package/lib/decorators.d.ts +13 -8
- package/lib/esm/LoggedClass.d.ts +38 -0
- package/lib/esm/LoggedClass.js +39 -1
- package/lib/esm/constants.d.ts +1 -0
- package/lib/esm/constants.js +2 -1
- package/lib/esm/decorators.d.ts +13 -8
- package/lib/esm/decorators.js +11 -7
- package/lib/esm/index.d.ts +8 -2
- package/lib/esm/index.js +9 -3
- package/lib/esm/logging.d.ts +8 -17
- package/lib/esm/logging.js +23 -17
- package/lib/esm/types.d.ts +15 -0
- package/lib/esm/types.js +1 -1
- package/lib/index.cjs +9 -3
- package/lib/index.d.ts +8 -2
- package/lib/logging.cjs +23 -17
- package/lib/logging.d.ts +8 -17
- package/lib/types.cjs +1 -1
- package/lib/types.d.ts +15 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
<!-- AUTO-GENERATED: logging/workdocs/1-Header.md -->
|
|
2
|
+
# Logging Library (decaf-ts/logging)
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
A small, flexible TypeScript logging library designed for framework-agnostic projects. It provides:
|
|
5
|
+
- Context-aware loggers with hierarchical contexts (class.method) via MiniLogger and the static Logging facade.
|
|
6
|
+
- Configurable output (level filtering, verbosity, separators, timestamps) and optional ANSI styling/theming.
|
|
7
|
+
- Simple method decorators (log/debug/info/verbose/silly) to instrument class methods without boilerplate.
|
|
8
|
+
- Extensibility through a pluggable LoggerFactory (e.g., WinstonLogger) while keeping a minimal default runtime.
|
|
6
9
|
|
|
7
10
|
|
|
8
11
|

|
|
@@ -34,377 +37,290 @@ A comprehensive, flexible, and type-safe logging library for TypeScript applicat
|
|
|
34
37
|
|
|
35
38
|
Documentation available [here](https://decaf-ts.github.io/logging/)
|
|
36
39
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
40
|
+
# Logging Library — Detailed Description
|
|
41
|
+
|
|
42
|
+
The logging package is a lightweight, extensible logging solution for TypeScript projects. It centers on two main constructs:
|
|
43
|
+
- MiniLogger — a minimal, context-aware logger used by default.
|
|
44
|
+
- Logging — a static facade that manages global configuration, creates loggers for classes/functions/strings, and applies optional theming.
|
|
45
|
+
|
|
46
|
+
It also offers:
|
|
47
|
+
- A concise set of decorators (log, debug, info, verbose, silly) to instrument methods with consistent logging and optional benchmarking.
|
|
48
|
+
- Pluggable factories so that alternate implementations (e.g., WinstonLogger) can be used without changing call sites.
|
|
49
|
+
- Strong typing for configuration and theming primitives.
|
|
50
|
+
|
|
51
|
+
Core files and their roles
|
|
52
|
+
- src/types.ts: Type definitions and contracts
|
|
53
|
+
- Logger: the runtime contract with methods silly, verbose, info, debug, error, for, setConfig.
|
|
54
|
+
- LoggingConfig: runtime configuration for filtering, formatting, and styling.
|
|
55
|
+
- LoggerFactory: factory signature returning a Logger for a given context and optional config.
|
|
56
|
+
- Theme/ThemeOption/ThemeOptionByLogLevel: shape of color and style configuration, optionally varying by LogLevel.
|
|
57
|
+
- Additional helpers: StringLike, AnyFunction, Class, LoggingContext.
|
|
58
|
+
|
|
59
|
+
- src/constants.ts: Defaults and enums
|
|
60
|
+
- LogLevel: error | info | verbose | debug | silly (string values), plus NumericLogLevels for filtering.
|
|
61
|
+
- LoggingMode: RAW | JSON (current implementation focuses on RAW; JSON is available for adapters like Winston).
|
|
62
|
+
- DefaultTheme: sensible default colors/styles per component and per log level.
|
|
63
|
+
- DefaultLoggingConfig: default global configuration (info level, no styling, timestamp on, etc.).
|
|
64
|
+
|
|
65
|
+
- src/logging.ts: Implementations and static facade
|
|
66
|
+
- MiniLogger: A small, dependency-light logger that:
|
|
67
|
+
- Generates formatted log strings (timestamp, log level, context, correlation id, message, stack) according to config.
|
|
68
|
+
- Supports child loggers via .for(method|config) with a Proxy to overlay per-child config and extend the context (class.method).
|
|
69
|
+
- Emits to console.log/console.debug/console.error based on level. Verbosity controls .silly output (gated by config.verbose).
|
|
70
|
+
- Logging: The static entry point that:
|
|
71
|
+
- Holds global configuration (Logging.getConfig(), Logging.setConfig()).
|
|
72
|
+
- Creates loggers for arbitrary contexts (Logging.for(object|class|function|string, config?)).
|
|
73
|
+
- Provides convenience static logging methods (info, debug, error, verbose, silly) delegating to a global logger instance.
|
|
74
|
+
- Supports theming (Logging.theme) by applying Theme options through styled-string-builder when style=true.
|
|
75
|
+
- Allows replacing the logger factory (Logging.setFactory) to integrate with other backends (e.g., Winston).
|
|
76
|
+
|
|
77
|
+
- src/decorators.ts: Method decorators
|
|
78
|
+
- log(level=info, benchmark=false, verbosity=0): wraps a method to emit a call log and optionally a completion time; supports Promise-returning methods.
|
|
79
|
+
- debug/info/silly/verbose: concise wrappers around log() for common patterns.
|
|
80
|
+
|
|
81
|
+
- src/LoggedClass.ts: Base convenience class
|
|
82
|
+
- LoggedClass exposes a protected this.log getter returning a context-aware Logger built via Logging.for(this), simplifying logging inside class methods.
|
|
83
|
+
|
|
84
|
+
- src/winston/winston.ts: Optional Winston adapter
|
|
85
|
+
- WinstonLogger: extends MiniLogger but delegates emission to a configured Winston instance.
|
|
86
|
+
- WinstonFactory: a LoggerFactory you can install with Logging.setFactory(WinstonFactory) to globally route logs through Winston.
|
|
87
|
+
|
|
88
|
+
Design principles
|
|
89
|
+
- Minimal by default: Console output with small surface area and no heavy dependencies (except styled-string-builder when style is enabled).
|
|
90
|
+
- Config-driven: Behavior (level thresholds, verbosity, timestamps, separators, theming) is controlled via LoggingConfig.
|
|
91
|
+
- Context-first: Log context is explicit ("MyClass" or "MyClass.method"), aiding filtering and debugging.
|
|
92
|
+
- Extensible: Swap logger implementations via a factory; MiniLogger serves as a reference implementation.
|
|
93
|
+
- Safe theming: Logging.theme guards against invalid theme keys and values and logs errors instead of throwing.
|
|
94
|
+
|
|
95
|
+
Key behaviors
|
|
96
|
+
- Level filtering: NumericLogLevels are used to compare configured level with the message level and decide emission.
|
|
97
|
+
- Verbosity: .silly obeys LoggingConfig.verbose; only messages with <= configured verbosity are emitted.
|
|
98
|
+
- Theming and styling: When style=true, Logging.theme applies Theme rules per component (class, message, logLevel, id, stack, timestamp). Theme can vary per LogLevel via ThemeOptionByLogLevel.
|
|
99
|
+
- Correlation IDs: If correlationId is configured in a logger or child logger, it is included in output for easier traceability.
|
|
100
|
+
|
|
101
|
+
Public API surface
|
|
102
|
+
- Classes: MiniLogger, Logging, LoggedClass; WinstonLogger (optional).
|
|
103
|
+
- Decorators: log, debug, info, verbose, silly.
|
|
104
|
+
- Enums/Consts: LogLevel, LoggingMode, NumericLogLevels, DefaultTheme, DefaultLoggingConfig.
|
|
105
|
+
- Types: Logger, LoggingConfig, LoggerFactory, Theme, ThemeOption, ThemeOptionByLogLevel, LoggingContext.
|
|
106
|
+
|
|
107
|
+
Intended usage
|
|
108
|
+
- Use Logging.setConfig() at application startup to set level/style/timestamps.
|
|
109
|
+
- Create class- or method-scoped loggers via Logging.for(MyClass) or logger.for('method').
|
|
110
|
+
- Adopt LoggedClass to remove boilerplate in classes.
|
|
111
|
+
- Add decorators to methods for automatic call/benchmark logs.
|
|
112
|
+
- For advanced deployments, swap to WinstonFactory.
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
# How to Use the Logging Library
|
|
116
|
+
|
|
117
|
+
This guide provides concise, non-redundant examples for each public API. Examples are inspired by the package’s unit tests and reflect real usage.
|
|
118
|
+
|
|
119
|
+
Note: Replace the import path with your actual package name. In this monorepo, tests import from "../../src".
|
|
120
|
+
|
|
121
|
+
- import { ... } from "@your-scope/logging" // typical
|
|
122
|
+
- import { ... } from "../../src" // inside this repo while developing
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
Basic setup and global logging via Logging
|
|
126
|
+
Description: Configure global logging and write messages through the static facade, similar to unit tests that verify console output and level filtering.
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
import { Logging, LogLevel } from "@decaf-ts/logging";
|
|
130
|
+
|
|
131
|
+
// Set global configuration
|
|
132
|
+
Logging.setConfig({
|
|
133
|
+
level: LogLevel.debug, // allow debug and above
|
|
134
|
+
style: false, // plain output (tests use both styled and themeless)
|
|
135
|
+
timestamp: false, // omit timestamp for simplicity in this example
|
|
136
|
+
});
|
|
102
137
|
|
|
103
|
-
|
|
104
|
-
|
|
138
|
+
// Log using the global logger
|
|
139
|
+
Logging.info("Application started");
|
|
140
|
+
Logging.debug("Debug details");
|
|
141
|
+
Logging.error("Something went wrong");
|
|
105
142
|
|
|
106
|
-
|
|
107
|
-
|
|
143
|
+
// Verbosity-controlled logs (silly delegates to verbose internally)
|
|
144
|
+
Logging.setConfig({ verbose: 2 });
|
|
145
|
+
Logging.silly("Extra details at verbosity 1"); // emitted when verbose >= 1
|
|
146
|
+
Logging.verbose("Even more details", 2); // only with verbose >= 2
|
|
147
|
+
```
|
|
108
148
|
|
|
109
|
-
4. **Decorator-Based Logging**:
|
|
110
|
-
Using method decorators to automatically log method calls and execution times.
|
|
111
149
|
|
|
112
|
-
|
|
113
|
-
|
|
150
|
+
Create a class-scoped logger and child method logger
|
|
151
|
+
Description: Create a logger bound to a specific context (class) and derive a child logger for a method, matching patterns used in tests.
|
|
114
152
|
|
|
115
|
-
|
|
153
|
+
```ts
|
|
154
|
+
import { Logging, LogLevel } from "@decaf-ts/logging";
|
|
116
155
|
|
|
156
|
+
Logging.setConfig({ level: LogLevel.debug });
|
|
117
157
|
|
|
118
|
-
|
|
158
|
+
// A class-scoped logger
|
|
159
|
+
const classLogger = Logging.for("UserService");
|
|
160
|
+
classLogger.info("Fetching users");
|
|
119
161
|
|
|
120
|
-
|
|
121
|
-
|
|
162
|
+
// A child logger for a specific method with temporary config overrides
|
|
163
|
+
const methodLogger = classLogger.for("list", { style: false });
|
|
164
|
+
methodLogger.debug("Querying repository...");
|
|
165
|
+
```
|
|
122
166
|
|
|
123
|
-
## Basic Usage
|
|
124
167
|
|
|
125
|
-
|
|
168
|
+
MiniLogger: direct use and per-instance config
|
|
169
|
+
Description: Instantiate MiniLogger directly (the default implementation behind Logging.setFactory). Tests create MiniLogger with and without custom config.
|
|
126
170
|
|
|
127
|
-
|
|
171
|
+
```ts
|
|
172
|
+
import { MiniLogger, LogLevel, type LoggingConfig } from "@decaf-ts/logging";
|
|
128
173
|
|
|
129
|
-
|
|
130
|
-
|
|
174
|
+
const logger = new MiniLogger("TestContext");
|
|
175
|
+
logger.info("Info from MiniLogger");
|
|
131
176
|
|
|
132
|
-
//
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
timestamp: true
|
|
137
|
-
});
|
|
177
|
+
// With custom configuration
|
|
178
|
+
const custom: Partial<LoggingConfig> = { level: LogLevel.debug, verbose: 2 };
|
|
179
|
+
const customLogger = new MiniLogger("TestContext", custom);
|
|
180
|
+
customLogger.debug("Debug with custom level");
|
|
138
181
|
|
|
139
|
-
//
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
Logging.error('An error occurred');
|
|
143
|
-
Logging.verbose('Detailed information', 1); // With verbosity level
|
|
182
|
+
// Child logger with correlation id
|
|
183
|
+
const traced = customLogger.for("run", { correlationId: "req-123" });
|
|
184
|
+
traced.info("Tracing this operation");
|
|
144
185
|
```
|
|
145
186
|
|
|
146
|
-
### Class-Specific Logging
|
|
147
187
|
|
|
148
|
-
|
|
188
|
+
Decorators: log, debug, info, verbose, silly
|
|
189
|
+
Description: Instrument methods to log calls and optional benchmarks. Tests validate decorator behavior for call and completion messages.
|
|
149
190
|
|
|
150
|
-
```
|
|
151
|
-
import {
|
|
191
|
+
```ts
|
|
192
|
+
import { log, debug, info as infoDecor, verbose as verboseDecor, silly as sillyDecor, LogLevel, Logging } from "@decaf-ts/logging";
|
|
152
193
|
|
|
153
|
-
|
|
154
|
-
|
|
194
|
+
// Configure logging for demo
|
|
195
|
+
Logging.setConfig({ level: LogLevel.debug, style: false, timestamp: false });
|
|
155
196
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
197
|
+
class AccountService {
|
|
198
|
+
@log(LogLevel.info) // logs method call with args
|
|
199
|
+
create(name: string) {
|
|
200
|
+
return { id: "1", name };
|
|
160
201
|
}
|
|
161
202
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
// ...
|
|
165
|
-
|
|
203
|
+
@debug(true) // logs call and completion time at debug level
|
|
204
|
+
rebuildIndex() {
|
|
205
|
+
// heavy work...
|
|
206
|
+
return true;
|
|
166
207
|
}
|
|
167
208
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
// ... implementation
|
|
172
|
-
this.logger.debug('User updated successfully');
|
|
173
|
-
} catch (error) {
|
|
174
|
-
this.logger.error(error); // Logs error with stack trace
|
|
175
|
-
}
|
|
209
|
+
@info() // convenience wrapper for info level
|
|
210
|
+
enable() {
|
|
211
|
+
return true;
|
|
176
212
|
}
|
|
177
|
-
}
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### Method-Specific Logging
|
|
181
|
-
|
|
182
|
-
Create child loggers for specific methods to further refine the context:
|
|
183
|
-
|
|
184
|
-
```typescript
|
|
185
|
-
import { Logging, Logger } from 'decaf-logging';
|
|
186
213
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
constructor() {
|
|
191
|
-
this.logger = Logging.for(DataProcessor);
|
|
214
|
+
@verbose(1, true) // verbose with verbosity threshold and benchmark
|
|
215
|
+
syncAll() {
|
|
216
|
+
return Promise.resolve("ok");
|
|
192
217
|
}
|
|
193
218
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
methodLogger.info(`Processing ${data.length} items`);
|
|
199
|
-
|
|
200
|
-
// With custom configuration
|
|
201
|
-
const verboseLogger = methodLogger.for('details', { verbose: 2 });
|
|
202
|
-
verboseLogger.verbose('Starting detailed processing', 1);
|
|
203
|
-
|
|
204
|
-
// ... implementation
|
|
219
|
+
@silly() // very chatty, only emitted when verbose allows
|
|
220
|
+
ping() {
|
|
221
|
+
return "pong";
|
|
205
222
|
}
|
|
206
223
|
}
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
### Using Decorators
|
|
210
|
-
|
|
211
|
-
Decorators provide an easy way to add logging to class methods:
|
|
212
224
|
|
|
213
|
-
|
|
214
|
-
|
|
225
|
+
const svc = new AccountService();
|
|
226
|
+
svc.create("Alice");
|
|
227
|
+
svc.rebuildIndex();
|
|
228
|
+
svc.enable();
|
|
229
|
+
await svc.syncAll();
|
|
230
|
+
svc.ping();
|
|
231
|
+
```
|
|
215
232
|
|
|
216
|
-
class PaymentProcessor {
|
|
217
|
-
// Basic logging with info level
|
|
218
|
-
@info()
|
|
219
|
-
processPayment(amount: number, userId: string) {
|
|
220
|
-
// Method implementation
|
|
221
|
-
return true;
|
|
222
|
-
}
|
|
223
233
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
validatePayment(paymentData: any) {
|
|
227
|
-
// Method implementation
|
|
228
|
-
return true;
|
|
229
|
-
}
|
|
234
|
+
LoggedClass: zero-boilerplate logging inside classes
|
|
235
|
+
Description: Extend LoggedClass to gain a protected this.log with the correct context (class name). Tests use Logging.for to build similar context.
|
|
230
236
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
recordTransaction(transactionData: any) {
|
|
234
|
-
// Method implementation
|
|
235
|
-
}
|
|
237
|
+
```ts
|
|
238
|
+
import { LoggedClass } from "@your-scope/logging";
|
|
236
239
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
240
|
+
class UserRepository extends LoggedClass {
|
|
241
|
+
findById(id: string) {
|
|
242
|
+
this.log.info(`Finding ${id}`);
|
|
243
|
+
return { id };
|
|
241
244
|
}
|
|
242
245
|
}
|
|
243
|
-
```
|
|
244
246
|
|
|
245
|
-
|
|
247
|
+
const repo = new UserRepository();
|
|
248
|
+
repo.findById("42");
|
|
249
|
+
```
|
|
246
250
|
|
|
247
|
-
To use Winston for logging:
|
|
248
251
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
import { WinstonFactory } from 'decaf-logging/winston';
|
|
252
|
-
import winston from 'winston';
|
|
252
|
+
Winston integration: swap the logger factory
|
|
253
|
+
Description: Route all logging through WinstonLogger by installing WinstonFactory. This mirrors the optional adapter in src/winston.
|
|
253
254
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
new winston.transports.File({ filename: 'app.log' })
|
|
258
|
-
];
|
|
255
|
+
```ts
|
|
256
|
+
import { Logging } from "@your-scope/logging";
|
|
257
|
+
import { WinstonFactory } from "@your-scope/logging/winston/winston";
|
|
259
258
|
|
|
260
|
-
//
|
|
259
|
+
// Install Winston as the logger factory
|
|
261
260
|
Logging.setFactory(WinstonFactory);
|
|
262
261
|
|
|
263
|
-
//
|
|
264
|
-
Logging.
|
|
265
|
-
|
|
266
|
-
timestamp: true,
|
|
267
|
-
timestampFormat: 'YYYY-MM-DD HH:mm:ss'
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
// Create a Winston logger for a class
|
|
271
|
-
const logger = Logging.for('MyService');
|
|
272
|
-
logger.info('Service initialized');
|
|
262
|
+
// Now any logger created will use Winston under the hood
|
|
263
|
+
const log = Logging.for("ApiGateway");
|
|
264
|
+
log.info("Gateway started");
|
|
273
265
|
```
|
|
274
266
|
|
|
275
|
-
## Advanced Usage
|
|
276
267
|
|
|
277
|
-
|
|
268
|
+
Theming and styling with Logging.theme and config
|
|
269
|
+
Description: Enable style and customize theme to colorize parts of the log (tests check styled output patterns).
|
|
278
270
|
|
|
279
|
-
|
|
271
|
+
```ts
|
|
272
|
+
import { Logging, LogLevel, DefaultTheme, type Theme } from "@your-scope/logging";
|
|
280
273
|
|
|
281
|
-
|
|
282
|
-
|
|
274
|
+
// Enable styling globally
|
|
275
|
+
Logging.setConfig({ style: true, timestamp: true, context: false });
|
|
283
276
|
|
|
284
|
-
//
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
-
fg: 35, // Magenta
|
|
288
|
-
},
|
|
289
|
-
id: {
|
|
290
|
-
fg: 36, // Cyan
|
|
291
|
-
},
|
|
292
|
-
stack: {},
|
|
293
|
-
timestamp: {
|
|
294
|
-
fg: 90, // Gray
|
|
295
|
-
},
|
|
296
|
-
message: {
|
|
297
|
-
error: {
|
|
298
|
-
fg: 31, // Red
|
|
299
|
-
style: ['bold'],
|
|
300
|
-
},
|
|
301
|
-
},
|
|
302
|
-
method: {},
|
|
277
|
+
// Optionally override theme: make debug level yellow (fg:33) and error red+bold
|
|
278
|
+
const theme: Theme = {
|
|
279
|
+
...DefaultTheme,
|
|
303
280
|
logLevel: {
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
},
|
|
308
|
-
info: {
|
|
309
|
-
fg: 32, // Green
|
|
310
|
-
},
|
|
311
|
-
verbose: {
|
|
312
|
-
fg: 34, // Blue
|
|
313
|
-
},
|
|
314
|
-
debug: {
|
|
315
|
-
fg: 33, // Yellow
|
|
316
|
-
},
|
|
281
|
+
...DefaultTheme.logLevel,
|
|
282
|
+
debug: { fg: 33 },
|
|
283
|
+
error: { fg: 31, style: ["bold"] },
|
|
317
284
|
},
|
|
318
285
|
};
|
|
319
286
|
|
|
320
|
-
// Apply
|
|
321
|
-
Logging.
|
|
322
|
-
style: true,
|
|
323
|
-
theme: customTheme
|
|
324
|
-
});
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
### Correlation IDs
|
|
328
|
-
|
|
329
|
-
Track related log messages with correlation IDs:
|
|
330
|
-
|
|
331
|
-
```typescript
|
|
332
|
-
import { Logging } from 'decaf-logging';
|
|
333
|
-
|
|
334
|
-
function processRequest(requestId: string, data: any) {
|
|
335
|
-
// Create a logger with correlation ID
|
|
336
|
-
const logger = Logging.for('RequestProcessor', {
|
|
337
|
-
correlationId: requestId
|
|
338
|
-
});
|
|
287
|
+
// Apply at runtime by passing to Logging.theme where needed (MiniLogger does this internally)
|
|
288
|
+
const styled = Logging.theme("debug", "logLevel", LogLevel.debug, theme);
|
|
339
289
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
// All log messages from this logger will include the correlation ID
|
|
343
|
-
processRequestData(data, logger);
|
|
344
|
-
|
|
345
|
-
logger.info('Request processing completed');
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
function processRequestData(data: any, logger: Logger) {
|
|
349
|
-
// Child loggers inherit the correlation ID
|
|
350
|
-
const dataLogger = logger.for('DataProcessor');
|
|
351
|
-
dataLogger.debug('Processing data');
|
|
352
|
-
// ...
|
|
353
|
-
}
|
|
290
|
+
// Regular logging picks up style=true and formats output accordingly
|
|
291
|
+
Logging.debug("This is a styled debug message");
|
|
354
292
|
```
|
|
355
293
|
|
|
356
|
-
### JSON Output Mode
|
|
357
294
|
|
|
358
|
-
|
|
295
|
+
Factory basics and because(reason, id)
|
|
296
|
+
Description: Create ad-hoc, labeled loggers and use factory semantics.
|
|
359
297
|
|
|
360
|
-
```
|
|
361
|
-
import { Logging
|
|
298
|
+
```ts
|
|
299
|
+
import { Logging } from "@your-scope/logging";
|
|
362
300
|
|
|
363
|
-
//
|
|
364
|
-
Logging.
|
|
365
|
-
|
|
366
|
-
timestamp: true
|
|
367
|
-
});
|
|
368
|
-
|
|
369
|
-
Logging.info('This will be output in JSON format');
|
|
301
|
+
// Ad-hoc logger labeled with a reason and optional id (handy for correlation)
|
|
302
|
+
const jobLog = Logging.because("reindex", "job-77");
|
|
303
|
+
jobLog.info("Starting reindex");
|
|
370
304
|
```
|
|
371
305
|
|
|
372
|
-
### Custom Logger Factory
|
|
373
306
|
|
|
374
|
-
|
|
307
|
+
Types: Logger and LoggingConfig in your code
|
|
308
|
+
Description: Use the library’s types for better APIs.
|
|
375
309
|
|
|
376
|
-
```
|
|
377
|
-
import { Logger,
|
|
378
|
-
|
|
379
|
-
// Custom logger that adds prefix to all messages
|
|
380
|
-
class PrefixedLogger extends MiniLogger {
|
|
381
|
-
constructor(context: string, prefix: string, conf?: Partial<LoggingConfig>) {
|
|
382
|
-
super(context, conf);
|
|
383
|
-
this.prefix = prefix;
|
|
384
|
-
}
|
|
310
|
+
```ts
|
|
311
|
+
import type { Logger, LoggingConfig } from "@your-scope/logging";
|
|
385
312
|
|
|
386
|
-
|
|
313
|
+
export interface ServiceDeps {
|
|
314
|
+
log: Logger;
|
|
315
|
+
config?: Partial<LoggingConfig>;
|
|
316
|
+
}
|
|
387
317
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
318
|
+
export class PaymentService {
|
|
319
|
+
constructor(private deps: ServiceDeps) {}
|
|
320
|
+
charge(amount: number) {
|
|
321
|
+
this.deps.log.info(`Charging ${amount}`);
|
|
392
322
|
}
|
|
393
323
|
}
|
|
394
|
-
|
|
395
|
-
// Custom factory function
|
|
396
|
-
const PrefixedLoggerFactory: LoggerFactory = (
|
|
397
|
-
context: string,
|
|
398
|
-
conf?: Partial<LoggingConfig>,
|
|
399
|
-
...args: any[]
|
|
400
|
-
) => new PrefixedLogger(context, args[0] || '[APP]', conf);
|
|
401
|
-
|
|
402
|
-
// Set the custom factory
|
|
403
|
-
Logging.setFactory(PrefixedLoggerFactory);
|
|
404
|
-
|
|
405
|
-
// Create a logger with the custom factory
|
|
406
|
-
const logger = Logging.for('MyClass', undefined, '[CUSTOM]');
|
|
407
|
-
logger.info('Hello world'); // Outputs: "[CUSTOM]: Hello world"
|
|
408
324
|
```
|
|
409
325
|
|
|
410
326
|
|