@statly/observe 1.0.0 → 1.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.
@@ -0,0 +1,671 @@
1
+ /**
2
+ * Logger Types
3
+ * Type definitions for the Statly Observe logging framework
4
+ */
5
+ type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal' | 'audit';
6
+ declare const LOG_LEVELS: Record<LogLevel, number>;
7
+ type LevelSet = 'default' | 'extended' | LogLevel[];
8
+ declare const DEFAULT_LEVELS: LogLevel[];
9
+ declare const EXTENDED_LEVELS: LogLevel[];
10
+ interface LogEntry {
11
+ level: LogLevel;
12
+ message: string;
13
+ timestamp: number;
14
+ loggerName?: string;
15
+ context?: Record<string, unknown>;
16
+ tags?: Record<string, string>;
17
+ source?: {
18
+ file?: string;
19
+ line?: number;
20
+ function?: string;
21
+ };
22
+ traceId?: string;
23
+ spanId?: string;
24
+ sessionId?: string;
25
+ environment?: string;
26
+ release?: string;
27
+ sdkName?: string;
28
+ sdkVersion?: string;
29
+ }
30
+ interface ConsoleDestinationConfig {
31
+ enabled?: boolean;
32
+ colors?: boolean;
33
+ format?: 'pretty' | 'json';
34
+ timestamps?: boolean;
35
+ levels?: LogLevel[];
36
+ }
37
+ interface FileDestinationConfig {
38
+ enabled?: boolean;
39
+ path: string;
40
+ format?: 'json' | 'text';
41
+ rotation?: FileRotationConfig;
42
+ levels?: LogLevel[];
43
+ }
44
+ interface FileRotationConfig {
45
+ type: 'size' | 'time';
46
+ maxSize?: string;
47
+ maxFiles?: number;
48
+ interval?: 'hourly' | 'daily' | 'weekly';
49
+ retentionDays?: number;
50
+ compress?: boolean;
51
+ }
52
+ interface ObserveDestinationConfig {
53
+ enabled?: boolean;
54
+ batchSize?: number;
55
+ flushInterval?: number;
56
+ sampling?: Partial<Record<LogLevel, number>>;
57
+ levels?: LogLevel[];
58
+ }
59
+ interface ScrubbingConfig {
60
+ enabled?: boolean;
61
+ patterns?: ScrubPattern[];
62
+ customPatterns?: RegExp[];
63
+ allowlist?: string[];
64
+ customScrubber?: (key: string, value: unknown) => unknown;
65
+ }
66
+ type ScrubPattern = 'apiKey' | 'password' | 'token' | 'creditCard' | 'ssn' | 'email' | 'ipAddress' | 'awsKey' | 'privateKey' | 'jwt';
67
+ interface LoggerConfig {
68
+ dsn?: string;
69
+ level?: LogLevel;
70
+ levels?: LevelSet;
71
+ loggerName?: string;
72
+ environment?: string;
73
+ release?: string;
74
+ destinations?: {
75
+ console?: ConsoleDestinationConfig;
76
+ file?: FileDestinationConfig;
77
+ observe?: ObserveDestinationConfig;
78
+ };
79
+ scrubbing?: ScrubbingConfig;
80
+ context?: Record<string, unknown>;
81
+ tags?: Record<string, string>;
82
+ }
83
+ interface Destination {
84
+ name: string;
85
+ write(entry: LogEntry): void | Promise<void>;
86
+ flush?(): Promise<void>;
87
+ close?(): Promise<void>;
88
+ }
89
+ interface ErrorExplanation {
90
+ summary: string;
91
+ possibleCauses: string[];
92
+ stackAnalysis?: string;
93
+ relatedDocs?: string[];
94
+ }
95
+ interface FixSuggestion {
96
+ summary: string;
97
+ suggestedFixes: Array<{
98
+ description: string;
99
+ code?: string;
100
+ confidence: 'high' | 'medium' | 'low';
101
+ }>;
102
+ preventionTips?: string[];
103
+ }
104
+
105
+ /**
106
+ * AI Features for Logger
107
+ * Provides AI-powered error explanation and fix suggestions
108
+ */
109
+
110
+ interface AIConfig {
111
+ enabled?: boolean;
112
+ apiKey?: string;
113
+ model?: string;
114
+ endpoint?: string;
115
+ }
116
+ declare class AIFeatures {
117
+ private config;
118
+ private dsn;
119
+ constructor(dsn: string, config?: AIConfig);
120
+ /**
121
+ * Parse DSN to construct AI endpoint
122
+ */
123
+ private parseEndpoint;
124
+ /**
125
+ * Explain an error using AI
126
+ */
127
+ explainError(error: Error | LogEntry | string): Promise<ErrorExplanation>;
128
+ /**
129
+ * Suggest fixes for an error using AI
130
+ */
131
+ suggestFix(error: Error | LogEntry | string, context?: {
132
+ code?: string;
133
+ file?: string;
134
+ language?: string;
135
+ }): Promise<FixSuggestion>;
136
+ /**
137
+ * Analyze a batch of logs for patterns
138
+ */
139
+ analyzePatterns(logs: LogEntry[]): Promise<{
140
+ patterns: Array<{
141
+ type: string;
142
+ description: string;
143
+ occurrences: number;
144
+ examples: string[];
145
+ }>;
146
+ summary: string;
147
+ recommendations: string[];
148
+ }>;
149
+ /**
150
+ * Normalize error input to a standard format
151
+ */
152
+ private normalizeError;
153
+ /**
154
+ * Set API key for AI features
155
+ */
156
+ setApiKey(apiKey: string): void;
157
+ /**
158
+ * Enable or disable AI features
159
+ */
160
+ setEnabled(enabled: boolean): void;
161
+ /**
162
+ * Check if AI features are enabled
163
+ */
164
+ isEnabled(): boolean;
165
+ }
166
+
167
+ /**
168
+ * Logger Class
169
+ * Main entry point for the Statly Observe logging framework
170
+ */
171
+
172
+ declare class Logger {
173
+ private name;
174
+ private config;
175
+ private minLevel;
176
+ private enabledLevels;
177
+ private destinations;
178
+ private scrubber;
179
+ private ai;
180
+ private context;
181
+ private tags;
182
+ private sessionId?;
183
+ private traceId?;
184
+ private spanId?;
185
+ constructor(config?: LoggerConfig);
186
+ /**
187
+ * Parse level set configuration
188
+ */
189
+ private parseLevelSet;
190
+ /**
191
+ * Initialize destinations from config
192
+ */
193
+ private initDestinations;
194
+ /**
195
+ * Generate a unique ID
196
+ */
197
+ private generateId;
198
+ /**
199
+ * Check if a level should be logged
200
+ */
201
+ private shouldLog;
202
+ /**
203
+ * Get source location (if available)
204
+ */
205
+ private getSource;
206
+ /**
207
+ * Create a log entry
208
+ */
209
+ private createEntry;
210
+ /**
211
+ * Write to all destinations
212
+ */
213
+ private write;
214
+ /**
215
+ * Log a trace message
216
+ */
217
+ trace(message: string, context?: Record<string, unknown>): void;
218
+ /**
219
+ * Log a debug message
220
+ */
221
+ debug(message: string, context?: Record<string, unknown>): void;
222
+ /**
223
+ * Log an info message
224
+ */
225
+ info(message: string, context?: Record<string, unknown>): void;
226
+ /**
227
+ * Log a warning message
228
+ */
229
+ warn(message: string, context?: Record<string, unknown>): void;
230
+ /**
231
+ * Log an error message
232
+ */
233
+ error(message: string, context?: Record<string, unknown>): void;
234
+ error(error: Error, context?: Record<string, unknown>): void;
235
+ /**
236
+ * Log a fatal message
237
+ */
238
+ fatal(message: string, context?: Record<string, unknown>): void;
239
+ fatal(error: Error, context?: Record<string, unknown>): void;
240
+ /**
241
+ * Log an audit message (always logged, never sampled)
242
+ */
243
+ audit(message: string, context?: Record<string, unknown>): void;
244
+ /**
245
+ * Log at a specific level
246
+ */
247
+ log(level: LogLevel, message: string, context?: Record<string, unknown>): void;
248
+ /**
249
+ * Set persistent context
250
+ */
251
+ setContext(context: Record<string, unknown>): void;
252
+ /**
253
+ * Clear context
254
+ */
255
+ clearContext(): void;
256
+ /**
257
+ * Set a tag
258
+ */
259
+ setTag(key: string, value: string): void;
260
+ /**
261
+ * Set multiple tags
262
+ */
263
+ setTags(tags: Record<string, string>): void;
264
+ /**
265
+ * Clear tags
266
+ */
267
+ clearTags(): void;
268
+ /**
269
+ * Set trace ID for distributed tracing
270
+ */
271
+ setTraceId(traceId: string): void;
272
+ /**
273
+ * Set span ID
274
+ */
275
+ setSpanId(spanId: string): void;
276
+ /**
277
+ * Clear tracing context
278
+ */
279
+ clearTracing(): void;
280
+ /**
281
+ * Create a child logger with additional context
282
+ */
283
+ child(options?: {
284
+ name?: string;
285
+ context?: Record<string, unknown>;
286
+ tags?: Record<string, string>;
287
+ }): Logger;
288
+ /**
289
+ * Explain an error using AI
290
+ */
291
+ explainError(error: Error | string): Promise<ErrorExplanation>;
292
+ /**
293
+ * Suggest fixes for an error using AI
294
+ */
295
+ suggestFix(error: Error | string, context?: {
296
+ code?: string;
297
+ file?: string;
298
+ language?: string;
299
+ }): Promise<FixSuggestion>;
300
+ /**
301
+ * Configure AI features
302
+ */
303
+ configureAI(config: AIConfig): void;
304
+ /**
305
+ * Add a custom destination
306
+ */
307
+ addDestination(destination: Destination): void;
308
+ /**
309
+ * Remove a destination by name
310
+ */
311
+ removeDestination(name: string): void;
312
+ /**
313
+ * Get all destinations
314
+ */
315
+ getDestinations(): Destination[];
316
+ /**
317
+ * Set minimum log level
318
+ */
319
+ setLevel(level: LogLevel): void;
320
+ /**
321
+ * Get current minimum level
322
+ */
323
+ getLevel(): LogLevel;
324
+ /**
325
+ * Check if a level is enabled
326
+ */
327
+ isLevelEnabled(level: LogLevel): boolean;
328
+ /**
329
+ * Flush all destinations
330
+ */
331
+ flush(): Promise<void>;
332
+ /**
333
+ * Close the logger and all destinations
334
+ */
335
+ close(): Promise<void>;
336
+ /**
337
+ * Get logger name
338
+ */
339
+ getName(): string;
340
+ /**
341
+ * Get session ID
342
+ */
343
+ getSessionId(): string | undefined;
344
+ }
345
+
346
+ /**
347
+ * Secret Scrubber
348
+ * Detects and redacts sensitive data from log entries
349
+ */
350
+
351
+ declare class Scrubber {
352
+ private enabled;
353
+ private patterns;
354
+ private customPatterns;
355
+ private allowlist;
356
+ private customScrubber?;
357
+ constructor(config?: ScrubbingConfig);
358
+ /**
359
+ * Scrub sensitive data from a value
360
+ */
361
+ scrub<T>(value: T): T;
362
+ /**
363
+ * Scrub a log message string
364
+ */
365
+ scrubMessage(message: string): string;
366
+ /**
367
+ * Recursively scrub sensitive data
368
+ */
369
+ private scrubValue;
370
+ /**
371
+ * Scrub sensitive patterns from a string
372
+ */
373
+ private scrubString;
374
+ /**
375
+ * Scrub sensitive data from an object
376
+ */
377
+ private scrubObject;
378
+ /**
379
+ * Add a custom pattern at runtime
380
+ */
381
+ addPattern(pattern: RegExp): void;
382
+ /**
383
+ * Add a key to the allowlist
384
+ */
385
+ addToAllowlist(key: string): void;
386
+ /**
387
+ * Check if scrubbing is enabled
388
+ */
389
+ isEnabled(): boolean;
390
+ /**
391
+ * Enable or disable scrubbing
392
+ */
393
+ setEnabled(enabled: boolean): void;
394
+ }
395
+
396
+ /**
397
+ * Console Destination
398
+ * Outputs log entries to the console with formatting and colors
399
+ */
400
+
401
+ declare class ConsoleDestination implements Destination {
402
+ readonly name = "console";
403
+ private config;
404
+ private minLevel;
405
+ constructor(config?: ConsoleDestinationConfig);
406
+ /**
407
+ * Write a log entry to the console
408
+ */
409
+ write(entry: LogEntry): void;
410
+ /**
411
+ * Check if the environment supports colors
412
+ */
413
+ private supportsColors;
414
+ /**
415
+ * Set minimum log level
416
+ */
417
+ setMinLevel(level: LogLevel): void;
418
+ /**
419
+ * Enable or disable the destination
420
+ */
421
+ setEnabled(enabled: boolean): void;
422
+ /**
423
+ * Set color mode
424
+ */
425
+ setColors(enabled: boolean): void;
426
+ /**
427
+ * Set output format
428
+ */
429
+ setFormat(format: 'pretty' | 'json'): void;
430
+ }
431
+
432
+ /**
433
+ * Observe Destination
434
+ * Sends log entries to Statly Observe backend with batching and sampling
435
+ */
436
+
437
+ declare class ObserveDestination implements Destination {
438
+ readonly name = "observe";
439
+ private config;
440
+ private dsn;
441
+ private endpoint;
442
+ private queue;
443
+ private isFlushing;
444
+ private flushTimer?;
445
+ private minLevel;
446
+ constructor(dsn: string, config?: ObserveDestinationConfig);
447
+ /**
448
+ * Parse DSN to construct endpoint
449
+ */
450
+ private parseEndpoint;
451
+ /**
452
+ * Start the flush timer
453
+ */
454
+ private startFlushTimer;
455
+ /**
456
+ * Write a log entry (queues for batching)
457
+ */
458
+ write(entry: LogEntry): void;
459
+ /**
460
+ * Flush all queued entries to the server
461
+ */
462
+ flush(): Promise<void>;
463
+ /**
464
+ * Send a batch of entries to the server
465
+ */
466
+ private sendBatch;
467
+ /**
468
+ * Close the destination
469
+ */
470
+ close(): Promise<void>;
471
+ /**
472
+ * Set minimum log level
473
+ */
474
+ setMinLevel(level: LogLevel): void;
475
+ /**
476
+ * Set sampling rate for a level
477
+ */
478
+ setSamplingRate(level: LogLevel, rate: number): void;
479
+ /**
480
+ * Enable or disable the destination
481
+ */
482
+ setEnabled(enabled: boolean): void;
483
+ /**
484
+ * Get the current queue size
485
+ */
486
+ getQueueSize(): number;
487
+ }
488
+
489
+ /**
490
+ * File Destination
491
+ * Writes log entries to files with rotation support (Node.js only)
492
+ */
493
+
494
+ declare class FileDestination implements Destination {
495
+ readonly name = "file";
496
+ private config;
497
+ private minLevel;
498
+ private buffer;
499
+ private currentSize;
500
+ private maxSize;
501
+ private lastRotation;
502
+ private rotationInterval;
503
+ private writePromise;
504
+ private fs;
505
+ constructor(config: FileDestinationConfig);
506
+ /**
507
+ * Initialize file system operations
508
+ */
509
+ private initFileSystem;
510
+ /**
511
+ * Get rotation interval in milliseconds
512
+ */
513
+ private getRotationInterval;
514
+ /**
515
+ * Write a log entry
516
+ */
517
+ write(entry: LogEntry): void;
518
+ /**
519
+ * Schedule a buffered write
520
+ */
521
+ private scheduleWrite;
522
+ /**
523
+ * Write buffer to file
524
+ */
525
+ private writeBuffer;
526
+ /**
527
+ * Check if rotation is needed
528
+ */
529
+ private checkRotation;
530
+ /**
531
+ * Rotate the log file
532
+ */
533
+ private rotate;
534
+ /**
535
+ * Clean up old rotated files
536
+ */
537
+ private cleanupOldFiles;
538
+ /**
539
+ * Flush buffered writes
540
+ */
541
+ flush(): Promise<void>;
542
+ /**
543
+ * Close the destination
544
+ */
545
+ close(): Promise<void>;
546
+ /**
547
+ * Set minimum log level
548
+ */
549
+ setMinLevel(level: LogLevel): void;
550
+ /**
551
+ * Enable or disable the destination
552
+ */
553
+ setEnabled(enabled: boolean): void;
554
+ }
555
+
556
+ /**
557
+ * Secret Scrubbing Patterns
558
+ * Built-in regex patterns for detecting and redacting sensitive data
559
+ */
560
+
561
+ declare const SENSITIVE_KEYS: Set<string>;
562
+ declare const SCRUB_PATTERNS: Record<ScrubPattern, {
563
+ regex: RegExp;
564
+ description: string;
565
+ }>;
566
+ declare const REDACTED = "[REDACTED]";
567
+ /**
568
+ * Check if a key name indicates sensitive data
569
+ */
570
+ declare function isSensitiveKey(key: string): boolean;
571
+
572
+ /**
573
+ * Console Formatter
574
+ * Formats log entries for console output with colors
575
+ */
576
+
577
+ interface ConsoleFormatOptions {
578
+ colors?: boolean;
579
+ timestamps?: boolean;
580
+ showLevel?: boolean;
581
+ showLogger?: boolean;
582
+ showContext?: boolean;
583
+ showSource?: boolean;
584
+ }
585
+ /**
586
+ * Format a log entry for pretty console output
587
+ */
588
+ declare function formatPretty(entry: LogEntry, options?: ConsoleFormatOptions): string;
589
+ /**
590
+ * Format a log entry as JSON
591
+ */
592
+ declare function formatJson(entry: LogEntry): string;
593
+ /**
594
+ * Format a log entry as JSON with pretty printing
595
+ */
596
+ declare function formatJsonPretty(entry: LogEntry): string;
597
+ /**
598
+ * Get the native console method for a log level
599
+ */
600
+ declare function getConsoleMethod(level: LogLevel): 'log' | 'info' | 'warn' | 'error' | 'debug' | 'trace';
601
+
602
+ /**
603
+ * Statly Observe Logger
604
+ *
605
+ * A comprehensive logging framework with multi-destination output,
606
+ * secret scrubbing, sampling, and AI-powered analysis.
607
+ *
608
+ * @example
609
+ * ```typescript
610
+ * import { Logger } from '@statly/observe';
611
+ *
612
+ * // Create a logger with default settings
613
+ * const logger = new Logger({
614
+ * dsn: 'https://sk_live_xxx@statly.live/your-org',
615
+ * loggerName: 'my-app',
616
+ * environment: 'production',
617
+ * release: '1.0.0',
618
+ * });
619
+ *
620
+ * // Basic logging
621
+ * logger.info('Application started');
622
+ * logger.debug('Processing request', { requestId: '123' });
623
+ * logger.warn('Deprecated API used', { endpoint: '/old-api' });
624
+ * logger.error('Failed to process', { error: 'timeout' });
625
+ *
626
+ * // Log with Error object
627
+ * try {
628
+ * riskyOperation();
629
+ * } catch (err) {
630
+ * logger.error(err);
631
+ * }
632
+ *
633
+ * // Audit logging (always logged, never sampled)
634
+ * logger.audit('User login', { userId: '123', ip: '10.0.0.1' });
635
+ *
636
+ * // AI-powered analysis
637
+ * const explanation = await logger.explainError(error);
638
+ * const fix = await logger.suggestFix(error);
639
+ *
640
+ * // Child loggers
641
+ * const requestLogger = logger.child({
642
+ * name: 'request',
643
+ * context: { requestId: '456' },
644
+ * });
645
+ * requestLogger.info('Handling request');
646
+ *
647
+ * // Configure destinations
648
+ * logger.addDestination(myCustomDestination);
649
+ *
650
+ * // Cleanup
651
+ * await logger.close();
652
+ * ```
653
+ */
654
+
655
+ /**
656
+ * Get or create the default logger instance
657
+ */
658
+ declare function getDefaultLogger(): Logger;
659
+ /**
660
+ * Set the default logger instance
661
+ */
662
+ declare function setDefaultLogger(logger: Logger): void;
663
+ declare function trace(message: string, context?: Record<string, unknown>): void;
664
+ declare function debug(message: string, context?: Record<string, unknown>): void;
665
+ declare function info(message: string, context?: Record<string, unknown>): void;
666
+ declare function warn(message: string, context?: Record<string, unknown>): void;
667
+ declare function error(messageOrError: string | Error, context?: Record<string, unknown>): void;
668
+ declare function fatal(messageOrError: string | Error, context?: Record<string, unknown>): void;
669
+ declare function audit(message: string, context?: Record<string, unknown>): void;
670
+
671
+ export { AIFeatures, ConsoleDestination, type ConsoleDestinationConfig, DEFAULT_LEVELS, type Destination, EXTENDED_LEVELS, type ErrorExplanation, FileDestination, type FileDestinationConfig, type FileRotationConfig, type FixSuggestion, LOG_LEVELS, type LevelSet, type LogEntry, type LogLevel, Logger, type LoggerConfig, ObserveDestination, type ObserveDestinationConfig, REDACTED, SCRUB_PATTERNS, SENSITIVE_KEYS, type ScrubPattern, Scrubber, type ScrubbingConfig, audit, debug, error, fatal, formatJson, formatJsonPretty, formatPretty, getConsoleMethod, getDefaultLogger, info, isSensitiveKey, setDefaultLogger, trace, warn };