vestig 0.2.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/dist/config.d.ts +19 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +80 -0
- package/dist/config.js.map +1 -0
- package/dist/context/correlation.d.ts +26 -0
- package/dist/context/correlation.d.ts.map +1 -0
- package/dist/context/correlation.js +53 -0
- package/dist/context/correlation.js.map +1 -0
- package/dist/context/index.d.ts +20 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +122 -0
- package/dist/context/index.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/levels.d.ts +14 -0
- package/dist/levels.d.ts.map +1 -0
- package/dist/levels.js +28 -0
- package/dist/levels.js.map +1 -0
- package/dist/logger.d.ts +82 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +267 -0
- package/dist/logger.js.map +1 -0
- package/dist/runtime.d.ts +29 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +72 -0
- package/dist/runtime.js.map +1 -0
- package/dist/transports/batch.d.ts +69 -0
- package/dist/transports/batch.d.ts.map +1 -0
- package/dist/transports/batch.js +157 -0
- package/dist/transports/batch.js.map +1 -0
- package/dist/transports/console.d.ts +27 -0
- package/dist/transports/console.d.ts.map +1 -0
- package/dist/transports/console.js +82 -0
- package/dist/transports/console.js.map +1 -0
- package/dist/transports/datadog.d.ts +57 -0
- package/dist/transports/datadog.d.ts.map +1 -0
- package/dist/transports/datadog.js +173 -0
- package/dist/transports/datadog.js.map +1 -0
- package/dist/transports/file.d.ts +59 -0
- package/dist/transports/file.d.ts.map +1 -0
- package/dist/transports/file.js +167 -0
- package/dist/transports/file.js.map +1 -0
- package/dist/transports/http.d.ts +49 -0
- package/dist/transports/http.d.ts.map +1 -0
- package/dist/transports/http.js +106 -0
- package/dist/transports/http.js.map +1 -0
- package/dist/types.d.ts +224 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/buffer.d.ts +62 -0
- package/dist/utils/buffer.d.ts.map +1 -0
- package/dist/utils/buffer.js +110 -0
- package/dist/utils/buffer.js.map +1 -0
- package/dist/utils/error.d.ts +14 -0
- package/dist/utils/error.d.ts.map +1 -0
- package/dist/utils/error.js +92 -0
- package/dist/utils/error.js.map +1 -0
- package/dist/utils/sanitize-presets.d.ts +54 -0
- package/dist/utils/sanitize-presets.d.ts.map +1 -0
- package/dist/utils/sanitize-presets.js +245 -0
- package/dist/utils/sanitize-presets.js.map +1 -0
- package/dist/utils/sanitize.d.ts +75 -0
- package/dist/utils/sanitize.d.ts.map +1 -0
- package/dist/utils/sanitize.js +216 -0
- package/dist/utils/sanitize.js.map +1 -0
- package/package.json +76 -0
package/dist/logger.js
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { mergeConfig } from './config';
|
|
2
|
+
import { getContext } from './context';
|
|
3
|
+
import { LOG_LEVELS, shouldLog } from './levels';
|
|
4
|
+
import { RUNTIME } from './runtime';
|
|
5
|
+
import { ConsoleTransport } from './transports/console';
|
|
6
|
+
import { isError, serializeError } from './utils/error';
|
|
7
|
+
import { sanitize } from './utils/sanitize';
|
|
8
|
+
/**
|
|
9
|
+
* Format variadic arguments into message and metadata
|
|
10
|
+
*/
|
|
11
|
+
function formatArgs(args) {
|
|
12
|
+
if (args.length === 0) {
|
|
13
|
+
return { message: '', metadata: {} };
|
|
14
|
+
}
|
|
15
|
+
const first = args[0];
|
|
16
|
+
// If first arg is a string, it's the message
|
|
17
|
+
if (typeof first === 'string') {
|
|
18
|
+
const message = first;
|
|
19
|
+
const rest = args.slice(1);
|
|
20
|
+
// If second arg is a plain object (not Error), it's metadata
|
|
21
|
+
if (rest.length === 1 && typeof rest[0] === 'object' && rest[0] !== null && !isError(rest[0])) {
|
|
22
|
+
return { message, metadata: rest[0] };
|
|
23
|
+
}
|
|
24
|
+
// Otherwise, collect all remaining args
|
|
25
|
+
const metadata = {};
|
|
26
|
+
for (let i = 0; i < rest.length; i++) {
|
|
27
|
+
const arg = rest[i];
|
|
28
|
+
if (isError(arg)) {
|
|
29
|
+
metadata.error = serializeError(arg);
|
|
30
|
+
}
|
|
31
|
+
else if (typeof arg === 'object' && arg !== null) {
|
|
32
|
+
Object.assign(metadata, arg);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
metadata[`arg${i + 1}`] = arg;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return { message, metadata };
|
|
39
|
+
}
|
|
40
|
+
// If first arg is not a string, stringify all
|
|
41
|
+
const metadata = {};
|
|
42
|
+
for (let i = 0; i < args.length; i++) {
|
|
43
|
+
const arg = args[i];
|
|
44
|
+
if (isError(arg)) {
|
|
45
|
+
metadata.error = serializeError(arg);
|
|
46
|
+
}
|
|
47
|
+
else if (typeof arg === 'object' && arg !== null) {
|
|
48
|
+
Object.assign(metadata, arg);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
metadata[`arg${i}`] = arg;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return { message: String(first), metadata };
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Core logger implementation
|
|
58
|
+
*/
|
|
59
|
+
export class LoggerImpl {
|
|
60
|
+
config;
|
|
61
|
+
transports = [];
|
|
62
|
+
children = new Map();
|
|
63
|
+
initialized = false;
|
|
64
|
+
constructor(config) {
|
|
65
|
+
this.config = mergeConfig(config);
|
|
66
|
+
// Add default console transport
|
|
67
|
+
this.transports.push(new ConsoleTransport({
|
|
68
|
+
structured: this.config.structured,
|
|
69
|
+
colors: !this.config.structured,
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Internal log method
|
|
74
|
+
*/
|
|
75
|
+
log(level, args) {
|
|
76
|
+
// Check if logging is enabled and level is sufficient
|
|
77
|
+
if (!this.config.enabled || !shouldLog(level, this.config.level)) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const { message, metadata } = formatArgs(args);
|
|
81
|
+
// Get context from async storage
|
|
82
|
+
const asyncContext = getContext();
|
|
83
|
+
// Sanitize metadata if enabled
|
|
84
|
+
const sanitizedMetadata = this.config.sanitize
|
|
85
|
+
? sanitize(metadata, this.config.sanitizeFields)
|
|
86
|
+
: metadata;
|
|
87
|
+
// Build log entry
|
|
88
|
+
const entry = {
|
|
89
|
+
timestamp: new Date().toISOString(),
|
|
90
|
+
level,
|
|
91
|
+
message,
|
|
92
|
+
metadata: Object.keys(sanitizedMetadata).length > 0 ? sanitizedMetadata : undefined,
|
|
93
|
+
context: this.mergeContext(asyncContext),
|
|
94
|
+
runtime: RUNTIME,
|
|
95
|
+
namespace: this.config.namespace || undefined,
|
|
96
|
+
error: sanitizedMetadata.error,
|
|
97
|
+
};
|
|
98
|
+
// Remove error from metadata since it's top-level
|
|
99
|
+
if (entry.metadata?.error) {
|
|
100
|
+
const { error: _, ...rest } = entry.metadata;
|
|
101
|
+
entry.metadata = Object.keys(rest).length > 0 ? rest : undefined;
|
|
102
|
+
}
|
|
103
|
+
// Send to all enabled transports
|
|
104
|
+
for (const transport of this.transports) {
|
|
105
|
+
// Check if transport is enabled
|
|
106
|
+
if (transport.config.enabled === false)
|
|
107
|
+
continue;
|
|
108
|
+
// Check transport-level log level filter
|
|
109
|
+
if (transport.config.level && !shouldLog(level, transport.config.level))
|
|
110
|
+
continue;
|
|
111
|
+
// Check transport-level custom filter
|
|
112
|
+
if (transport.config.filter && !transport.config.filter(entry))
|
|
113
|
+
continue;
|
|
114
|
+
// Send to transport
|
|
115
|
+
transport.log(entry);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Merge static context with async context
|
|
120
|
+
*/
|
|
121
|
+
mergeContext(asyncContext) {
|
|
122
|
+
const staticContext = this.config.context;
|
|
123
|
+
const hasStatic = Object.keys(staticContext).length > 0;
|
|
124
|
+
const hasAsync = asyncContext && Object.keys(asyncContext).length > 0;
|
|
125
|
+
if (!hasStatic && !hasAsync)
|
|
126
|
+
return undefined;
|
|
127
|
+
return { ...staticContext, ...asyncContext };
|
|
128
|
+
}
|
|
129
|
+
trace(...args) {
|
|
130
|
+
this.log('trace', args);
|
|
131
|
+
}
|
|
132
|
+
debug(...args) {
|
|
133
|
+
this.log('debug', args);
|
|
134
|
+
}
|
|
135
|
+
info(...args) {
|
|
136
|
+
this.log('info', args);
|
|
137
|
+
}
|
|
138
|
+
warn(...args) {
|
|
139
|
+
this.log('warn', args);
|
|
140
|
+
}
|
|
141
|
+
error(...args) {
|
|
142
|
+
this.log('error', args);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Create a child logger with a namespace
|
|
146
|
+
*/
|
|
147
|
+
child(namespace, config) {
|
|
148
|
+
const fullNamespace = this.config.namespace
|
|
149
|
+
? `${this.config.namespace}:${namespace}`
|
|
150
|
+
: namespace;
|
|
151
|
+
// Check cache
|
|
152
|
+
const cached = this.children.get(fullNamespace);
|
|
153
|
+
if (cached && !config) {
|
|
154
|
+
return cached;
|
|
155
|
+
}
|
|
156
|
+
// Create new child logger
|
|
157
|
+
const child = new LoggerImpl({
|
|
158
|
+
...this.config,
|
|
159
|
+
...config,
|
|
160
|
+
namespace: fullNamespace,
|
|
161
|
+
context: { ...this.config.context, ...config?.context },
|
|
162
|
+
});
|
|
163
|
+
// Cache if no custom config
|
|
164
|
+
if (!config) {
|
|
165
|
+
this.children.set(fullNamespace, child);
|
|
166
|
+
}
|
|
167
|
+
return child;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Set the minimum log level
|
|
171
|
+
*/
|
|
172
|
+
setLevel(level) {
|
|
173
|
+
this.config.level = level;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Get the current log level
|
|
177
|
+
*/
|
|
178
|
+
getLevel() {
|
|
179
|
+
return this.config.level;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Enable logging
|
|
183
|
+
*/
|
|
184
|
+
enable() {
|
|
185
|
+
this.config.enabled = true;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Disable logging
|
|
189
|
+
*/
|
|
190
|
+
disable() {
|
|
191
|
+
this.config.enabled = false;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Check if logging is enabled
|
|
195
|
+
*/
|
|
196
|
+
isEnabled() {
|
|
197
|
+
return this.config.enabled;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Flush any buffered logs from all transports
|
|
201
|
+
*/
|
|
202
|
+
async flush() {
|
|
203
|
+
await Promise.all(this.transports.map((t) => t.flush?.()));
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Add a transport to the logger
|
|
207
|
+
*/
|
|
208
|
+
addTransport(transport) {
|
|
209
|
+
// Check for duplicate names
|
|
210
|
+
if (this.transports.some((t) => t.name === transport.name)) {
|
|
211
|
+
throw new Error(`Transport with name "${transport.name}" already exists`);
|
|
212
|
+
}
|
|
213
|
+
this.transports.push(transport);
|
|
214
|
+
// Initialize if logger is already initialized
|
|
215
|
+
if (this.initialized) {
|
|
216
|
+
transport.init?.().catch((err) => {
|
|
217
|
+
console.error(`Failed to initialize transport "${transport.name}":`, err);
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Remove a transport by name
|
|
223
|
+
*/
|
|
224
|
+
removeTransport(name) {
|
|
225
|
+
const index = this.transports.findIndex((t) => t.name === name);
|
|
226
|
+
if (index === -1)
|
|
227
|
+
return false;
|
|
228
|
+
const removed = this.transports.splice(index, 1);
|
|
229
|
+
const transport = removed[0];
|
|
230
|
+
if (transport) {
|
|
231
|
+
transport.destroy?.().catch((err) => {
|
|
232
|
+
console.error(`Failed to destroy transport "${name}":`, err);
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Get all registered transports
|
|
239
|
+
*/
|
|
240
|
+
getTransports() {
|
|
241
|
+
return this.transports;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Initialize all transports
|
|
245
|
+
*/
|
|
246
|
+
async init() {
|
|
247
|
+
if (this.initialized)
|
|
248
|
+
return;
|
|
249
|
+
await Promise.all(this.transports.map((t) => t.init?.()));
|
|
250
|
+
this.initialized = true;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Destroy all transports (call on shutdown)
|
|
254
|
+
*/
|
|
255
|
+
async destroy() {
|
|
256
|
+
await Promise.all(this.transports.map((t) => t.destroy?.()));
|
|
257
|
+
this.transports = [];
|
|
258
|
+
this.initialized = false;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Create a new logger instance
|
|
263
|
+
*/
|
|
264
|
+
export function createLogger(config) {
|
|
265
|
+
return new LoggerImpl(config);
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Runtime } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Runtime capabilities
|
|
4
|
+
*/
|
|
5
|
+
export interface RuntimeCapabilities {
|
|
6
|
+
hasAsyncLocalStorage: boolean;
|
|
7
|
+
hasProcess: boolean;
|
|
8
|
+
hasPerformance: boolean;
|
|
9
|
+
hasConsole: boolean;
|
|
10
|
+
hasCrypto: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Current runtime (computed once at module load)
|
|
14
|
+
*/
|
|
15
|
+
export declare const RUNTIME: Runtime;
|
|
16
|
+
/**
|
|
17
|
+
* Current capabilities (computed once at module load)
|
|
18
|
+
*/
|
|
19
|
+
export declare const CAPABILITIES: RuntimeCapabilities;
|
|
20
|
+
/**
|
|
21
|
+
* Convenience flags
|
|
22
|
+
*/
|
|
23
|
+
export declare const IS_NODE: boolean;
|
|
24
|
+
export declare const IS_BUN: boolean;
|
|
25
|
+
export declare const IS_EDGE: boolean;
|
|
26
|
+
export declare const IS_BROWSER: boolean;
|
|
27
|
+
export declare const IS_WORKER: boolean;
|
|
28
|
+
export declare const IS_SERVER: boolean;
|
|
29
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAEtC;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,oBAAoB,EAAE,OAAO,CAAA;IAC7B,UAAU,EAAE,OAAO,CAAA;IACnB,cAAc,EAAE,OAAO,CAAA;IACvB,UAAU,EAAE,OAAO,CAAA;IACnB,SAAS,EAAE,OAAO,CAAA;CAClB;AAoED;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,OAAyB,CAAA;AAE/C;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,mBAA0C,CAAA;AAErE;;GAEG;AACH,eAAO,MAAM,OAAO,SAAqB,CAAA;AACzC,eAAO,MAAM,MAAM,SAAoB,CAAA;AACvC,eAAO,MAAM,OAAO,SAAqB,CAAA;AACzC,eAAO,MAAM,UAAU,SAAwB,CAAA;AAC/C,eAAO,MAAM,SAAS,SAAuB,CAAA;AAC7C,eAAO,MAAM,SAAS,SAA+B,CAAA"}
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detect the current runtime environment
|
|
3
|
+
*/
|
|
4
|
+
function detectRuntime() {
|
|
5
|
+
// Bun detection (highest priority)
|
|
6
|
+
if (typeof globalThis !== 'undefined' && 'Bun' in globalThis) {
|
|
7
|
+
return 'bun';
|
|
8
|
+
}
|
|
9
|
+
// Edge runtime detection
|
|
10
|
+
if (typeof globalThis !== 'undefined') {
|
|
11
|
+
// Vercel Edge Runtime
|
|
12
|
+
if ('EdgeRuntime' in globalThis) {
|
|
13
|
+
return 'edge';
|
|
14
|
+
}
|
|
15
|
+
// Next.js Edge
|
|
16
|
+
if (typeof process !== 'undefined' && process.env?.NEXT_RUNTIME === 'edge') {
|
|
17
|
+
return 'edge';
|
|
18
|
+
}
|
|
19
|
+
// Cloudflare Workers (has caches but no window/process.versions)
|
|
20
|
+
if ('caches' in globalThis &&
|
|
21
|
+
typeof globalThis.Request === 'function' &&
|
|
22
|
+
typeof globalThis.Response === 'function' &&
|
|
23
|
+
typeof window === 'undefined' &&
|
|
24
|
+
(typeof process === 'undefined' || !process.versions?.node)) {
|
|
25
|
+
return 'edge';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// Node.js detection
|
|
29
|
+
if (typeof process !== 'undefined' && process.versions?.node && typeof window === 'undefined') {
|
|
30
|
+
return 'node';
|
|
31
|
+
}
|
|
32
|
+
// Browser detection
|
|
33
|
+
if (typeof window !== 'undefined' && typeof document !== 'undefined') {
|
|
34
|
+
return 'browser';
|
|
35
|
+
}
|
|
36
|
+
// Web Worker detection
|
|
37
|
+
if (typeof self !== 'undefined' &&
|
|
38
|
+
typeof self.importScripts === 'function') {
|
|
39
|
+
return 'worker';
|
|
40
|
+
}
|
|
41
|
+
return 'unknown';
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Detect runtime capabilities
|
|
45
|
+
*/
|
|
46
|
+
function detectCapabilities() {
|
|
47
|
+
return {
|
|
48
|
+
hasAsyncLocalStorage: typeof process !== 'undefined' && (RUNTIME === 'node' || RUNTIME === 'bun'),
|
|
49
|
+
hasProcess: typeof process !== 'undefined',
|
|
50
|
+
hasPerformance: typeof performance !== 'undefined',
|
|
51
|
+
hasConsole: typeof console !== 'undefined',
|
|
52
|
+
hasCrypto: typeof crypto !== 'undefined',
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Current runtime (computed once at module load)
|
|
57
|
+
*/
|
|
58
|
+
export const RUNTIME = detectRuntime();
|
|
59
|
+
/**
|
|
60
|
+
* Current capabilities (computed once at module load)
|
|
61
|
+
*/
|
|
62
|
+
export const CAPABILITIES = detectCapabilities();
|
|
63
|
+
/**
|
|
64
|
+
* Convenience flags
|
|
65
|
+
*/
|
|
66
|
+
export const IS_NODE = RUNTIME === 'node';
|
|
67
|
+
export const IS_BUN = RUNTIME === 'bun';
|
|
68
|
+
export const IS_EDGE = RUNTIME === 'edge';
|
|
69
|
+
export const IS_BROWSER = RUNTIME === 'browser';
|
|
70
|
+
export const IS_WORKER = RUNTIME === 'worker';
|
|
71
|
+
export const IS_SERVER = IS_NODE || IS_BUN || IS_EDGE;
|
|
72
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAaA;;GAEG;AACH,SAAS,aAAa;IACrB,mCAAmC;IACnC,IAAI,OAAO,UAAU,KAAK,WAAW,IAAI,KAAK,IAAI,UAAU,EAAE,CAAC;QAC9D,OAAO,KAAK,CAAA;IACb,CAAC;IAED,yBAAyB;IACzB,IAAI,OAAO,UAAU,KAAK,WAAW,EAAE,CAAC;QACvC,sBAAsB;QACtB,IAAI,aAAa,IAAI,UAAU,EAAE,CAAC;YACjC,OAAO,MAAM,CAAA;QACd,CAAC;QACD,eAAe;QACf,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,YAAY,KAAK,MAAM,EAAE,CAAC;YAC5E,OAAO,MAAM,CAAA;QACd,CAAC;QACD,iEAAiE;QACjE,IACC,QAAQ,IAAI,UAAU;YACtB,OAAQ,UAAsC,CAAC,OAAO,KAAK,UAAU;YACrE,OAAQ,UAAsC,CAAC,QAAQ,KAAK,UAAU;YACtE,OAAO,MAAM,KAAK,WAAW;YAC7B,CAAC,OAAO,OAAO,KAAK,WAAW,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,EAC1D,CAAC;YACF,OAAO,MAAM,CAAA;QACd,CAAC;IACF,CAAC;IAED,oBAAoB;IACpB,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,QAAQ,EAAE,IAAI,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAC/F,OAAO,MAAM,CAAA;IACd,CAAC;IAED,oBAAoB;IACpB,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;QACtE,OAAO,SAAS,CAAA;IACjB,CAAC;IAED,uBAAuB;IACvB,IACC,OAAO,IAAI,KAAK,WAAW;QAC3B,OAAQ,IAA2C,CAAC,aAAa,KAAK,UAAU,EAC/E,CAAC;QACF,OAAO,QAAQ,CAAA;IAChB,CAAC;IAED,OAAO,SAAS,CAAA;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB;IAC1B,OAAO;QACN,oBAAoB,EACnB,OAAO,OAAO,KAAK,WAAW,IAAI,CAAC,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,KAAK,CAAC;QAC5E,UAAU,EAAE,OAAO,OAAO,KAAK,WAAW;QAC1C,cAAc,EAAE,OAAO,WAAW,KAAK,WAAW;QAClD,UAAU,EAAE,OAAO,OAAO,KAAK,WAAW;QAC1C,SAAS,EAAE,OAAO,MAAM,KAAK,WAAW;KACxC,CAAA;AACF,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAY,aAAa,EAAE,CAAA;AAE/C;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAwB,kBAAkB,EAAE,CAAA;AAErE;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,KAAK,MAAM,CAAA;AACzC,MAAM,CAAC,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,CAAA;AACvC,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,KAAK,MAAM,CAAA;AACzC,MAAM,CAAC,MAAM,UAAU,GAAG,OAAO,KAAK,SAAS,CAAA;AAC/C,MAAM,CAAC,MAAM,SAAS,GAAG,OAAO,KAAK,QAAQ,CAAA;AAC7C,MAAM,CAAC,MAAM,SAAS,GAAG,OAAO,IAAI,MAAM,IAAI,OAAO,CAAA"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { BatchTransportConfig, LogEntry, Transport, TransportConfig } from '../types';
|
|
2
|
+
import { CircularBuffer } from '../utils/buffer';
|
|
3
|
+
/**
|
|
4
|
+
* Abstract base class for batch transports
|
|
5
|
+
*
|
|
6
|
+
* Provides automatic batching with circular buffer, periodic flushing,
|
|
7
|
+
* and retry logic with exponential backoff.
|
|
8
|
+
*/
|
|
9
|
+
export declare abstract class BatchTransport implements Transport {
|
|
10
|
+
abstract readonly name: string;
|
|
11
|
+
readonly config: TransportConfig;
|
|
12
|
+
protected readonly buffer: CircularBuffer<LogEntry>;
|
|
13
|
+
protected readonly batchSize: number;
|
|
14
|
+
protected readonly flushInterval: number;
|
|
15
|
+
protected readonly maxRetries: number;
|
|
16
|
+
protected readonly retryDelay: number;
|
|
17
|
+
private flushTimer;
|
|
18
|
+
private isFlushing;
|
|
19
|
+
private isDestroyed;
|
|
20
|
+
constructor(config: BatchTransportConfig);
|
|
21
|
+
/**
|
|
22
|
+
* Initialize the transport and start the flush timer
|
|
23
|
+
*/
|
|
24
|
+
init(): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Add a log entry to the buffer
|
|
27
|
+
*/
|
|
28
|
+
log(entry: LogEntry): void;
|
|
29
|
+
/**
|
|
30
|
+
* Flush all buffered entries
|
|
31
|
+
*/
|
|
32
|
+
flush(): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Cleanup and stop the flush timer
|
|
35
|
+
*/
|
|
36
|
+
destroy(): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Send entries with retry logic and exponential backoff
|
|
39
|
+
*/
|
|
40
|
+
protected sendWithRetry(entries: LogEntry[]): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Abstract method to send entries to the destination
|
|
43
|
+
* Subclasses must implement this
|
|
44
|
+
*/
|
|
45
|
+
protected abstract send(entries: LogEntry[]): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Called when entries are dropped from the buffer
|
|
48
|
+
* Subclasses can override to handle dropped entries
|
|
49
|
+
*/
|
|
50
|
+
protected onDrop(entries: LogEntry[]): void;
|
|
51
|
+
/**
|
|
52
|
+
* Called when send fails after all retries
|
|
53
|
+
* Subclasses can override to handle send failures
|
|
54
|
+
*/
|
|
55
|
+
protected onSendError(error: Error, entries: LogEntry[]): void;
|
|
56
|
+
/**
|
|
57
|
+
* Utility to sleep for a given duration
|
|
58
|
+
*/
|
|
59
|
+
protected sleep(ms: number): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Get buffer statistics
|
|
62
|
+
*/
|
|
63
|
+
getStats(): {
|
|
64
|
+
buffered: number;
|
|
65
|
+
dropped: number;
|
|
66
|
+
isFlushing: boolean;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=batch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../../src/transports/batch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC1F,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAYhD;;;;;GAKG;AACH,8BAAsB,cAAe,YAAW,SAAS;IACxD,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAA;IAEhC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAA;IACnD,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IACpC,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IACxC,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IACrC,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAErC,OAAO,CAAC,UAAU,CAA8C;IAChE,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,WAAW,CAAQ;gBAEf,MAAM,EAAE,oBAAoB;IAmBxC;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAe3B;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAa1B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAe5B;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAc9B;;OAEG;cACa,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBjE;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAE3D;;;OAGG;IACH,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI;IAI3C;;;OAGG;IACH,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI;IAO9D;;OAEG;IACH,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C;;OAEG;IACH,QAAQ,IAAI;QACX,QAAQ,EAAE,MAAM,CAAA;QAChB,OAAO,EAAE,MAAM,CAAA;QACf,UAAU,EAAE,OAAO,CAAA;KACnB;CAQD"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { CircularBuffer } from '../utils/buffer';
|
|
2
|
+
/**
|
|
3
|
+
* Default batch transport configuration
|
|
4
|
+
*/
|
|
5
|
+
const DEFAULTS = {
|
|
6
|
+
batchSize: 100,
|
|
7
|
+
flushInterval: 5000,
|
|
8
|
+
maxRetries: 3,
|
|
9
|
+
retryDelay: 1000,
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Abstract base class for batch transports
|
|
13
|
+
*
|
|
14
|
+
* Provides automatic batching with circular buffer, periodic flushing,
|
|
15
|
+
* and retry logic with exponential backoff.
|
|
16
|
+
*/
|
|
17
|
+
export class BatchTransport {
|
|
18
|
+
config;
|
|
19
|
+
buffer;
|
|
20
|
+
batchSize;
|
|
21
|
+
flushInterval;
|
|
22
|
+
maxRetries;
|
|
23
|
+
retryDelay;
|
|
24
|
+
flushTimer = null;
|
|
25
|
+
isFlushing = false;
|
|
26
|
+
isDestroyed = false;
|
|
27
|
+
constructor(config) {
|
|
28
|
+
this.config = {
|
|
29
|
+
name: config.name,
|
|
30
|
+
enabled: config.enabled ?? true,
|
|
31
|
+
level: config.level,
|
|
32
|
+
filter: config.filter,
|
|
33
|
+
};
|
|
34
|
+
this.batchSize = config.batchSize ?? DEFAULTS.batchSize;
|
|
35
|
+
this.flushInterval = config.flushInterval ?? DEFAULTS.flushInterval;
|
|
36
|
+
this.maxRetries = config.maxRetries ?? DEFAULTS.maxRetries;
|
|
37
|
+
this.retryDelay = config.retryDelay ?? DEFAULTS.retryDelay;
|
|
38
|
+
this.buffer = new CircularBuffer({
|
|
39
|
+
maxSize: this.batchSize * 2, // Allow some overflow before dropping
|
|
40
|
+
onDrop: (items) => this.onDrop(items),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Initialize the transport and start the flush timer
|
|
45
|
+
*/
|
|
46
|
+
async init() {
|
|
47
|
+
if (this.flushTimer)
|
|
48
|
+
return;
|
|
49
|
+
this.flushTimer = setInterval(() => {
|
|
50
|
+
this.flush().catch((err) => {
|
|
51
|
+
console.error(`[${this.name}] Flush error:`, err);
|
|
52
|
+
});
|
|
53
|
+
}, this.flushInterval);
|
|
54
|
+
// Ensure timer doesn't prevent process exit
|
|
55
|
+
if (typeof this.flushTimer.unref === 'function') {
|
|
56
|
+
this.flushTimer.unref();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Add a log entry to the buffer
|
|
61
|
+
*/
|
|
62
|
+
log(entry) {
|
|
63
|
+
if (this.isDestroyed)
|
|
64
|
+
return;
|
|
65
|
+
this.buffer.push(entry);
|
|
66
|
+
// Auto-flush when batch size reached
|
|
67
|
+
if (this.buffer.size >= this.batchSize && !this.isFlushing) {
|
|
68
|
+
this.flush().catch((err) => {
|
|
69
|
+
console.error(`[${this.name}] Auto-flush error:`, err);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Flush all buffered entries
|
|
75
|
+
*/
|
|
76
|
+
async flush() {
|
|
77
|
+
if (this.isFlushing || this.buffer.size === 0)
|
|
78
|
+
return;
|
|
79
|
+
this.isFlushing = true;
|
|
80
|
+
try {
|
|
81
|
+
const entries = this.buffer.toArray();
|
|
82
|
+
this.buffer.clear();
|
|
83
|
+
await this.sendWithRetry(entries);
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
this.isFlushing = false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Cleanup and stop the flush timer
|
|
91
|
+
*/
|
|
92
|
+
async destroy() {
|
|
93
|
+
this.isDestroyed = true;
|
|
94
|
+
if (this.flushTimer) {
|
|
95
|
+
clearInterval(this.flushTimer);
|
|
96
|
+
this.flushTimer = null;
|
|
97
|
+
}
|
|
98
|
+
// Final flush
|
|
99
|
+
if (this.buffer.size > 0) {
|
|
100
|
+
await this.flush();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Send entries with retry logic and exponential backoff
|
|
105
|
+
*/
|
|
106
|
+
async sendWithRetry(entries) {
|
|
107
|
+
let lastError = new Error('Unknown error');
|
|
108
|
+
for (let attempt = 0; attempt < this.maxRetries; attempt++) {
|
|
109
|
+
try {
|
|
110
|
+
await this.send(entries);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
115
|
+
if (attempt < this.maxRetries - 1) {
|
|
116
|
+
// Exponential backoff: 1s, 2s, 4s, etc.
|
|
117
|
+
const delay = this.retryDelay * 2 ** attempt;
|
|
118
|
+
await this.sleep(delay);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// All retries failed, call error handler
|
|
123
|
+
this.onSendError(lastError, entries);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Called when entries are dropped from the buffer
|
|
127
|
+
* Subclasses can override to handle dropped entries
|
|
128
|
+
*/
|
|
129
|
+
onDrop(entries) {
|
|
130
|
+
console.warn(`[${this.name}] Dropped ${entries.length} log entries due to buffer overflow`);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Called when send fails after all retries
|
|
134
|
+
* Subclasses can override to handle send failures
|
|
135
|
+
*/
|
|
136
|
+
onSendError(error, entries) {
|
|
137
|
+
console.error(`[${this.name}] Failed to send ${entries.length} entries after ${this.maxRetries} retries:`, error.message);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Utility to sleep for a given duration
|
|
141
|
+
*/
|
|
142
|
+
sleep(ms) {
|
|
143
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Get buffer statistics
|
|
147
|
+
*/
|
|
148
|
+
getStats() {
|
|
149
|
+
const stats = this.buffer.getStats();
|
|
150
|
+
return {
|
|
151
|
+
buffered: stats.size,
|
|
152
|
+
dropped: stats.dropped,
|
|
153
|
+
isFlushing: this.isFlushing,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=batch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch.js","sourceRoot":"","sources":["../../src/transports/batch.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD;;GAEG;AACH,MAAM,QAAQ,GAAG;IAChB,SAAS,EAAE,GAAG;IACd,aAAa,EAAE,IAAI;IACnB,UAAU,EAAE,CAAC;IACb,UAAU,EAAE,IAAI;CACP,CAAA;AAEV;;;;;GAKG;AACH,MAAM,OAAgB,cAAc;IAE1B,MAAM,CAAiB;IAEb,MAAM,CAA0B;IAChC,SAAS,CAAQ;IACjB,aAAa,CAAQ;IACrB,UAAU,CAAQ;IAClB,UAAU,CAAQ;IAE7B,UAAU,GAA0C,IAAI,CAAA;IACxD,UAAU,GAAG,KAAK,CAAA;IAClB,WAAW,GAAG,KAAK,CAAA;IAE3B,YAAY,MAA4B;QACvC,IAAI,CAAC,MAAM,GAAG;YACb,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI;YAC/B,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM;SACrB,CAAA;QAED,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,QAAQ,CAAC,SAAS,CAAA;QACvD,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,aAAa,IAAI,QAAQ,CAAC,aAAa,CAAA;QACnE,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU,CAAA;QAC1D,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU,CAAA;QAE1D,IAAI,CAAC,MAAM,GAAG,IAAI,cAAc,CAAW;YAC1C,OAAO,EAAE,IAAI,CAAC,SAAS,GAAG,CAAC,EAAE,sCAAsC;YACnE,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAmB,CAAC;SACnD,CAAC,CAAA;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACT,IAAI,IAAI,CAAC,UAAU;YAAE,OAAM;QAE3B,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;YAClC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBAC1B,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,gBAAgB,EAAE,GAAG,CAAC,CAAA;YAClD,CAAC,CAAC,CAAA;QACH,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,CAAA;QAEtB,4CAA4C;QAC5C,IAAI,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;YACjD,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAA;QACxB,CAAC;IACF,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,KAAe;QAClB,IAAI,IAAI,CAAC,WAAW;YAAE,OAAM;QAE5B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAEvB,qCAAqC;QACrC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YAC5D,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBAC1B,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,qBAAqB,EAAE,GAAG,CAAC,CAAA;YACvD,CAAC,CAAC,CAAA;QACH,CAAC;IACF,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACV,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC;YAAE,OAAM;QAErD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAA;QAEtB,IAAI,CAAC;YACJ,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAA;YACrC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAA;YAEnB,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;QAClC,CAAC;gBAAS,CAAC;YACV,IAAI,CAAC,UAAU,GAAG,KAAK,CAAA;QACxB,CAAC;IACF,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACZ,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;QAEvB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;YAC9B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAA;QACvB,CAAC;QAED,cAAc;QACd,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,CAAC,KAAK,EAAE,CAAA;QACnB,CAAC;IACF,CAAC;IAED;;OAEG;IACO,KAAK,CAAC,aAAa,CAAC,OAAmB;QAChD,IAAI,SAAS,GAAU,IAAI,KAAK,CAAC,eAAe,CAAC,CAAA;QAEjD,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;YAC5D,IAAI,CAAC;gBACJ,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;gBACxB,OAAM;YACP,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,SAAS,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;gBAE/D,IAAI,OAAO,GAAG,IAAI,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;oBACnC,wCAAwC;oBACxC,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,GAAG,CAAC,IAAI,OAAO,CAAA;oBAC5C,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;gBACxB,CAAC;YACF,CAAC;QACF,CAAC;QAED,yCAAyC;QACzC,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;IACrC,CAAC;IAQD;;;OAGG;IACO,MAAM,CAAC,OAAmB;QACnC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,aAAa,OAAO,CAAC,MAAM,qCAAqC,CAAC,CAAA;IAC5F,CAAC;IAED;;;OAGG;IACO,WAAW,CAAC,KAAY,EAAE,OAAmB;QACtD,OAAO,CAAC,KAAK,CACZ,IAAI,IAAI,CAAC,IAAI,oBAAoB,OAAO,CAAC,MAAM,kBAAkB,IAAI,CAAC,UAAU,WAAW,EAC3F,KAAK,CAAC,OAAO,CACb,CAAA;IACF,CAAC;IAED;;OAEG;IACO,KAAK,CAAC,EAAU;QACzB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;IACzD,CAAC;IAED;;OAEG;IACH,QAAQ;QAKP,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAA;QACpC,OAAO;YACN,QAAQ,EAAE,KAAK,CAAC,IAAI;YACpB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,UAAU,EAAE,IAAI,CAAC,UAAU;SAC3B,CAAA;IACF,CAAC;CACD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { LogEntry, Transport, TransportConfig } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Console transport configuration
|
|
4
|
+
*/
|
|
5
|
+
export interface ConsoleTransportConfig extends Omit<TransportConfig, 'name'> {
|
|
6
|
+
/** Use structured JSON output */
|
|
7
|
+
structured?: boolean;
|
|
8
|
+
/** Use colors in output (only for non-structured) */
|
|
9
|
+
colors?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Console transport for logging to stdout/stderr
|
|
13
|
+
*/
|
|
14
|
+
export declare class ConsoleTransport implements Transport {
|
|
15
|
+
readonly name = "console";
|
|
16
|
+
readonly config: TransportConfig;
|
|
17
|
+
private structured;
|
|
18
|
+
private colors;
|
|
19
|
+
constructor(config?: ConsoleTransportConfig);
|
|
20
|
+
log(entry: LogEntry): void;
|
|
21
|
+
/**
|
|
22
|
+
* Update configuration
|
|
23
|
+
*/
|
|
24
|
+
setStructured(structured: boolean): void;
|
|
25
|
+
setColors(colors: boolean): void;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=console.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../src/transports/console.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAY,SAAS,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAwD9E;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC;IAC5E,iCAAiC;IACjC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,qDAAqD;IACrD,MAAM,CAAC,EAAE,OAAO,CAAA;CAChB;AAED;;GAEG;AACH,qBAAa,gBAAiB,YAAW,SAAS;IACjD,QAAQ,CAAC,IAAI,aAAY;IACzB,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAA;IAChC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,GAAE,sBAA2B;IAW/C,GAAG,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAS1B;;OAEG;IACH,aAAa,CAAC,UAAU,EAAE,OAAO,GAAG,IAAI;IAIxC,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;CAGhC"}
|