@buenojs/bueno 0.8.0
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/.env.example +109 -0
- package/.github/workflows/ci.yml +31 -0
- package/LICENSE +21 -0
- package/README.md +892 -0
- package/architecture.md +652 -0
- package/bun.lock +70 -0
- package/dist/cli/index.js +3233 -0
- package/dist/index.js +9014 -0
- package/package.json +77 -0
- package/src/cache/index.ts +795 -0
- package/src/cli/ARCHITECTURE.md +837 -0
- package/src/cli/bin.ts +10 -0
- package/src/cli/commands/build.ts +425 -0
- package/src/cli/commands/dev.ts +248 -0
- package/src/cli/commands/generate.ts +541 -0
- package/src/cli/commands/help.ts +55 -0
- package/src/cli/commands/index.ts +112 -0
- package/src/cli/commands/migration.ts +355 -0
- package/src/cli/commands/new.ts +804 -0
- package/src/cli/commands/start.ts +208 -0
- package/src/cli/core/args.ts +283 -0
- package/src/cli/core/console.ts +349 -0
- package/src/cli/core/index.ts +60 -0
- package/src/cli/core/prompt.ts +424 -0
- package/src/cli/core/spinner.ts +265 -0
- package/src/cli/index.ts +135 -0
- package/src/cli/templates/deploy.ts +295 -0
- package/src/cli/templates/docker.ts +307 -0
- package/src/cli/templates/index.ts +24 -0
- package/src/cli/utils/fs.ts +428 -0
- package/src/cli/utils/index.ts +8 -0
- package/src/cli/utils/strings.ts +197 -0
- package/src/config/env.ts +408 -0
- package/src/config/index.ts +506 -0
- package/src/config/loader.ts +329 -0
- package/src/config/merge.ts +285 -0
- package/src/config/types.ts +320 -0
- package/src/config/validation.ts +441 -0
- package/src/container/forward-ref.ts +143 -0
- package/src/container/index.ts +386 -0
- package/src/context/index.ts +360 -0
- package/src/database/index.ts +1142 -0
- package/src/database/migrations/index.ts +371 -0
- package/src/database/schema/index.ts +619 -0
- package/src/frontend/api-routes.ts +640 -0
- package/src/frontend/bundler.ts +643 -0
- package/src/frontend/console-client.ts +419 -0
- package/src/frontend/console-stream.ts +587 -0
- package/src/frontend/dev-server.ts +846 -0
- package/src/frontend/file-router.ts +611 -0
- package/src/frontend/frameworks/index.ts +106 -0
- package/src/frontend/frameworks/react.ts +85 -0
- package/src/frontend/frameworks/solid.ts +104 -0
- package/src/frontend/frameworks/svelte.ts +110 -0
- package/src/frontend/frameworks/vue.ts +92 -0
- package/src/frontend/hmr-client.ts +663 -0
- package/src/frontend/hmr.ts +728 -0
- package/src/frontend/index.ts +342 -0
- package/src/frontend/islands.ts +552 -0
- package/src/frontend/isr.ts +555 -0
- package/src/frontend/layout.ts +475 -0
- package/src/frontend/ssr/react.ts +446 -0
- package/src/frontend/ssr/solid.ts +523 -0
- package/src/frontend/ssr/svelte.ts +546 -0
- package/src/frontend/ssr/vue.ts +504 -0
- package/src/frontend/ssr.ts +699 -0
- package/src/frontend/types.ts +2274 -0
- package/src/health/index.ts +604 -0
- package/src/index.ts +410 -0
- package/src/lock/index.ts +587 -0
- package/src/logger/index.ts +444 -0
- package/src/logger/transports/index.ts +969 -0
- package/src/metrics/index.ts +494 -0
- package/src/middleware/built-in.ts +360 -0
- package/src/middleware/index.ts +94 -0
- package/src/modules/filters.ts +458 -0
- package/src/modules/guards.ts +405 -0
- package/src/modules/index.ts +1256 -0
- package/src/modules/interceptors.ts +574 -0
- package/src/modules/lazy.ts +418 -0
- package/src/modules/lifecycle.ts +478 -0
- package/src/modules/metadata.ts +90 -0
- package/src/modules/pipes.ts +626 -0
- package/src/router/index.ts +339 -0
- package/src/router/linear.ts +371 -0
- package/src/router/regex.ts +292 -0
- package/src/router/tree.ts +562 -0
- package/src/rpc/index.ts +1263 -0
- package/src/security/index.ts +436 -0
- package/src/ssg/index.ts +631 -0
- package/src/storage/index.ts +456 -0
- package/src/telemetry/index.ts +1097 -0
- package/src/testing/index.ts +1586 -0
- package/src/types/index.ts +236 -0
- package/src/types/optional-deps.d.ts +219 -0
- package/src/validation/index.ts +276 -0
- package/src/websocket/index.ts +1004 -0
- package/tests/integration/cli.test.ts +1016 -0
- package/tests/integration/fullstack.test.ts +234 -0
- package/tests/unit/cache.test.ts +174 -0
- package/tests/unit/cli-commands.test.ts +892 -0
- package/tests/unit/cli.test.ts +1258 -0
- package/tests/unit/container.test.ts +279 -0
- package/tests/unit/context.test.ts +221 -0
- package/tests/unit/database.test.ts +183 -0
- package/tests/unit/linear-router.test.ts +280 -0
- package/tests/unit/lock.test.ts +336 -0
- package/tests/unit/middleware.test.ts +184 -0
- package/tests/unit/modules.test.ts +142 -0
- package/tests/unit/pubsub.test.ts +257 -0
- package/tests/unit/regex-router.test.ts +265 -0
- package/tests/unit/router.test.ts +373 -0
- package/tests/unit/rpc.test.ts +1248 -0
- package/tests/unit/security.test.ts +174 -0
- package/tests/unit/telemetry.test.ts +371 -0
- package/tests/unit/test-cache.test.ts +110 -0
- package/tests/unit/test-database.test.ts +282 -0
- package/tests/unit/tree-router.test.ts +325 -0
- package/tests/unit/validation.test.ts +794 -0
- package/tsconfig.json +27 -0
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured Logging System
|
|
3
|
+
*
|
|
4
|
+
* Provides structured logging with JSON output, log levels,
|
|
5
|
+
* context-aware logging, and performance metrics.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// ============= Types =============
|
|
9
|
+
|
|
10
|
+
export type LogLevel = "debug" | "info" | "warn" | "error" | "fatal";
|
|
11
|
+
|
|
12
|
+
export interface LogEntry {
|
|
13
|
+
level: LogLevel;
|
|
14
|
+
message: string;
|
|
15
|
+
timestamp: string;
|
|
16
|
+
context?: Record<string, unknown>;
|
|
17
|
+
error?: {
|
|
18
|
+
name: string;
|
|
19
|
+
message: string;
|
|
20
|
+
stack?: string;
|
|
21
|
+
};
|
|
22
|
+
duration?: number;
|
|
23
|
+
[key: string]: unknown;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface LoggerConfig {
|
|
27
|
+
level?: LogLevel;
|
|
28
|
+
pretty?: boolean;
|
|
29
|
+
timestamp?: boolean;
|
|
30
|
+
context?: Record<string, unknown>;
|
|
31
|
+
output?: "console" | "stdout" | ((entry: LogEntry) => void);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface LoggerContext {
|
|
35
|
+
requestId?: string;
|
|
36
|
+
userId?: string;
|
|
37
|
+
method?: string;
|
|
38
|
+
path?: string;
|
|
39
|
+
[key: string]: unknown;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ============= Log Level Priority =============
|
|
43
|
+
|
|
44
|
+
const LOG_LEVELS: Record<LogLevel, number> = {
|
|
45
|
+
debug: 0,
|
|
46
|
+
info: 1,
|
|
47
|
+
warn: 2,
|
|
48
|
+
error: 3,
|
|
49
|
+
fatal: 4,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// ============= Logger Class =============
|
|
53
|
+
|
|
54
|
+
export class Logger {
|
|
55
|
+
private level: LogLevel;
|
|
56
|
+
private pretty: boolean;
|
|
57
|
+
private timestamp: boolean;
|
|
58
|
+
private context: Record<string, unknown>;
|
|
59
|
+
private output: (entry: LogEntry) => void;
|
|
60
|
+
|
|
61
|
+
constructor(config: LoggerConfig = {}) {
|
|
62
|
+
this.level = config.level ?? "info";
|
|
63
|
+
this.pretty = config.pretty ?? process.env.NODE_ENV !== "production";
|
|
64
|
+
this.timestamp = config.timestamp ?? true;
|
|
65
|
+
this.context = config.context ?? {};
|
|
66
|
+
|
|
67
|
+
if (typeof config.output === "function") {
|
|
68
|
+
this.output = config.output;
|
|
69
|
+
} else if (config.output === "stdout") {
|
|
70
|
+
this.output = (entry) => console.log(this.serialize(entry));
|
|
71
|
+
} else {
|
|
72
|
+
this.output = (entry) => {
|
|
73
|
+
if (this.pretty) {
|
|
74
|
+
this.prettyPrint(entry);
|
|
75
|
+
} else {
|
|
76
|
+
console.log(this.serialize(entry));
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Check if a log level should be logged
|
|
84
|
+
*/
|
|
85
|
+
private shouldLog(level: LogLevel): boolean {
|
|
86
|
+
return LOG_LEVELS[level] >= LOG_LEVELS[this.level];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Serialize log entry to JSON
|
|
91
|
+
*/
|
|
92
|
+
private serialize(entry: LogEntry): string {
|
|
93
|
+
return JSON.stringify(entry);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Pretty print log entry
|
|
98
|
+
*/
|
|
99
|
+
private prettyPrint(entry: LogEntry): void {
|
|
100
|
+
const timestamp = entry.timestamp;
|
|
101
|
+
const levelColors: Record<LogLevel, string> = {
|
|
102
|
+
debug: "\x1b[36m", // cyan
|
|
103
|
+
info: "\x1b[32m", // green
|
|
104
|
+
warn: "\x1b[33m", // yellow
|
|
105
|
+
error: "\x1b[31m", // red
|
|
106
|
+
fatal: "\x1b[35m", // magenta
|
|
107
|
+
};
|
|
108
|
+
const reset = "\x1b[0m";
|
|
109
|
+
const color = levelColors[entry.level];
|
|
110
|
+
|
|
111
|
+
let output = `${timestamp} ${color}[${entry.level.toUpperCase()}]${reset} ${entry.message}`;
|
|
112
|
+
|
|
113
|
+
if (entry.context && Object.keys(entry.context).length > 0) {
|
|
114
|
+
output += ` ${reset}\x1b[90m${JSON.stringify(entry.context)}\x1b[0m`;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (entry.duration !== undefined) {
|
|
118
|
+
output += ` \x1b[90m(${entry.duration}ms)\x1b[0m`;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (entry.error) {
|
|
122
|
+
output += `\n \x1b[31m${entry.error.name}: ${entry.error.message}\x1b[0m`;
|
|
123
|
+
if (entry.error.stack) {
|
|
124
|
+
output += `\n \x1b[90m${entry.error.stack}\x1b[0m`;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
switch (entry.level) {
|
|
129
|
+
case "error":
|
|
130
|
+
case "fatal":
|
|
131
|
+
console.error(output);
|
|
132
|
+
break;
|
|
133
|
+
case "warn":
|
|
134
|
+
console.warn(output);
|
|
135
|
+
break;
|
|
136
|
+
default:
|
|
137
|
+
console.log(output);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Create a log entry
|
|
143
|
+
*/
|
|
144
|
+
private createEntry(
|
|
145
|
+
level: LogLevel,
|
|
146
|
+
message: string,
|
|
147
|
+
context?: Record<string, unknown>,
|
|
148
|
+
error?: Error,
|
|
149
|
+
): LogEntry {
|
|
150
|
+
const entry: LogEntry = {
|
|
151
|
+
level,
|
|
152
|
+
message,
|
|
153
|
+
timestamp: this.timestamp ? new Date().toISOString() : "",
|
|
154
|
+
...this.context,
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
if (context) {
|
|
158
|
+
entry.context = context;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (error) {
|
|
162
|
+
entry.error = {
|
|
163
|
+
name: error.name,
|
|
164
|
+
message: error.message,
|
|
165
|
+
stack: error.stack,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return entry;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Log a debug message
|
|
174
|
+
*/
|
|
175
|
+
debug(message: string, context?: Record<string, unknown>): void {
|
|
176
|
+
if (!this.shouldLog("debug")) return;
|
|
177
|
+
this.output(this.createEntry("debug", message, context));
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Log an info message
|
|
182
|
+
*/
|
|
183
|
+
info(message: string, context?: Record<string, unknown>): void {
|
|
184
|
+
if (!this.shouldLog("info")) return;
|
|
185
|
+
this.output(this.createEntry("info", message, context));
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Log a warning message
|
|
190
|
+
*/
|
|
191
|
+
warn(message: string, context?: Record<string, unknown>): void {
|
|
192
|
+
if (!this.shouldLog("warn")) return;
|
|
193
|
+
this.output(this.createEntry("warn", message, context));
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Log an error message
|
|
198
|
+
*/
|
|
199
|
+
error(
|
|
200
|
+
message: string,
|
|
201
|
+
error?: Error | unknown,
|
|
202
|
+
context?: Record<string, unknown>,
|
|
203
|
+
): void {
|
|
204
|
+
if (!this.shouldLog("error")) return;
|
|
205
|
+
const err = error instanceof Error ? error : undefined;
|
|
206
|
+
this.output(this.createEntry("error", message, context, err));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Log a fatal message
|
|
211
|
+
*/
|
|
212
|
+
fatal(
|
|
213
|
+
message: string,
|
|
214
|
+
error?: Error | unknown,
|
|
215
|
+
context?: Record<string, unknown>,
|
|
216
|
+
): void {
|
|
217
|
+
if (!this.shouldLog("fatal")) return;
|
|
218
|
+
const err = error instanceof Error ? error : undefined;
|
|
219
|
+
this.output(this.createEntry("fatal", message, context, err));
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Create a child logger with additional context
|
|
224
|
+
*/
|
|
225
|
+
child(context: Record<string, unknown>): Logger {
|
|
226
|
+
return new Logger({
|
|
227
|
+
level: this.level,
|
|
228
|
+
pretty: this.pretty,
|
|
229
|
+
timestamp: this.timestamp,
|
|
230
|
+
context: { ...this.context, ...context },
|
|
231
|
+
output: this.output,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Set log level
|
|
237
|
+
*/
|
|
238
|
+
setLevel(level: LogLevel): void {
|
|
239
|
+
this.level = level;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Add context to the logger
|
|
244
|
+
*/
|
|
245
|
+
addContext(context: Record<string, unknown>): void {
|
|
246
|
+
Object.assign(this.context, context);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Time a function
|
|
251
|
+
*/
|
|
252
|
+
async time<T>(label: string, fn: () => T | Promise<T>): Promise<T> {
|
|
253
|
+
const start = Date.now();
|
|
254
|
+
|
|
255
|
+
try {
|
|
256
|
+
const result = await fn();
|
|
257
|
+
this.debug(`${label} completed`, { duration: Date.now() - start });
|
|
258
|
+
return result;
|
|
259
|
+
} catch (error) {
|
|
260
|
+
this.error(`${label} failed`, error, { duration: Date.now() - start });
|
|
261
|
+
throw error;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Create a timer
|
|
267
|
+
*/
|
|
268
|
+
startTimer(label: string): () => number {
|
|
269
|
+
const start = Date.now();
|
|
270
|
+
return () => {
|
|
271
|
+
const duration = Date.now() - start;
|
|
272
|
+
this.debug(`${label}`, { duration });
|
|
273
|
+
return duration;
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// ============= Request Logger =============
|
|
279
|
+
|
|
280
|
+
export interface RequestLogContext {
|
|
281
|
+
requestId?: string;
|
|
282
|
+
method: string;
|
|
283
|
+
path: string;
|
|
284
|
+
query?: string;
|
|
285
|
+
ip?: string;
|
|
286
|
+
userAgent?: string;
|
|
287
|
+
userId?: string;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export interface ResponseLogContext extends RequestLogContext {
|
|
291
|
+
statusCode: number;
|
|
292
|
+
duration: number;
|
|
293
|
+
contentLength?: number;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Create a request logger middleware
|
|
298
|
+
*/
|
|
299
|
+
export function createRequestLogger(logger: Logger) {
|
|
300
|
+
return async (ctx: unknown, next: () => Promise<unknown>) => {
|
|
301
|
+
const context = ctx as {
|
|
302
|
+
method: string;
|
|
303
|
+
path: string;
|
|
304
|
+
url: URL;
|
|
305
|
+
getHeader: (name: string) => string | undefined;
|
|
306
|
+
ip?: string;
|
|
307
|
+
set: (key: string, value: unknown) => void;
|
|
308
|
+
get: (key: string) => unknown;
|
|
309
|
+
};
|
|
310
|
+
const start = Date.now();
|
|
311
|
+
const requestId = context.getHeader("x-request-id") || crypto.randomUUID();
|
|
312
|
+
|
|
313
|
+
context.set("requestId", requestId);
|
|
314
|
+
|
|
315
|
+
// Log request
|
|
316
|
+
const requestContext: Record<string, unknown> = {
|
|
317
|
+
requestId,
|
|
318
|
+
method: context.method,
|
|
319
|
+
path: context.path,
|
|
320
|
+
query: context.url?.search,
|
|
321
|
+
ip: context.ip,
|
|
322
|
+
userAgent: context.getHeader("user-agent"),
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
logger.info("Request started", requestContext);
|
|
326
|
+
|
|
327
|
+
try {
|
|
328
|
+
const response = await next();
|
|
329
|
+
|
|
330
|
+
// Log response
|
|
331
|
+
const duration = Date.now() - start;
|
|
332
|
+
const responseContext: Record<string, unknown> = {
|
|
333
|
+
...requestContext,
|
|
334
|
+
statusCode: (response as Response)?.status ?? 200,
|
|
335
|
+
duration,
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
logger.info("Request completed", responseContext);
|
|
339
|
+
|
|
340
|
+
return response;
|
|
341
|
+
} catch (error) {
|
|
342
|
+
const duration = Date.now() - start;
|
|
343
|
+
logger.error("Request failed", error, {
|
|
344
|
+
...requestContext,
|
|
345
|
+
duration,
|
|
346
|
+
});
|
|
347
|
+
throw error;
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// ============= Performance Logger =============
|
|
353
|
+
|
|
354
|
+
export class PerformanceLogger {
|
|
355
|
+
private logger: Logger;
|
|
356
|
+
private metrics: Map<string, number[]> = new Map();
|
|
357
|
+
|
|
358
|
+
constructor(logger: Logger) {
|
|
359
|
+
this.logger = logger;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Record a metric
|
|
364
|
+
*/
|
|
365
|
+
record(name: string, value: number): void {
|
|
366
|
+
if (!this.metrics.has(name)) {
|
|
367
|
+
this.metrics.set(name, []);
|
|
368
|
+
}
|
|
369
|
+
this.metrics.get(name)?.push(value);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Get metric statistics
|
|
374
|
+
*/
|
|
375
|
+
stats(
|
|
376
|
+
name: string,
|
|
377
|
+
): {
|
|
378
|
+
count: number;
|
|
379
|
+
min: number;
|
|
380
|
+
max: number;
|
|
381
|
+
avg: number;
|
|
382
|
+
p99: number;
|
|
383
|
+
} | null {
|
|
384
|
+
const values = this.metrics.get(name);
|
|
385
|
+
if (!values || values.length === 0) return null;
|
|
386
|
+
|
|
387
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
388
|
+
const count = sorted.length;
|
|
389
|
+
const min = sorted[0];
|
|
390
|
+
const max = sorted[count - 1];
|
|
391
|
+
const avg = sorted.reduce((a, b) => a + b, 0) / count;
|
|
392
|
+
const p99Index = Math.floor(count * 0.99);
|
|
393
|
+
const p99 = sorted[p99Index];
|
|
394
|
+
|
|
395
|
+
return { count, min, max, avg, p99 };
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Log all metrics
|
|
400
|
+
*/
|
|
401
|
+
logMetrics(): void {
|
|
402
|
+
for (const [name] of this.metrics) {
|
|
403
|
+
const stats = this.stats(name);
|
|
404
|
+
if (stats) {
|
|
405
|
+
this.logger.info(`Metric: ${name}`, stats);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Clear all metrics
|
|
412
|
+
*/
|
|
413
|
+
clear(): void {
|
|
414
|
+
this.metrics.clear();
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// ============= Default Logger Instance =============
|
|
419
|
+
|
|
420
|
+
let defaultLogger: Logger | null = null;
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Get the default logger instance
|
|
424
|
+
*/
|
|
425
|
+
export function getLogger(): Logger {
|
|
426
|
+
if (!defaultLogger) {
|
|
427
|
+
defaultLogger = new Logger();
|
|
428
|
+
}
|
|
429
|
+
return defaultLogger;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Set the default logger instance
|
|
434
|
+
*/
|
|
435
|
+
export function setLogger(logger: Logger): void {
|
|
436
|
+
defaultLogger = logger;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Create a new logger
|
|
441
|
+
*/
|
|
442
|
+
export function createLogger(config?: LoggerConfig): Logger {
|
|
443
|
+
return new Logger(config);
|
|
444
|
+
}
|