@logtide/sdk-node 0.2.1 → 0.2.2
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/index.cjs +86 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -2
- package/dist/index.d.ts +33 -2
- package/dist/index.js +86 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -42,25 +42,98 @@ var CircuitBreaker = class {
|
|
|
42
42
|
return this.state;
|
|
43
43
|
}
|
|
44
44
|
};
|
|
45
|
+
function parseNodeStackTrace(stack) {
|
|
46
|
+
if (!stack) return [];
|
|
47
|
+
const frames = [];
|
|
48
|
+
const lines = stack.split("\n");
|
|
49
|
+
for (const line of lines) {
|
|
50
|
+
const trimmed = line.trim();
|
|
51
|
+
if (!trimmed.startsWith("at ")) continue;
|
|
52
|
+
const match1 = trimmed.match(/^at\s+(.+?)\s+\((.+):(\d+):(\d+)\)$/);
|
|
53
|
+
if (match1) {
|
|
54
|
+
frames.push({
|
|
55
|
+
function: match1[1],
|
|
56
|
+
file: match1[2],
|
|
57
|
+
line: parseInt(match1[3], 10),
|
|
58
|
+
column: parseInt(match1[4], 10)
|
|
59
|
+
});
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const match2 = trimmed.match(/^at\s+(.+):(\d+):(\d+)$/);
|
|
63
|
+
if (match2) {
|
|
64
|
+
frames.push({
|
|
65
|
+
file: match2[1],
|
|
66
|
+
line: parseInt(match2[2], 10),
|
|
67
|
+
column: parseInt(match2[3], 10)
|
|
68
|
+
});
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const match3 = trimmed.match(/^at\s+(.+?)\s+\((.+)\)$/);
|
|
72
|
+
if (match3) {
|
|
73
|
+
frames.push({
|
|
74
|
+
function: match3[1],
|
|
75
|
+
file: match3[2]
|
|
76
|
+
});
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const match4 = trimmed.match(/^at\s+(.+)$/);
|
|
80
|
+
if (match4) {
|
|
81
|
+
frames.push({
|
|
82
|
+
function: match4[1]
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return frames;
|
|
87
|
+
}
|
|
45
88
|
function serializeError(error) {
|
|
46
89
|
if (error instanceof Error) {
|
|
47
90
|
const result = {
|
|
48
|
-
|
|
91
|
+
type: error.name,
|
|
49
92
|
message: error.message,
|
|
50
|
-
|
|
93
|
+
language: "nodejs",
|
|
94
|
+
stacktrace: parseNodeStackTrace(error.stack),
|
|
95
|
+
raw: error.stack
|
|
51
96
|
};
|
|
52
97
|
if (error.cause) {
|
|
53
98
|
result.cause = serializeError(error.cause);
|
|
54
99
|
}
|
|
100
|
+
const errorMetadata = {};
|
|
101
|
+
const standardProps = ["name", "message", "stack", "cause"];
|
|
102
|
+
for (const key of Object.keys(error)) {
|
|
103
|
+
if (!standardProps.includes(key)) {
|
|
104
|
+
errorMetadata[key] = error[key];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if ("code" in error) errorMetadata.code = error.code;
|
|
108
|
+
if ("errno" in error) errorMetadata.errno = error.errno;
|
|
109
|
+
if ("syscall" in error) errorMetadata.syscall = error.syscall;
|
|
110
|
+
if ("path" in error) errorMetadata.path = error.path;
|
|
111
|
+
if (Object.keys(errorMetadata).length > 0) {
|
|
112
|
+
result.metadata = errorMetadata;
|
|
113
|
+
}
|
|
55
114
|
return result;
|
|
56
115
|
}
|
|
57
116
|
if (typeof error === "string") {
|
|
58
|
-
return {
|
|
117
|
+
return {
|
|
118
|
+
type: "Error",
|
|
119
|
+
message: error,
|
|
120
|
+
language: "nodejs"
|
|
121
|
+
};
|
|
59
122
|
}
|
|
60
123
|
if (typeof error === "object" && error !== null) {
|
|
61
|
-
|
|
124
|
+
const obj = error;
|
|
125
|
+
return {
|
|
126
|
+
type: typeof obj.type === "string" ? obj.type : typeof obj.name === "string" ? obj.name : "Error",
|
|
127
|
+
message: typeof obj.message === "string" ? obj.message : JSON.stringify(error),
|
|
128
|
+
language: "nodejs",
|
|
129
|
+
metadata: obj
|
|
130
|
+
};
|
|
62
131
|
}
|
|
63
|
-
return {
|
|
132
|
+
return {
|
|
133
|
+
type: "Error",
|
|
134
|
+
message: String(error),
|
|
135
|
+
language: "nodejs"
|
|
136
|
+
};
|
|
64
137
|
}
|
|
65
138
|
var LogTideClient = class {
|
|
66
139
|
apiUrl;
|
|
@@ -244,6 +317,12 @@ var LogTideClient = class {
|
|
|
244
317
|
return arg;
|
|
245
318
|
});
|
|
246
319
|
}
|
|
320
|
+
if (level === "error" || level === "critical") {
|
|
321
|
+
const errorArg = args.find((arg) => arg instanceof Error);
|
|
322
|
+
if (errorArg instanceof Error) {
|
|
323
|
+
metadata.exception = serializeError(errorArg);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
247
326
|
this.log({
|
|
248
327
|
service: config.service,
|
|
249
328
|
level,
|
|
@@ -399,7 +478,7 @@ var LogTideClient = class {
|
|
|
399
478
|
error(service, message, metadataOrError) {
|
|
400
479
|
let metadata = {};
|
|
401
480
|
if (metadataOrError instanceof Error) {
|
|
402
|
-
metadata = {
|
|
481
|
+
metadata = { exception: serializeError(metadataOrError) };
|
|
403
482
|
} else if (metadataOrError) {
|
|
404
483
|
metadata = metadataOrError;
|
|
405
484
|
}
|
|
@@ -408,7 +487,7 @@ var LogTideClient = class {
|
|
|
408
487
|
critical(service, message, metadataOrError) {
|
|
409
488
|
let metadata = {};
|
|
410
489
|
if (metadataOrError instanceof Error) {
|
|
411
|
-
metadata = {
|
|
490
|
+
metadata = { exception: serializeError(metadataOrError) };
|
|
412
491
|
} else if (metadataOrError) {
|
|
413
492
|
metadata = metadataOrError;
|
|
414
493
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":["randomUUID"],"mappings":"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","file":"index.cjs","sourcesContent":["import { randomUUID } from 'crypto';\n\n// ==================== Types ====================\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'critical';\n\nexport interface ConsoleInterceptOptions {\n enabled: boolean;\n service?: string;\n preserveOriginal?: boolean;\n includeStackTrace?: boolean;\n levels?: {\n log?: boolean;\n info?: boolean;\n warn?: boolean;\n error?: boolean;\n debug?: boolean;\n };\n}\n\nexport interface PayloadLimitsOptions {\n /** Maximum size in bytes for a single field value (default: 10KB) */\n maxFieldSize?: number;\n /** Maximum size in bytes for the entire log entry (default: 100KB) */\n maxLogSize?: number;\n /** Fields to exclude from metadata (e.g., ['body', 'requestBody', 'responseBody']) */\n excludeFields?: string[];\n /** Marker to append when a field is truncated (default: '...[TRUNCATED]') */\n truncationMarker?: string;\n}\n\nexport interface LogTideClientOptions {\n apiUrl: string;\n apiKey: string;\n batchSize?: number;\n flushInterval?: number;\n maxBufferSize?: number;\n maxRetries?: number;\n retryDelayMs?: number;\n circuitBreakerThreshold?: number;\n circuitBreakerResetMs?: number;\n enableMetrics?: boolean;\n debug?: boolean;\n globalMetadata?: Record<string, unknown>;\n autoTraceId?: boolean;\n interceptConsole?: ConsoleInterceptOptions;\n /** Payload size limits to prevent 413 errors */\n payloadLimits?: PayloadLimitsOptions;\n}\n\nexport interface LogEntry {\n service: string;\n level: LogLevel;\n message: string;\n time?: string;\n metadata?: Record<string, unknown>;\n trace_id?: string;\n}\n\nexport interface InternalLogEntry extends LogEntry {\n time: string;\n}\n\nexport interface QueryOptions {\n service?: string;\n level?: LogLevel;\n from?: Date | string;\n to?: Date | string;\n q?: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface LogsResponse {\n logs: InternalLogEntry[];\n total: number;\n limit: number;\n offset: number;\n}\n\nexport interface AggregatedStatsOptions {\n from: Date | string;\n to: Date | string;\n interval?: '1m' | '5m' | '1h' | '1d';\n service?: string;\n}\n\nexport interface AggregatedStatsResponse {\n timeseries: Array<{\n bucket: string;\n total: number;\n by_level: Record<string, number>;\n }>;\n top_services: Array<{ service: string; count: number }>;\n top_errors: Array<{ message: string; count: number }>;\n}\n\nexport interface ClientMetrics {\n logsSent: number;\n logsDropped: number;\n errors: number;\n retries: number;\n avgLatencyMs: number;\n circuitBreakerTrips: number;\n}\n\nexport interface StreamOptions {\n service?: string;\n level?: LogLevel;\n onLog: (log: InternalLogEntry) => void;\n onError?: (error: Error) => void;\n}\n\n// ==================== Circuit Breaker ====================\n\nenum CircuitState {\n CLOSED = 'CLOSED',\n OPEN = 'OPEN',\n HALF_OPEN = 'HALF_OPEN',\n}\n\nclass CircuitBreaker {\n private state: CircuitState = CircuitState.CLOSED;\n private failureCount = 0;\n private lastFailureTime: number | null = null;\n\n constructor(\n private threshold: number,\n private resetMs: number,\n ) {}\n\n recordSuccess() {\n this.failureCount = 0;\n this.state = CircuitState.CLOSED;\n }\n\n recordFailure() {\n this.failureCount++;\n this.lastFailureTime = Date.now();\n\n if (this.failureCount >= this.threshold) {\n this.state = CircuitState.OPEN;\n }\n }\n\n canAttempt(): boolean {\n if (this.state === CircuitState.CLOSED) {\n return true;\n }\n\n if (this.state === CircuitState.OPEN) {\n const now = Date.now();\n if (this.lastFailureTime && now - this.lastFailureTime >= this.resetMs) {\n this.state = CircuitState.HALF_OPEN;\n return true;\n }\n return false;\n }\n\n // HALF_OPEN state - allow one attempt\n return true;\n }\n\n getState(): CircuitState {\n return this.state;\n }\n}\n\n\n// ==================== Error Serialization ====================\n\nexport function serializeError(error: unknown): Record<string, unknown> {\n if (error instanceof Error) {\n const result: Record<string, unknown> = {\n name: error.name,\n message: error.message,\n stack: error.stack,\n };\n\n if (error.cause) {\n result.cause = serializeError(error.cause);\n }\n\n return result;\n }\n\n if (typeof error === 'string') {\n return { message: error };\n }\n\n if (typeof error === 'object' && error !== null) {\n return error as Record<string, unknown>;\n }\n\n return { message: String(error) };\n}\n\n// ==================== Main Client ====================\n\nexport class LogTideClient {\n private apiUrl: string;\n private apiKey: string;\n private batchSize: number;\n private flushInterval: number;\n private maxBufferSize: number;\n private maxRetries: number;\n private retryDelayMs: number;\n private enableMetrics: boolean;\n private debugMode: boolean;\n private globalMetadata: Record<string, unknown>;\n private autoTraceId: boolean;\n\n private buffer: InternalLogEntry[] = [];\n private timer: NodeJS.Timeout | null = null;\n private circuitBreaker: CircuitBreaker;\n\n // Metrics\n private metrics: ClientMetrics = {\n logsSent: 0,\n logsDropped: 0,\n errors: 0,\n retries: 0,\n avgLatencyMs: 0,\n circuitBreakerTrips: 0,\n };\n private latencies: number[] = [];\n\n // Context tracking\n private currentTraceId: string | null = null;\n\n // Console interception\n private consoleInterceptOptions: ConsoleInterceptOptions | null = null;\n private originalConsole: {\n log: typeof console.log;\n info: typeof console.info;\n warn: typeof console.warn;\n error: typeof console.error;\n debug: typeof console.debug;\n } | null = null;\n\n // Payload limits\n private payloadLimits: Required<PayloadLimitsOptions>;\n\n constructor(options: LogTideClientOptions) {\n this.apiUrl = options.apiUrl.replace(/\\/$/, '');\n this.apiKey = options.apiKey;\n this.batchSize = options.batchSize || 100;\n this.flushInterval = options.flushInterval || 5000;\n this.maxBufferSize = options.maxBufferSize || 10000;\n this.maxRetries = options.maxRetries || 3;\n this.retryDelayMs = options.retryDelayMs || 1000;\n this.enableMetrics = options.enableMetrics ?? true;\n this.debugMode = options.debug ?? false;\n this.globalMetadata = options.globalMetadata || {};\n this.autoTraceId = options.autoTraceId ?? false;\n\n this.circuitBreaker = new CircuitBreaker(\n options.circuitBreakerThreshold || 5,\n options.circuitBreakerResetMs || 30000,\n );\n\n // Initialize payload limits with defaults\n this.payloadLimits = {\n maxFieldSize: options.payloadLimits?.maxFieldSize ?? 10 * 1024, // 10KB\n maxLogSize: options.payloadLimits?.maxLogSize ?? 100 * 1024, // 100KB\n excludeFields: options.payloadLimits?.excludeFields ?? [],\n truncationMarker: options.payloadLimits?.truncationMarker ?? '...[TRUNCATED]',\n };\n\n this.startFlushTimer();\n\n // Start console interception if configured\n if (options.interceptConsole?.enabled) {\n this.startConsoleInterception(options.interceptConsole);\n }\n }\n\n // ==================== Context Helpers ====================\n\n /**\n * Set trace ID for subsequent logs\n */\n setTraceId(traceId: string | null) {\n this.currentTraceId = traceId;\n }\n\n /**\n * Get current trace ID\n */\n getTraceId(): string | null {\n return this.currentTraceId;\n }\n\n /**\n * Execute function with a specific trace ID context\n */\n withTraceId<T>(traceId: string, fn: () => T): T {\n const previousTraceId = this.currentTraceId;\n this.currentTraceId = traceId;\n try {\n return fn();\n } finally {\n this.currentTraceId = previousTraceId;\n }\n }\n\n /**\n * Execute function with a new auto-generated trace ID\n */\n withNewTraceId<T>(fn: () => T): T {\n return this.withTraceId(randomUUID(), fn);\n }\n\n // ==================== Console Interception ====================\n\n /**\n * Start intercepting console methods and forward them to LogTide\n */\n startConsoleInterception(options?: Partial<ConsoleInterceptOptions>) {\n if (this.originalConsole) {\n // Already intercepting\n return;\n }\n\n const config: ConsoleInterceptOptions = {\n enabled: true,\n service: options?.service ?? 'console',\n preserveOriginal: options?.preserveOriginal ?? true,\n includeStackTrace: options?.includeStackTrace ?? false,\n levels: {\n log: options?.levels?.log ?? true,\n info: options?.levels?.info ?? true,\n warn: options?.levels?.warn ?? true,\n error: options?.levels?.error ?? true,\n debug: options?.levels?.debug ?? true,\n },\n };\n\n this.consoleInterceptOptions = config;\n\n // Save original console methods\n this.originalConsole = {\n log: console.log.bind(console),\n info: console.info.bind(console),\n warn: console.warn.bind(console),\n error: console.error.bind(console),\n debug: console.debug.bind(console),\n };\n\n const createInterceptor = (\n method: 'log' | 'info' | 'warn' | 'error' | 'debug',\n level: LogLevel,\n ) => {\n const original = this.originalConsole![method];\n\n return (...args: unknown[]) => {\n // Always call original if preserveOriginal is true\n if (config.preserveOriginal) {\n original(...args);\n }\n\n // Skip if this method is not configured for interception\n if (!config.levels?.[method]) {\n return;\n }\n\n // Skip internal LogTide logs to prevent infinite loops\n const message = args\n .map((arg) => {\n if (typeof arg === 'string') return arg;\n if (arg instanceof Error) return arg.message;\n try {\n return JSON.stringify(arg);\n } catch {\n return String(arg);\n }\n })\n .join(' ');\n\n if (message.startsWith('[LogTide]')) {\n return;\n }\n\n // Build metadata\n const metadata: Record<string, unknown> = {\n source: 'console',\n originalMethod: method,\n };\n\n // Include stack trace if configured\n if (config.includeStackTrace) {\n const stack = new Error().stack;\n if (stack) {\n // Remove the first two lines (Error + this interceptor function)\n const stackLines = stack.split('\\n').slice(2);\n metadata.stackTrace = stackLines.join('\\n');\n\n // Extract caller location from first relevant stack line\n const callerLine = stackLines[0];\n if (callerLine) {\n const match = callerLine.match(/at\\s+(.+?)\\s+\\((.+):(\\d+):(\\d+)\\)/);\n if (match) {\n metadata.caller = {\n function: match[1],\n file: match[2],\n line: parseInt(match[3], 10),\n column: parseInt(match[4], 10),\n };\n } else {\n // Try alternative format: \"at file:line:column\"\n const altMatch = callerLine.match(/at\\s+(.+):(\\d+):(\\d+)/);\n if (altMatch) {\n metadata.caller = {\n file: altMatch[1],\n line: parseInt(altMatch[2], 10),\n column: parseInt(altMatch[3], 10),\n };\n }\n }\n }\n }\n }\n\n // Include raw arguments for complex objects\n if (args.length > 1 || (args.length === 1 && typeof args[0] !== 'string')) {\n metadata.args = args.map((arg) => {\n if (arg instanceof Error) {\n return serializeError(arg);\n }\n return arg;\n });\n }\n\n // Log to LogTide\n this.log({\n service: config.service!,\n level,\n message,\n metadata,\n });\n };\n };\n\n // Replace console methods\n console.log = createInterceptor('log', 'info');\n console.info = createInterceptor('info', 'info');\n console.warn = createInterceptor('warn', 'warn');\n console.error = createInterceptor('error', 'error');\n console.debug = createInterceptor('debug', 'debug');\n\n if (this.debugMode) {\n this.originalConsole.log('[LogTide] Console interception started');\n }\n }\n\n /**\n * Stop intercepting console methods and restore originals\n */\n stopConsoleInterception() {\n if (!this.originalConsole) {\n return;\n }\n\n // Restore original console methods\n console.log = this.originalConsole.log;\n console.info = this.originalConsole.info;\n console.warn = this.originalConsole.warn;\n console.error = this.originalConsole.error;\n console.debug = this.originalConsole.debug;\n\n if (this.debugMode) {\n console.log('[LogTide] Console interception stopped');\n }\n\n this.originalConsole = null;\n this.consoleInterceptOptions = null;\n }\n\n /**\n * Check if console interception is active\n */\n isConsoleInterceptionActive(): boolean {\n return this.originalConsole !== null;\n }\n\n // ==================== Payload Processing ====================\n\n /**\n * Check if a string looks like base64 encoded data\n */\n private looksLikeBase64(str: string): boolean {\n if (typeof str !== 'string' || str.length < 100) return false;\n // Check for common base64 patterns: data URLs or long base64 strings\n if (str.startsWith('data:')) return true;\n // Check if it's a long string with only base64 characters\n const base64Regex = /^[A-Za-z0-9+/=]{100,}$/;\n return base64Regex.test(str.replace(/\\s/g, ''));\n }\n\n /**\n * Process a value for payload limits (truncation, base64 removal, etc.)\n */\n private processValue(value: unknown, fieldPath: string): unknown {\n // Check if this field should be excluded\n const fieldName = fieldPath.split('.').pop() || fieldPath;\n if (this.payloadLimits.excludeFields.includes(fieldName)) {\n return '[EXCLUDED]';\n }\n\n if (value === null || value === undefined) {\n return value;\n }\n\n if (typeof value === 'string') {\n // Check for base64 data\n if (this.looksLikeBase64(value)) {\n return '[BASE64 DATA REMOVED]';\n }\n // Truncate if too long\n if (value.length > this.payloadLimits.maxFieldSize) {\n return value.substring(0, this.payloadLimits.maxFieldSize) + this.payloadLimits.truncationMarker;\n }\n return value;\n }\n\n if (Array.isArray(value)) {\n return value.map((item, index) => this.processValue(item, `${fieldPath}[${index}]`));\n }\n\n if (typeof value === 'object') {\n const processed: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n processed[key] = this.processValue(val, `${fieldPath}.${key}`);\n }\n return processed;\n }\n\n return value;\n }\n\n /**\n * Process metadata to apply payload limits\n */\n private processMetadata(metadata: Record<string, unknown> | undefined): Record<string, unknown> | undefined {\n if (!metadata) return metadata;\n return this.processValue(metadata, 'metadata') as Record<string, unknown>;\n }\n\n /**\n * Ensure log entry doesn't exceed max size\n */\n private enforceMaxLogSize(entry: InternalLogEntry): InternalLogEntry {\n const serialized = JSON.stringify(entry);\n if (serialized.length <= this.payloadLimits.maxLogSize) {\n return entry;\n }\n\n // Log is too large, progressively truncate metadata\n if (this.debugMode) {\n console.warn(`[LogTide] Log entry too large (${serialized.length} bytes), truncating metadata`);\n }\n\n // Create a copy and truncate metadata heavily\n const truncated: InternalLogEntry = {\n ...entry,\n metadata: {\n _truncated: true,\n _originalSize: serialized.length,\n message: entry.message,\n },\n };\n\n return truncated;\n }\n\n // ==================== Logging Methods ====================\n\n private startFlushTimer() {\n this.timer = setInterval(() => {\n this.flush();\n }, this.flushInterval);\n }\n\n log(entry: LogEntry) {\n // Check buffer size limit\n if (this.buffer.length >= this.maxBufferSize) {\n this.metrics.logsDropped++;\n if (this.debugMode) {\n console.warn(`[LogTide] Buffer full, dropping log: ${entry.message}`);\n }\n return;\n }\n\n // Determine trace_id: use entry's trace_id, current context, or auto-generate if enabled\n const traceId = entry.trace_id || this.currentTraceId || (this.autoTraceId ? randomUUID() : undefined);\n\n // Merge and process metadata (applies truncation, exclusion, base64 removal)\n const mergedMetadata = {\n ...this.globalMetadata,\n ...entry.metadata,\n };\n const processedMetadata = this.processMetadata(mergedMetadata);\n\n let internalEntry: InternalLogEntry = {\n ...entry,\n time: entry.time || new Date().toISOString(),\n metadata: processedMetadata,\n trace_id: traceId,\n };\n\n // Enforce max log size\n internalEntry = this.enforceMaxLogSize(internalEntry);\n\n this.buffer.push(internalEntry);\n\n if (this.buffer.length >= this.batchSize) {\n this.flush();\n }\n }\n\n debug(service: string, message: string, metadata?: Record<string, unknown>) {\n this.log({ service, level: 'debug', message, metadata });\n }\n\n info(service: string, message: string, metadata?: Record<string, unknown>) {\n this.log({ service, level: 'info', message, metadata });\n }\n\n warn(service: string, message: string, metadata?: Record<string, unknown>) {\n this.log({ service, level: 'warn', message, metadata });\n }\n\n error(service: string, message: string, metadataOrError?: Record<string, unknown> | Error) {\n let metadata: Record<string, unknown> = {};\n\n if (metadataOrError instanceof Error) {\n metadata = { error: serializeError(metadataOrError) };\n } else if (metadataOrError) {\n metadata = metadataOrError;\n }\n\n this.log({ service, level: 'error', message, metadata });\n }\n\n critical(service: string, message: string, metadataOrError?: Record<string, unknown> | Error) {\n let metadata: Record<string, unknown> = {};\n\n if (metadataOrError instanceof Error) {\n metadata = { error: serializeError(metadataOrError) };\n } else if (metadataOrError) {\n metadata = metadataOrError;\n }\n\n this.log({ service, level: 'critical', message, metadata });\n }\n\n // ==================== Flush with Retry & Circuit Breaker ====================\n\n async flush() {\n if (this.buffer.length === 0) return;\n\n // Check circuit breaker\n if (!this.circuitBreaker.canAttempt()) {\n this.metrics.circuitBreakerTrips++;\n if (this.debugMode) {\n console.warn('[LogTide] Circuit breaker OPEN, skipping flush');\n }\n return;\n }\n\n const logs = [...this.buffer];\n this.buffer = [];\n\n const startTime = Date.now();\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n try {\n const response = await fetch(`${this.apiUrl}/api/v1/ingest`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-API-Key': this.apiKey,\n },\n body: JSON.stringify({ logs }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`HTTP ${response.status}: ${errorText}`);\n }\n\n // Success\n this.circuitBreaker.recordSuccess();\n this.metrics.logsSent += logs.length;\n\n if (this.enableMetrics) {\n const latency = Date.now() - startTime;\n this.latencies.push(latency);\n if (this.latencies.length > 100) {\n this.latencies.shift();\n }\n this.metrics.avgLatencyMs =\n this.latencies.reduce((a, b) => a + b, 0) / this.latencies.length;\n }\n\n if (this.debugMode) {\n console.log(`[LogTide] Sent ${logs.length} logs successfully`);\n }\n\n return;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n this.metrics.errors++;\n\n if (attempt < this.maxRetries) {\n this.metrics.retries++;\n const delay = this.retryDelayMs * Math.pow(2, attempt);\n if (this.debugMode) {\n console.warn(\n `[LogTide] Retry ${attempt + 1}/${this.maxRetries} after ${delay}ms: ${lastError.message}`,\n );\n }\n await this.sleep(delay);\n }\n }\n }\n\n // All retries failed\n this.circuitBreaker.recordFailure();\n\n if (this.debugMode) {\n console.error(`[LogTide] Failed to send logs after ${this.maxRetries} retries:`, lastError);\n }\n\n // Re-add logs to buffer if not full\n if (this.buffer.length + logs.length <= this.maxBufferSize) {\n this.buffer.unshift(...logs);\n } else {\n this.metrics.logsDropped += logs.length;\n }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n // ==================== Query Methods ====================\n\n async query(options: QueryOptions = {}): Promise<LogsResponse> {\n const params = new URLSearchParams();\n\n if (options.service) params.append('service', options.service);\n if (options.level) params.append('level', options.level);\n if (options.from) {\n const from = options.from instanceof Date ? options.from.toISOString() : options.from;\n params.append('from', from);\n }\n if (options.to) {\n const to = options.to instanceof Date ? options.to.toISOString() : options.to;\n params.append('to', to);\n }\n if (options.q) params.append('q', options.q);\n if (options.limit) params.append('limit', String(options.limit));\n if (options.offset) params.append('offset', String(options.offset));\n\n const url = `${this.apiUrl}/api/v1/logs?${params.toString()}`;\n\n const response = await fetch(url, {\n headers: {\n 'X-API-Key': this.apiKey,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Query failed: HTTP ${response.status}: ${errorText}`);\n }\n\n return (await response.json()) as LogsResponse;\n }\n\n async getByTraceId(traceId: string): Promise<InternalLogEntry[]> {\n const url = `${this.apiUrl}/api/v1/logs/trace/${traceId}`;\n\n const response = await fetch(url, {\n headers: {\n 'X-API-Key': this.apiKey,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Get by trace ID failed: HTTP ${response.status}: ${errorText}`);\n }\n\n const data = (await response.json()) as { logs?: InternalLogEntry[] };\n return data.logs || [];\n }\n\n async getAggregatedStats(options: AggregatedStatsOptions): Promise<AggregatedStatsResponse> {\n const params = new URLSearchParams();\n\n const from = options.from instanceof Date ? options.from.toISOString() : options.from;\n const to = options.to instanceof Date ? options.to.toISOString() : options.to;\n\n params.append('from', from);\n params.append('to', to);\n if (options.interval) params.append('interval', options.interval);\n if (options.service) params.append('service', options.service);\n\n const url = `${this.apiUrl}/api/v1/logs/aggregated?${params.toString()}`;\n\n const response = await fetch(url, {\n headers: {\n 'X-API-Key': this.apiKey,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Get aggregated stats failed: HTTP ${response.status}: ${errorText}`);\n }\n\n return (await response.json()) as AggregatedStatsResponse;\n }\n\n // ==================== Live Tail (SSE) ====================\n\n stream(options: StreamOptions): () => void {\n const params = new URLSearchParams();\n params.append('token', this.apiKey);\n if (options.service) params.append('service', options.service);\n if (options.level) params.append('level', options.level);\n\n const url = `${this.apiUrl}/api/v1/logs/stream?${params.toString()}`;\n\n const eventSource = new EventSource(url);\n\n eventSource.addEventListener('log', (event: Event) => {\n try {\n const messageEvent = event as MessageEvent;\n const log = JSON.parse(messageEvent.data) as InternalLogEntry;\n options.onLog(log);\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n options.onError?.(err);\n }\n });\n\n eventSource.addEventListener('error', () => {\n const error = new Error('SSE connection error');\n options.onError?.(error);\n });\n\n // Return cleanup function\n return () => {\n eventSource.close();\n };\n }\n\n // ==================== Metrics ====================\n\n getMetrics(): ClientMetrics {\n return { ...this.metrics };\n }\n\n resetMetrics() {\n this.metrics = {\n logsSent: 0,\n logsDropped: 0,\n errors: 0,\n retries: 0,\n avgLatencyMs: 0,\n circuitBreakerTrips: 0,\n };\n this.latencies = [];\n }\n\n getCircuitBreakerState(): string {\n return this.circuitBreaker.getState();\n }\n\n // ==================== Cleanup ====================\n\n async close() {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n this.stopConsoleInterception();\n await this.flush();\n }\n}\n\nexport default LogTideClient;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["randomUUID"],"mappings":"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","file":"index.cjs","sourcesContent":["import { randomUUID } from 'crypto';\n\n// ==================== Types ====================\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'critical';\n\nexport interface ConsoleInterceptOptions {\n enabled: boolean;\n service?: string;\n preserveOriginal?: boolean;\n includeStackTrace?: boolean;\n levels?: {\n log?: boolean;\n info?: boolean;\n warn?: boolean;\n error?: boolean;\n debug?: boolean;\n };\n}\n\nexport interface PayloadLimitsOptions {\n /** Maximum size in bytes for a single field value (default: 10KB) */\n maxFieldSize?: number;\n /** Maximum size in bytes for the entire log entry (default: 100KB) */\n maxLogSize?: number;\n /** Fields to exclude from metadata (e.g., ['body', 'requestBody', 'responseBody']) */\n excludeFields?: string[];\n /** Marker to append when a field is truncated (default: '...[TRUNCATED]') */\n truncationMarker?: string;\n}\n\nexport interface LogTideClientOptions {\n apiUrl: string;\n apiKey: string;\n batchSize?: number;\n flushInterval?: number;\n maxBufferSize?: number;\n maxRetries?: number;\n retryDelayMs?: number;\n circuitBreakerThreshold?: number;\n circuitBreakerResetMs?: number;\n enableMetrics?: boolean;\n debug?: boolean;\n globalMetadata?: Record<string, unknown>;\n autoTraceId?: boolean;\n interceptConsole?: ConsoleInterceptOptions;\n /** Payload size limits to prevent 413 errors */\n payloadLimits?: PayloadLimitsOptions;\n}\n\nexport interface LogEntry {\n service: string;\n level: LogLevel;\n message: string;\n time?: string;\n metadata?: Record<string, unknown>;\n trace_id?: string;\n}\n\nexport interface InternalLogEntry extends LogEntry {\n time: string;\n}\n\nexport interface QueryOptions {\n service?: string;\n level?: LogLevel;\n from?: Date | string;\n to?: Date | string;\n q?: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface LogsResponse {\n logs: InternalLogEntry[];\n total: number;\n limit: number;\n offset: number;\n}\n\nexport interface AggregatedStatsOptions {\n from: Date | string;\n to: Date | string;\n interval?: '1m' | '5m' | '1h' | '1d';\n service?: string;\n}\n\nexport interface AggregatedStatsResponse {\n timeseries: Array<{\n bucket: string;\n total: number;\n by_level: Record<string, number>;\n }>;\n top_services: Array<{ service: string; count: number }>;\n top_errors: Array<{ message: string; count: number }>;\n}\n\nexport interface ClientMetrics {\n logsSent: number;\n logsDropped: number;\n errors: number;\n retries: number;\n avgLatencyMs: number;\n circuitBreakerTrips: number;\n}\n\nexport interface StreamOptions {\n service?: string;\n level?: LogLevel;\n onLog: (log: InternalLogEntry) => void;\n onError?: (error: Error) => void;\n}\n\n// ==================== Circuit Breaker ====================\n\nenum CircuitState {\n CLOSED = 'CLOSED',\n OPEN = 'OPEN',\n HALF_OPEN = 'HALF_OPEN',\n}\n\nclass CircuitBreaker {\n private state: CircuitState = CircuitState.CLOSED;\n private failureCount = 0;\n private lastFailureTime: number | null = null;\n\n constructor(\n private threshold: number,\n private resetMs: number,\n ) {}\n\n recordSuccess() {\n this.failureCount = 0;\n this.state = CircuitState.CLOSED;\n }\n\n recordFailure() {\n this.failureCount++;\n this.lastFailureTime = Date.now();\n\n if (this.failureCount >= this.threshold) {\n this.state = CircuitState.OPEN;\n }\n }\n\n canAttempt(): boolean {\n if (this.state === CircuitState.CLOSED) {\n return true;\n }\n\n if (this.state === CircuitState.OPEN) {\n const now = Date.now();\n if (this.lastFailureTime && now - this.lastFailureTime >= this.resetMs) {\n this.state = CircuitState.HALF_OPEN;\n return true;\n }\n return false;\n }\n\n // HALF_OPEN state - allow one attempt\n return true;\n }\n\n getState(): CircuitState {\n return this.state;\n }\n}\n\n\n// ==================== Structured Exception Types ====================\n\nexport interface StructuredStackFrame {\n /** File path or module name */\n file?: string;\n /** Function/method name */\n function?: string;\n /** Line number (1-based) */\n line?: number;\n /** Column number */\n column?: number;\n /** Additional frame metadata */\n metadata?: Record<string, unknown>;\n}\n\nexport interface StructuredException {\n /** Exception type/class name (e.g., \"TypeError\", \"Error\") */\n type: string;\n /** Human-readable error message */\n message: string;\n /** Stack trace as an array of frames (top to bottom) */\n stacktrace?: StructuredStackFrame[];\n /** Language hint for better fingerprinting */\n language?: string;\n /** Inner/cause exception (for wrapped exceptions) */\n cause?: StructuredException;\n /** Additional exception metadata */\n metadata?: Record<string, unknown>;\n /** Original raw stack trace as a string (fallback) */\n raw?: string;\n}\n\n// ==================== Error Serialization ====================\n\n/**\n * Parse a V8/Node.js stack trace string into structured frames\n */\nfunction parseNodeStackTrace(stack: string | undefined): StructuredStackFrame[] {\n if (!stack) return [];\n\n const frames: StructuredStackFrame[] = [];\n const lines = stack.split('\\n');\n\n for (const line of lines) {\n // Skip the first line (error message) and empty lines\n const trimmed = line.trim();\n if (!trimmed.startsWith('at ')) continue;\n\n // Format 1: \"at functionName (file:line:column)\"\n const match1 = trimmed.match(/^at\\s+(.+?)\\s+\\((.+):(\\d+):(\\d+)\\)$/);\n if (match1) {\n frames.push({\n function: match1[1],\n file: match1[2],\n line: parseInt(match1[3], 10),\n column: parseInt(match1[4], 10),\n });\n continue;\n }\n\n // Format 2: \"at file:line:column\" (anonymous function)\n const match2 = trimmed.match(/^at\\s+(.+):(\\d+):(\\d+)$/);\n if (match2) {\n frames.push({\n file: match2[1],\n line: parseInt(match2[2], 10),\n column: parseInt(match2[3], 10),\n });\n continue;\n }\n\n // Format 3: \"at functionName (native)\" or similar\n const match3 = trimmed.match(/^at\\s+(.+?)\\s+\\((.+)\\)$/);\n if (match3) {\n frames.push({\n function: match3[1],\n file: match3[2],\n });\n continue;\n }\n\n // Format 4: \"at functionName\" (no file info)\n const match4 = trimmed.match(/^at\\s+(.+)$/);\n if (match4) {\n frames.push({\n function: match4[1],\n });\n }\n }\n\n return frames;\n}\n\n/**\n * Serialize an error into the StructuredException format\n */\nexport function serializeError(error: unknown): StructuredException {\n if (error instanceof Error) {\n const result: StructuredException = {\n type: error.name,\n message: error.message,\n language: 'nodejs',\n stacktrace: parseNodeStackTrace(error.stack),\n raw: error.stack,\n };\n\n // Handle error.cause (Node.js 16.9+)\n if (error.cause) {\n result.cause = serializeError(error.cause);\n }\n\n // Extract additional error properties as metadata\n const errorMetadata: Record<string, unknown> = {};\n const standardProps = ['name', 'message', 'stack', 'cause'];\n\n for (const key of Object.keys(error)) {\n if (!standardProps.includes(key)) {\n errorMetadata[key] = (error as unknown as Record<string, unknown>)[key];\n }\n }\n\n // Include common Node.js error properties\n if ('code' in error) errorMetadata.code = (error as NodeJS.ErrnoException).code;\n if ('errno' in error) errorMetadata.errno = (error as NodeJS.ErrnoException).errno;\n if ('syscall' in error) errorMetadata.syscall = (error as NodeJS.ErrnoException).syscall;\n if ('path' in error) errorMetadata.path = (error as NodeJS.ErrnoException).path;\n\n if (Object.keys(errorMetadata).length > 0) {\n result.metadata = errorMetadata;\n }\n\n return result;\n }\n\n if (typeof error === 'string') {\n return {\n type: 'Error',\n message: error,\n language: 'nodejs',\n };\n }\n\n if (typeof error === 'object' && error !== null) {\n // Try to extract type and message from the object\n const obj = error as Record<string, unknown>;\n return {\n type: (typeof obj.type === 'string' ? obj.type : typeof obj.name === 'string' ? obj.name : 'Error'),\n message: (typeof obj.message === 'string' ? obj.message : JSON.stringify(error)),\n language: 'nodejs',\n metadata: obj,\n };\n }\n\n return {\n type: 'Error',\n message: String(error),\n language: 'nodejs',\n };\n}\n\n// ==================== Main Client ====================\n\nexport class LogTideClient {\n private apiUrl: string;\n private apiKey: string;\n private batchSize: number;\n private flushInterval: number;\n private maxBufferSize: number;\n private maxRetries: number;\n private retryDelayMs: number;\n private enableMetrics: boolean;\n private debugMode: boolean;\n private globalMetadata: Record<string, unknown>;\n private autoTraceId: boolean;\n\n private buffer: InternalLogEntry[] = [];\n private timer: NodeJS.Timeout | null = null;\n private circuitBreaker: CircuitBreaker;\n\n // Metrics\n private metrics: ClientMetrics = {\n logsSent: 0,\n logsDropped: 0,\n errors: 0,\n retries: 0,\n avgLatencyMs: 0,\n circuitBreakerTrips: 0,\n };\n private latencies: number[] = [];\n\n // Context tracking\n private currentTraceId: string | null = null;\n\n // Console interception\n private consoleInterceptOptions: ConsoleInterceptOptions | null = null;\n private originalConsole: {\n log: typeof console.log;\n info: typeof console.info;\n warn: typeof console.warn;\n error: typeof console.error;\n debug: typeof console.debug;\n } | null = null;\n\n // Payload limits\n private payloadLimits: Required<PayloadLimitsOptions>;\n\n constructor(options: LogTideClientOptions) {\n this.apiUrl = options.apiUrl.replace(/\\/$/, '');\n this.apiKey = options.apiKey;\n this.batchSize = options.batchSize || 100;\n this.flushInterval = options.flushInterval || 5000;\n this.maxBufferSize = options.maxBufferSize || 10000;\n this.maxRetries = options.maxRetries || 3;\n this.retryDelayMs = options.retryDelayMs || 1000;\n this.enableMetrics = options.enableMetrics ?? true;\n this.debugMode = options.debug ?? false;\n this.globalMetadata = options.globalMetadata || {};\n this.autoTraceId = options.autoTraceId ?? false;\n\n this.circuitBreaker = new CircuitBreaker(\n options.circuitBreakerThreshold || 5,\n options.circuitBreakerResetMs || 30000,\n );\n\n // Initialize payload limits with defaults\n this.payloadLimits = {\n maxFieldSize: options.payloadLimits?.maxFieldSize ?? 10 * 1024, // 10KB\n maxLogSize: options.payloadLimits?.maxLogSize ?? 100 * 1024, // 100KB\n excludeFields: options.payloadLimits?.excludeFields ?? [],\n truncationMarker: options.payloadLimits?.truncationMarker ?? '...[TRUNCATED]',\n };\n\n this.startFlushTimer();\n\n // Start console interception if configured\n if (options.interceptConsole?.enabled) {\n this.startConsoleInterception(options.interceptConsole);\n }\n }\n\n // ==================== Context Helpers ====================\n\n /**\n * Set trace ID for subsequent logs\n */\n setTraceId(traceId: string | null) {\n this.currentTraceId = traceId;\n }\n\n /**\n * Get current trace ID\n */\n getTraceId(): string | null {\n return this.currentTraceId;\n }\n\n /**\n * Execute function with a specific trace ID context\n */\n withTraceId<T>(traceId: string, fn: () => T): T {\n const previousTraceId = this.currentTraceId;\n this.currentTraceId = traceId;\n try {\n return fn();\n } finally {\n this.currentTraceId = previousTraceId;\n }\n }\n\n /**\n * Execute function with a new auto-generated trace ID\n */\n withNewTraceId<T>(fn: () => T): T {\n return this.withTraceId(randomUUID(), fn);\n }\n\n // ==================== Console Interception ====================\n\n /**\n * Start intercepting console methods and forward them to LogTide\n */\n startConsoleInterception(options?: Partial<ConsoleInterceptOptions>) {\n if (this.originalConsole) {\n // Already intercepting\n return;\n }\n\n const config: ConsoleInterceptOptions = {\n enabled: true,\n service: options?.service ?? 'console',\n preserveOriginal: options?.preserveOriginal ?? true,\n includeStackTrace: options?.includeStackTrace ?? false,\n levels: {\n log: options?.levels?.log ?? true,\n info: options?.levels?.info ?? true,\n warn: options?.levels?.warn ?? true,\n error: options?.levels?.error ?? true,\n debug: options?.levels?.debug ?? true,\n },\n };\n\n this.consoleInterceptOptions = config;\n\n // Save original console methods\n this.originalConsole = {\n log: console.log.bind(console),\n info: console.info.bind(console),\n warn: console.warn.bind(console),\n error: console.error.bind(console),\n debug: console.debug.bind(console),\n };\n\n const createInterceptor = (\n method: 'log' | 'info' | 'warn' | 'error' | 'debug',\n level: LogLevel,\n ) => {\n const original = this.originalConsole![method];\n\n return (...args: unknown[]) => {\n // Always call original if preserveOriginal is true\n if (config.preserveOriginal) {\n original(...args);\n }\n\n // Skip if this method is not configured for interception\n if (!config.levels?.[method]) {\n return;\n }\n\n // Skip internal LogTide logs to prevent infinite loops\n const message = args\n .map((arg) => {\n if (typeof arg === 'string') return arg;\n if (arg instanceof Error) return arg.message;\n try {\n return JSON.stringify(arg);\n } catch {\n return String(arg);\n }\n })\n .join(' ');\n\n if (message.startsWith('[LogTide]')) {\n return;\n }\n\n // Build metadata\n const metadata: Record<string, unknown> = {\n source: 'console',\n originalMethod: method,\n };\n\n // Include stack trace if configured\n if (config.includeStackTrace) {\n const stack = new Error().stack;\n if (stack) {\n // Remove the first two lines (Error + this interceptor function)\n const stackLines = stack.split('\\n').slice(2);\n metadata.stackTrace = stackLines.join('\\n');\n\n // Extract caller location from first relevant stack line\n const callerLine = stackLines[0];\n if (callerLine) {\n const match = callerLine.match(/at\\s+(.+?)\\s+\\((.+):(\\d+):(\\d+)\\)/);\n if (match) {\n metadata.caller = {\n function: match[1],\n file: match[2],\n line: parseInt(match[3], 10),\n column: parseInt(match[4], 10),\n };\n } else {\n // Try alternative format: \"at file:line:column\"\n const altMatch = callerLine.match(/at\\s+(.+):(\\d+):(\\d+)/);\n if (altMatch) {\n metadata.caller = {\n file: altMatch[1],\n line: parseInt(altMatch[2], 10),\n column: parseInt(altMatch[3], 10),\n };\n }\n }\n }\n }\n }\n\n // Include raw arguments for complex objects\n if (args.length > 1 || (args.length === 1 && typeof args[0] !== 'string')) {\n metadata.args = args.map((arg) => {\n if (arg instanceof Error) {\n return serializeError(arg);\n }\n return arg;\n });\n }\n\n // For error level, if any argument is an Error, add it to metadata.exception\n if (level === 'error' || level === 'critical') {\n const errorArg = args.find((arg) => arg instanceof Error);\n if (errorArg instanceof Error) {\n metadata.exception = serializeError(errorArg);\n }\n }\n\n // Log to LogTide\n this.log({\n service: config.service!,\n level,\n message,\n metadata,\n });\n };\n };\n\n // Replace console methods\n console.log = createInterceptor('log', 'info');\n console.info = createInterceptor('info', 'info');\n console.warn = createInterceptor('warn', 'warn');\n console.error = createInterceptor('error', 'error');\n console.debug = createInterceptor('debug', 'debug');\n\n if (this.debugMode) {\n this.originalConsole.log('[LogTide] Console interception started');\n }\n }\n\n /**\n * Stop intercepting console methods and restore originals\n */\n stopConsoleInterception() {\n if (!this.originalConsole) {\n return;\n }\n\n // Restore original console methods\n console.log = this.originalConsole.log;\n console.info = this.originalConsole.info;\n console.warn = this.originalConsole.warn;\n console.error = this.originalConsole.error;\n console.debug = this.originalConsole.debug;\n\n if (this.debugMode) {\n console.log('[LogTide] Console interception stopped');\n }\n\n this.originalConsole = null;\n this.consoleInterceptOptions = null;\n }\n\n /**\n * Check if console interception is active\n */\n isConsoleInterceptionActive(): boolean {\n return this.originalConsole !== null;\n }\n\n // ==================== Payload Processing ====================\n\n /**\n * Check if a string looks like base64 encoded data\n */\n private looksLikeBase64(str: string): boolean {\n if (typeof str !== 'string' || str.length < 100) return false;\n // Check for common base64 patterns: data URLs or long base64 strings\n if (str.startsWith('data:')) return true;\n // Check if it's a long string with only base64 characters\n const base64Regex = /^[A-Za-z0-9+/=]{100,}$/;\n return base64Regex.test(str.replace(/\\s/g, ''));\n }\n\n /**\n * Process a value for payload limits (truncation, base64 removal, etc.)\n */\n private processValue(value: unknown, fieldPath: string): unknown {\n // Check if this field should be excluded\n const fieldName = fieldPath.split('.').pop() || fieldPath;\n if (this.payloadLimits.excludeFields.includes(fieldName)) {\n return '[EXCLUDED]';\n }\n\n if (value === null || value === undefined) {\n return value;\n }\n\n if (typeof value === 'string') {\n // Check for base64 data\n if (this.looksLikeBase64(value)) {\n return '[BASE64 DATA REMOVED]';\n }\n // Truncate if too long\n if (value.length > this.payloadLimits.maxFieldSize) {\n return value.substring(0, this.payloadLimits.maxFieldSize) + this.payloadLimits.truncationMarker;\n }\n return value;\n }\n\n if (Array.isArray(value)) {\n return value.map((item, index) => this.processValue(item, `${fieldPath}[${index}]`));\n }\n\n if (typeof value === 'object') {\n const processed: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n processed[key] = this.processValue(val, `${fieldPath}.${key}`);\n }\n return processed;\n }\n\n return value;\n }\n\n /**\n * Process metadata to apply payload limits\n */\n private processMetadata(metadata: Record<string, unknown> | undefined): Record<string, unknown> | undefined {\n if (!metadata) return metadata;\n return this.processValue(metadata, 'metadata') as Record<string, unknown>;\n }\n\n /**\n * Ensure log entry doesn't exceed max size\n */\n private enforceMaxLogSize(entry: InternalLogEntry): InternalLogEntry {\n const serialized = JSON.stringify(entry);\n if (serialized.length <= this.payloadLimits.maxLogSize) {\n return entry;\n }\n\n // Log is too large, progressively truncate metadata\n if (this.debugMode) {\n console.warn(`[LogTide] Log entry too large (${serialized.length} bytes), truncating metadata`);\n }\n\n // Create a copy and truncate metadata heavily\n const truncated: InternalLogEntry = {\n ...entry,\n metadata: {\n _truncated: true,\n _originalSize: serialized.length,\n message: entry.message,\n },\n };\n\n return truncated;\n }\n\n // ==================== Logging Methods ====================\n\n private startFlushTimer() {\n this.timer = setInterval(() => {\n this.flush();\n }, this.flushInterval);\n }\n\n log(entry: LogEntry) {\n // Check buffer size limit\n if (this.buffer.length >= this.maxBufferSize) {\n this.metrics.logsDropped++;\n if (this.debugMode) {\n console.warn(`[LogTide] Buffer full, dropping log: ${entry.message}`);\n }\n return;\n }\n\n // Determine trace_id: use entry's trace_id, current context, or auto-generate if enabled\n const traceId = entry.trace_id || this.currentTraceId || (this.autoTraceId ? randomUUID() : undefined);\n\n // Merge and process metadata (applies truncation, exclusion, base64 removal)\n const mergedMetadata = {\n ...this.globalMetadata,\n ...entry.metadata,\n };\n const processedMetadata = this.processMetadata(mergedMetadata);\n\n let internalEntry: InternalLogEntry = {\n ...entry,\n time: entry.time || new Date().toISOString(),\n metadata: processedMetadata,\n trace_id: traceId,\n };\n\n // Enforce max log size\n internalEntry = this.enforceMaxLogSize(internalEntry);\n\n this.buffer.push(internalEntry);\n\n if (this.buffer.length >= this.batchSize) {\n this.flush();\n }\n }\n\n debug(service: string, message: string, metadata?: Record<string, unknown>) {\n this.log({ service, level: 'debug', message, metadata });\n }\n\n info(service: string, message: string, metadata?: Record<string, unknown>) {\n this.log({ service, level: 'info', message, metadata });\n }\n\n warn(service: string, message: string, metadata?: Record<string, unknown>) {\n this.log({ service, level: 'warn', message, metadata });\n }\n\n error(service: string, message: string, metadataOrError?: Record<string, unknown> | Error) {\n let metadata: Record<string, unknown> = {};\n\n if (metadataOrError instanceof Error) {\n metadata = { exception: serializeError(metadataOrError) };\n } else if (metadataOrError) {\n metadata = metadataOrError;\n }\n\n this.log({ service, level: 'error', message, metadata });\n }\n\n critical(service: string, message: string, metadataOrError?: Record<string, unknown> | Error) {\n let metadata: Record<string, unknown> = {};\n\n if (metadataOrError instanceof Error) {\n metadata = { exception: serializeError(metadataOrError) };\n } else if (metadataOrError) {\n metadata = metadataOrError;\n }\n\n this.log({ service, level: 'critical', message, metadata });\n }\n\n // ==================== Flush with Retry & Circuit Breaker ====================\n\n async flush() {\n if (this.buffer.length === 0) return;\n\n // Check circuit breaker\n if (!this.circuitBreaker.canAttempt()) {\n this.metrics.circuitBreakerTrips++;\n if (this.debugMode) {\n console.warn('[LogTide] Circuit breaker OPEN, skipping flush');\n }\n return;\n }\n\n const logs = [...this.buffer];\n this.buffer = [];\n\n const startTime = Date.now();\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n try {\n const response = await fetch(`${this.apiUrl}/api/v1/ingest`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-API-Key': this.apiKey,\n },\n body: JSON.stringify({ logs }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`HTTP ${response.status}: ${errorText}`);\n }\n\n // Success\n this.circuitBreaker.recordSuccess();\n this.metrics.logsSent += logs.length;\n\n if (this.enableMetrics) {\n const latency = Date.now() - startTime;\n this.latencies.push(latency);\n if (this.latencies.length > 100) {\n this.latencies.shift();\n }\n this.metrics.avgLatencyMs =\n this.latencies.reduce((a, b) => a + b, 0) / this.latencies.length;\n }\n\n if (this.debugMode) {\n console.log(`[LogTide] Sent ${logs.length} logs successfully`);\n }\n\n return;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n this.metrics.errors++;\n\n if (attempt < this.maxRetries) {\n this.metrics.retries++;\n const delay = this.retryDelayMs * Math.pow(2, attempt);\n if (this.debugMode) {\n console.warn(\n `[LogTide] Retry ${attempt + 1}/${this.maxRetries} after ${delay}ms: ${lastError.message}`,\n );\n }\n await this.sleep(delay);\n }\n }\n }\n\n // All retries failed\n this.circuitBreaker.recordFailure();\n\n if (this.debugMode) {\n console.error(`[LogTide] Failed to send logs after ${this.maxRetries} retries:`, lastError);\n }\n\n // Re-add logs to buffer if not full\n if (this.buffer.length + logs.length <= this.maxBufferSize) {\n this.buffer.unshift(...logs);\n } else {\n this.metrics.logsDropped += logs.length;\n }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n // ==================== Query Methods ====================\n\n async query(options: QueryOptions = {}): Promise<LogsResponse> {\n const params = new URLSearchParams();\n\n if (options.service) params.append('service', options.service);\n if (options.level) params.append('level', options.level);\n if (options.from) {\n const from = options.from instanceof Date ? options.from.toISOString() : options.from;\n params.append('from', from);\n }\n if (options.to) {\n const to = options.to instanceof Date ? options.to.toISOString() : options.to;\n params.append('to', to);\n }\n if (options.q) params.append('q', options.q);\n if (options.limit) params.append('limit', String(options.limit));\n if (options.offset) params.append('offset', String(options.offset));\n\n const url = `${this.apiUrl}/api/v1/logs?${params.toString()}`;\n\n const response = await fetch(url, {\n headers: {\n 'X-API-Key': this.apiKey,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Query failed: HTTP ${response.status}: ${errorText}`);\n }\n\n return (await response.json()) as LogsResponse;\n }\n\n async getByTraceId(traceId: string): Promise<InternalLogEntry[]> {\n const url = `${this.apiUrl}/api/v1/logs/trace/${traceId}`;\n\n const response = await fetch(url, {\n headers: {\n 'X-API-Key': this.apiKey,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Get by trace ID failed: HTTP ${response.status}: ${errorText}`);\n }\n\n const data = (await response.json()) as { logs?: InternalLogEntry[] };\n return data.logs || [];\n }\n\n async getAggregatedStats(options: AggregatedStatsOptions): Promise<AggregatedStatsResponse> {\n const params = new URLSearchParams();\n\n const from = options.from instanceof Date ? options.from.toISOString() : options.from;\n const to = options.to instanceof Date ? options.to.toISOString() : options.to;\n\n params.append('from', from);\n params.append('to', to);\n if (options.interval) params.append('interval', options.interval);\n if (options.service) params.append('service', options.service);\n\n const url = `${this.apiUrl}/api/v1/logs/aggregated?${params.toString()}`;\n\n const response = await fetch(url, {\n headers: {\n 'X-API-Key': this.apiKey,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Get aggregated stats failed: HTTP ${response.status}: ${errorText}`);\n }\n\n return (await response.json()) as AggregatedStatsResponse;\n }\n\n // ==================== Live Tail (SSE) ====================\n\n stream(options: StreamOptions): () => void {\n const params = new URLSearchParams();\n params.append('token', this.apiKey);\n if (options.service) params.append('service', options.service);\n if (options.level) params.append('level', options.level);\n\n const url = `${this.apiUrl}/api/v1/logs/stream?${params.toString()}`;\n\n const eventSource = new EventSource(url);\n\n eventSource.addEventListener('log', (event: Event) => {\n try {\n const messageEvent = event as MessageEvent;\n const log = JSON.parse(messageEvent.data) as InternalLogEntry;\n options.onLog(log);\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n options.onError?.(err);\n }\n });\n\n eventSource.addEventListener('error', () => {\n const error = new Error('SSE connection error');\n options.onError?.(error);\n });\n\n // Return cleanup function\n return () => {\n eventSource.close();\n };\n }\n\n // ==================== Metrics ====================\n\n getMetrics(): ClientMetrics {\n return { ...this.metrics };\n }\n\n resetMetrics() {\n this.metrics = {\n logsSent: 0,\n logsDropped: 0,\n errors: 0,\n retries: 0,\n avgLatencyMs: 0,\n circuitBreakerTrips: 0,\n };\n this.latencies = [];\n }\n\n getCircuitBreakerState(): string {\n return this.circuitBreaker.getState();\n }\n\n // ==================== Cleanup ====================\n\n async close() {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n this.stopConsoleInterception();\n await this.flush();\n }\n}\n\nexport default LogTideClient;\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -101,7 +101,38 @@ interface StreamOptions {
|
|
|
101
101
|
onLog: (log: InternalLogEntry) => void;
|
|
102
102
|
onError?: (error: Error) => void;
|
|
103
103
|
}
|
|
104
|
-
|
|
104
|
+
interface StructuredStackFrame {
|
|
105
|
+
/** File path or module name */
|
|
106
|
+
file?: string;
|
|
107
|
+
/** Function/method name */
|
|
108
|
+
function?: string;
|
|
109
|
+
/** Line number (1-based) */
|
|
110
|
+
line?: number;
|
|
111
|
+
/** Column number */
|
|
112
|
+
column?: number;
|
|
113
|
+
/** Additional frame metadata */
|
|
114
|
+
metadata?: Record<string, unknown>;
|
|
115
|
+
}
|
|
116
|
+
interface StructuredException {
|
|
117
|
+
/** Exception type/class name (e.g., "TypeError", "Error") */
|
|
118
|
+
type: string;
|
|
119
|
+
/** Human-readable error message */
|
|
120
|
+
message: string;
|
|
121
|
+
/** Stack trace as an array of frames (top to bottom) */
|
|
122
|
+
stacktrace?: StructuredStackFrame[];
|
|
123
|
+
/** Language hint for better fingerprinting */
|
|
124
|
+
language?: string;
|
|
125
|
+
/** Inner/cause exception (for wrapped exceptions) */
|
|
126
|
+
cause?: StructuredException;
|
|
127
|
+
/** Additional exception metadata */
|
|
128
|
+
metadata?: Record<string, unknown>;
|
|
129
|
+
/** Original raw stack trace as a string (fallback) */
|
|
130
|
+
raw?: string;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Serialize an error into the StructuredException format
|
|
134
|
+
*/
|
|
135
|
+
declare function serializeError(error: unknown): StructuredException;
|
|
105
136
|
declare class LogTideClient {
|
|
106
137
|
private apiUrl;
|
|
107
138
|
private apiKey;
|
|
@@ -187,4 +218,4 @@ declare class LogTideClient {
|
|
|
187
218
|
close(): Promise<void>;
|
|
188
219
|
}
|
|
189
220
|
|
|
190
|
-
export { type AggregatedStatsOptions, type AggregatedStatsResponse, type ClientMetrics, type ConsoleInterceptOptions, type InternalLogEntry, type LogEntry, type LogLevel, LogTideClient, type LogTideClientOptions, type LogsResponse, type PayloadLimitsOptions, type QueryOptions, type StreamOptions, LogTideClient as default, serializeError };
|
|
221
|
+
export { type AggregatedStatsOptions, type AggregatedStatsResponse, type ClientMetrics, type ConsoleInterceptOptions, type InternalLogEntry, type LogEntry, type LogLevel, LogTideClient, type LogTideClientOptions, type LogsResponse, type PayloadLimitsOptions, type QueryOptions, type StreamOptions, type StructuredException, type StructuredStackFrame, LogTideClient as default, serializeError };
|
package/dist/index.d.ts
CHANGED
|
@@ -101,7 +101,38 @@ interface StreamOptions {
|
|
|
101
101
|
onLog: (log: InternalLogEntry) => void;
|
|
102
102
|
onError?: (error: Error) => void;
|
|
103
103
|
}
|
|
104
|
-
|
|
104
|
+
interface StructuredStackFrame {
|
|
105
|
+
/** File path or module name */
|
|
106
|
+
file?: string;
|
|
107
|
+
/** Function/method name */
|
|
108
|
+
function?: string;
|
|
109
|
+
/** Line number (1-based) */
|
|
110
|
+
line?: number;
|
|
111
|
+
/** Column number */
|
|
112
|
+
column?: number;
|
|
113
|
+
/** Additional frame metadata */
|
|
114
|
+
metadata?: Record<string, unknown>;
|
|
115
|
+
}
|
|
116
|
+
interface StructuredException {
|
|
117
|
+
/** Exception type/class name (e.g., "TypeError", "Error") */
|
|
118
|
+
type: string;
|
|
119
|
+
/** Human-readable error message */
|
|
120
|
+
message: string;
|
|
121
|
+
/** Stack trace as an array of frames (top to bottom) */
|
|
122
|
+
stacktrace?: StructuredStackFrame[];
|
|
123
|
+
/** Language hint for better fingerprinting */
|
|
124
|
+
language?: string;
|
|
125
|
+
/** Inner/cause exception (for wrapped exceptions) */
|
|
126
|
+
cause?: StructuredException;
|
|
127
|
+
/** Additional exception metadata */
|
|
128
|
+
metadata?: Record<string, unknown>;
|
|
129
|
+
/** Original raw stack trace as a string (fallback) */
|
|
130
|
+
raw?: string;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Serialize an error into the StructuredException format
|
|
134
|
+
*/
|
|
135
|
+
declare function serializeError(error: unknown): StructuredException;
|
|
105
136
|
declare class LogTideClient {
|
|
106
137
|
private apiUrl;
|
|
107
138
|
private apiKey;
|
|
@@ -187,4 +218,4 @@ declare class LogTideClient {
|
|
|
187
218
|
close(): Promise<void>;
|
|
188
219
|
}
|
|
189
220
|
|
|
190
|
-
export { type AggregatedStatsOptions, type AggregatedStatsResponse, type ClientMetrics, type ConsoleInterceptOptions, type InternalLogEntry, type LogEntry, type LogLevel, LogTideClient, type LogTideClientOptions, type LogsResponse, type PayloadLimitsOptions, type QueryOptions, type StreamOptions, LogTideClient as default, serializeError };
|
|
221
|
+
export { type AggregatedStatsOptions, type AggregatedStatsResponse, type ClientMetrics, type ConsoleInterceptOptions, type InternalLogEntry, type LogEntry, type LogLevel, LogTideClient, type LogTideClientOptions, type LogsResponse, type PayloadLimitsOptions, type QueryOptions, type StreamOptions, type StructuredException, type StructuredStackFrame, LogTideClient as default, serializeError };
|
package/dist/index.js
CHANGED
|
@@ -38,25 +38,98 @@ var CircuitBreaker = class {
|
|
|
38
38
|
return this.state;
|
|
39
39
|
}
|
|
40
40
|
};
|
|
41
|
+
function parseNodeStackTrace(stack) {
|
|
42
|
+
if (!stack) return [];
|
|
43
|
+
const frames = [];
|
|
44
|
+
const lines = stack.split("\n");
|
|
45
|
+
for (const line of lines) {
|
|
46
|
+
const trimmed = line.trim();
|
|
47
|
+
if (!trimmed.startsWith("at ")) continue;
|
|
48
|
+
const match1 = trimmed.match(/^at\s+(.+?)\s+\((.+):(\d+):(\d+)\)$/);
|
|
49
|
+
if (match1) {
|
|
50
|
+
frames.push({
|
|
51
|
+
function: match1[1],
|
|
52
|
+
file: match1[2],
|
|
53
|
+
line: parseInt(match1[3], 10),
|
|
54
|
+
column: parseInt(match1[4], 10)
|
|
55
|
+
});
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const match2 = trimmed.match(/^at\s+(.+):(\d+):(\d+)$/);
|
|
59
|
+
if (match2) {
|
|
60
|
+
frames.push({
|
|
61
|
+
file: match2[1],
|
|
62
|
+
line: parseInt(match2[2], 10),
|
|
63
|
+
column: parseInt(match2[3], 10)
|
|
64
|
+
});
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
const match3 = trimmed.match(/^at\s+(.+?)\s+\((.+)\)$/);
|
|
68
|
+
if (match3) {
|
|
69
|
+
frames.push({
|
|
70
|
+
function: match3[1],
|
|
71
|
+
file: match3[2]
|
|
72
|
+
});
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const match4 = trimmed.match(/^at\s+(.+)$/);
|
|
76
|
+
if (match4) {
|
|
77
|
+
frames.push({
|
|
78
|
+
function: match4[1]
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return frames;
|
|
83
|
+
}
|
|
41
84
|
function serializeError(error) {
|
|
42
85
|
if (error instanceof Error) {
|
|
43
86
|
const result = {
|
|
44
|
-
|
|
87
|
+
type: error.name,
|
|
45
88
|
message: error.message,
|
|
46
|
-
|
|
89
|
+
language: "nodejs",
|
|
90
|
+
stacktrace: parseNodeStackTrace(error.stack),
|
|
91
|
+
raw: error.stack
|
|
47
92
|
};
|
|
48
93
|
if (error.cause) {
|
|
49
94
|
result.cause = serializeError(error.cause);
|
|
50
95
|
}
|
|
96
|
+
const errorMetadata = {};
|
|
97
|
+
const standardProps = ["name", "message", "stack", "cause"];
|
|
98
|
+
for (const key of Object.keys(error)) {
|
|
99
|
+
if (!standardProps.includes(key)) {
|
|
100
|
+
errorMetadata[key] = error[key];
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if ("code" in error) errorMetadata.code = error.code;
|
|
104
|
+
if ("errno" in error) errorMetadata.errno = error.errno;
|
|
105
|
+
if ("syscall" in error) errorMetadata.syscall = error.syscall;
|
|
106
|
+
if ("path" in error) errorMetadata.path = error.path;
|
|
107
|
+
if (Object.keys(errorMetadata).length > 0) {
|
|
108
|
+
result.metadata = errorMetadata;
|
|
109
|
+
}
|
|
51
110
|
return result;
|
|
52
111
|
}
|
|
53
112
|
if (typeof error === "string") {
|
|
54
|
-
return {
|
|
113
|
+
return {
|
|
114
|
+
type: "Error",
|
|
115
|
+
message: error,
|
|
116
|
+
language: "nodejs"
|
|
117
|
+
};
|
|
55
118
|
}
|
|
56
119
|
if (typeof error === "object" && error !== null) {
|
|
57
|
-
|
|
120
|
+
const obj = error;
|
|
121
|
+
return {
|
|
122
|
+
type: typeof obj.type === "string" ? obj.type : typeof obj.name === "string" ? obj.name : "Error",
|
|
123
|
+
message: typeof obj.message === "string" ? obj.message : JSON.stringify(error),
|
|
124
|
+
language: "nodejs",
|
|
125
|
+
metadata: obj
|
|
126
|
+
};
|
|
58
127
|
}
|
|
59
|
-
return {
|
|
128
|
+
return {
|
|
129
|
+
type: "Error",
|
|
130
|
+
message: String(error),
|
|
131
|
+
language: "nodejs"
|
|
132
|
+
};
|
|
60
133
|
}
|
|
61
134
|
var LogTideClient = class {
|
|
62
135
|
apiUrl;
|
|
@@ -240,6 +313,12 @@ var LogTideClient = class {
|
|
|
240
313
|
return arg;
|
|
241
314
|
});
|
|
242
315
|
}
|
|
316
|
+
if (level === "error" || level === "critical") {
|
|
317
|
+
const errorArg = args.find((arg) => arg instanceof Error);
|
|
318
|
+
if (errorArg instanceof Error) {
|
|
319
|
+
metadata.exception = serializeError(errorArg);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
243
322
|
this.log({
|
|
244
323
|
service: config.service,
|
|
245
324
|
level,
|
|
@@ -395,7 +474,7 @@ var LogTideClient = class {
|
|
|
395
474
|
error(service, message, metadataOrError) {
|
|
396
475
|
let metadata = {};
|
|
397
476
|
if (metadataOrError instanceof Error) {
|
|
398
|
-
metadata = {
|
|
477
|
+
metadata = { exception: serializeError(metadataOrError) };
|
|
399
478
|
} else if (metadataOrError) {
|
|
400
479
|
metadata = metadataOrError;
|
|
401
480
|
}
|
|
@@ -404,7 +483,7 @@ var LogTideClient = class {
|
|
|
404
483
|
critical(service, message, metadataOrError) {
|
|
405
484
|
let metadata = {};
|
|
406
485
|
if (metadataOrError instanceof Error) {
|
|
407
|
-
metadata = {
|
|
486
|
+
metadata = { exception: serializeError(metadataOrError) };
|
|
408
487
|
} else if (metadataOrError) {
|
|
409
488
|
metadata = metadataOrError;
|
|
410
489
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { randomUUID } from 'crypto';\n\n// ==================== Types ====================\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'critical';\n\nexport interface ConsoleInterceptOptions {\n enabled: boolean;\n service?: string;\n preserveOriginal?: boolean;\n includeStackTrace?: boolean;\n levels?: {\n log?: boolean;\n info?: boolean;\n warn?: boolean;\n error?: boolean;\n debug?: boolean;\n };\n}\n\nexport interface PayloadLimitsOptions {\n /** Maximum size in bytes for a single field value (default: 10KB) */\n maxFieldSize?: number;\n /** Maximum size in bytes for the entire log entry (default: 100KB) */\n maxLogSize?: number;\n /** Fields to exclude from metadata (e.g., ['body', 'requestBody', 'responseBody']) */\n excludeFields?: string[];\n /** Marker to append when a field is truncated (default: '...[TRUNCATED]') */\n truncationMarker?: string;\n}\n\nexport interface LogTideClientOptions {\n apiUrl: string;\n apiKey: string;\n batchSize?: number;\n flushInterval?: number;\n maxBufferSize?: number;\n maxRetries?: number;\n retryDelayMs?: number;\n circuitBreakerThreshold?: number;\n circuitBreakerResetMs?: number;\n enableMetrics?: boolean;\n debug?: boolean;\n globalMetadata?: Record<string, unknown>;\n autoTraceId?: boolean;\n interceptConsole?: ConsoleInterceptOptions;\n /** Payload size limits to prevent 413 errors */\n payloadLimits?: PayloadLimitsOptions;\n}\n\nexport interface LogEntry {\n service: string;\n level: LogLevel;\n message: string;\n time?: string;\n metadata?: Record<string, unknown>;\n trace_id?: string;\n}\n\nexport interface InternalLogEntry extends LogEntry {\n time: string;\n}\n\nexport interface QueryOptions {\n service?: string;\n level?: LogLevel;\n from?: Date | string;\n to?: Date | string;\n q?: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface LogsResponse {\n logs: InternalLogEntry[];\n total: number;\n limit: number;\n offset: number;\n}\n\nexport interface AggregatedStatsOptions {\n from: Date | string;\n to: Date | string;\n interval?: '1m' | '5m' | '1h' | '1d';\n service?: string;\n}\n\nexport interface AggregatedStatsResponse {\n timeseries: Array<{\n bucket: string;\n total: number;\n by_level: Record<string, number>;\n }>;\n top_services: Array<{ service: string; count: number }>;\n top_errors: Array<{ message: string; count: number }>;\n}\n\nexport interface ClientMetrics {\n logsSent: number;\n logsDropped: number;\n errors: number;\n retries: number;\n avgLatencyMs: number;\n circuitBreakerTrips: number;\n}\n\nexport interface StreamOptions {\n service?: string;\n level?: LogLevel;\n onLog: (log: InternalLogEntry) => void;\n onError?: (error: Error) => void;\n}\n\n// ==================== Circuit Breaker ====================\n\nenum CircuitState {\n CLOSED = 'CLOSED',\n OPEN = 'OPEN',\n HALF_OPEN = 'HALF_OPEN',\n}\n\nclass CircuitBreaker {\n private state: CircuitState = CircuitState.CLOSED;\n private failureCount = 0;\n private lastFailureTime: number | null = null;\n\n constructor(\n private threshold: number,\n private resetMs: number,\n ) {}\n\n recordSuccess() {\n this.failureCount = 0;\n this.state = CircuitState.CLOSED;\n }\n\n recordFailure() {\n this.failureCount++;\n this.lastFailureTime = Date.now();\n\n if (this.failureCount >= this.threshold) {\n this.state = CircuitState.OPEN;\n }\n }\n\n canAttempt(): boolean {\n if (this.state === CircuitState.CLOSED) {\n return true;\n }\n\n if (this.state === CircuitState.OPEN) {\n const now = Date.now();\n if (this.lastFailureTime && now - this.lastFailureTime >= this.resetMs) {\n this.state = CircuitState.HALF_OPEN;\n return true;\n }\n return false;\n }\n\n // HALF_OPEN state - allow one attempt\n return true;\n }\n\n getState(): CircuitState {\n return this.state;\n }\n}\n\n\n// ==================== Error Serialization ====================\n\nexport function serializeError(error: unknown): Record<string, unknown> {\n if (error instanceof Error) {\n const result: Record<string, unknown> = {\n name: error.name,\n message: error.message,\n stack: error.stack,\n };\n\n if (error.cause) {\n result.cause = serializeError(error.cause);\n }\n\n return result;\n }\n\n if (typeof error === 'string') {\n return { message: error };\n }\n\n if (typeof error === 'object' && error !== null) {\n return error as Record<string, unknown>;\n }\n\n return { message: String(error) };\n}\n\n// ==================== Main Client ====================\n\nexport class LogTideClient {\n private apiUrl: string;\n private apiKey: string;\n private batchSize: number;\n private flushInterval: number;\n private maxBufferSize: number;\n private maxRetries: number;\n private retryDelayMs: number;\n private enableMetrics: boolean;\n private debugMode: boolean;\n private globalMetadata: Record<string, unknown>;\n private autoTraceId: boolean;\n\n private buffer: InternalLogEntry[] = [];\n private timer: NodeJS.Timeout | null = null;\n private circuitBreaker: CircuitBreaker;\n\n // Metrics\n private metrics: ClientMetrics = {\n logsSent: 0,\n logsDropped: 0,\n errors: 0,\n retries: 0,\n avgLatencyMs: 0,\n circuitBreakerTrips: 0,\n };\n private latencies: number[] = [];\n\n // Context tracking\n private currentTraceId: string | null = null;\n\n // Console interception\n private consoleInterceptOptions: ConsoleInterceptOptions | null = null;\n private originalConsole: {\n log: typeof console.log;\n info: typeof console.info;\n warn: typeof console.warn;\n error: typeof console.error;\n debug: typeof console.debug;\n } | null = null;\n\n // Payload limits\n private payloadLimits: Required<PayloadLimitsOptions>;\n\n constructor(options: LogTideClientOptions) {\n this.apiUrl = options.apiUrl.replace(/\\/$/, '');\n this.apiKey = options.apiKey;\n this.batchSize = options.batchSize || 100;\n this.flushInterval = options.flushInterval || 5000;\n this.maxBufferSize = options.maxBufferSize || 10000;\n this.maxRetries = options.maxRetries || 3;\n this.retryDelayMs = options.retryDelayMs || 1000;\n this.enableMetrics = options.enableMetrics ?? true;\n this.debugMode = options.debug ?? false;\n this.globalMetadata = options.globalMetadata || {};\n this.autoTraceId = options.autoTraceId ?? false;\n\n this.circuitBreaker = new CircuitBreaker(\n options.circuitBreakerThreshold || 5,\n options.circuitBreakerResetMs || 30000,\n );\n\n // Initialize payload limits with defaults\n this.payloadLimits = {\n maxFieldSize: options.payloadLimits?.maxFieldSize ?? 10 * 1024, // 10KB\n maxLogSize: options.payloadLimits?.maxLogSize ?? 100 * 1024, // 100KB\n excludeFields: options.payloadLimits?.excludeFields ?? [],\n truncationMarker: options.payloadLimits?.truncationMarker ?? '...[TRUNCATED]',\n };\n\n this.startFlushTimer();\n\n // Start console interception if configured\n if (options.interceptConsole?.enabled) {\n this.startConsoleInterception(options.interceptConsole);\n }\n }\n\n // ==================== Context Helpers ====================\n\n /**\n * Set trace ID for subsequent logs\n */\n setTraceId(traceId: string | null) {\n this.currentTraceId = traceId;\n }\n\n /**\n * Get current trace ID\n */\n getTraceId(): string | null {\n return this.currentTraceId;\n }\n\n /**\n * Execute function with a specific trace ID context\n */\n withTraceId<T>(traceId: string, fn: () => T): T {\n const previousTraceId = this.currentTraceId;\n this.currentTraceId = traceId;\n try {\n return fn();\n } finally {\n this.currentTraceId = previousTraceId;\n }\n }\n\n /**\n * Execute function with a new auto-generated trace ID\n */\n withNewTraceId<T>(fn: () => T): T {\n return this.withTraceId(randomUUID(), fn);\n }\n\n // ==================== Console Interception ====================\n\n /**\n * Start intercepting console methods and forward them to LogTide\n */\n startConsoleInterception(options?: Partial<ConsoleInterceptOptions>) {\n if (this.originalConsole) {\n // Already intercepting\n return;\n }\n\n const config: ConsoleInterceptOptions = {\n enabled: true,\n service: options?.service ?? 'console',\n preserveOriginal: options?.preserveOriginal ?? true,\n includeStackTrace: options?.includeStackTrace ?? false,\n levels: {\n log: options?.levels?.log ?? true,\n info: options?.levels?.info ?? true,\n warn: options?.levels?.warn ?? true,\n error: options?.levels?.error ?? true,\n debug: options?.levels?.debug ?? true,\n },\n };\n\n this.consoleInterceptOptions = config;\n\n // Save original console methods\n this.originalConsole = {\n log: console.log.bind(console),\n info: console.info.bind(console),\n warn: console.warn.bind(console),\n error: console.error.bind(console),\n debug: console.debug.bind(console),\n };\n\n const createInterceptor = (\n method: 'log' | 'info' | 'warn' | 'error' | 'debug',\n level: LogLevel,\n ) => {\n const original = this.originalConsole![method];\n\n return (...args: unknown[]) => {\n // Always call original if preserveOriginal is true\n if (config.preserveOriginal) {\n original(...args);\n }\n\n // Skip if this method is not configured for interception\n if (!config.levels?.[method]) {\n return;\n }\n\n // Skip internal LogTide logs to prevent infinite loops\n const message = args\n .map((arg) => {\n if (typeof arg === 'string') return arg;\n if (arg instanceof Error) return arg.message;\n try {\n return JSON.stringify(arg);\n } catch {\n return String(arg);\n }\n })\n .join(' ');\n\n if (message.startsWith('[LogTide]')) {\n return;\n }\n\n // Build metadata\n const metadata: Record<string, unknown> = {\n source: 'console',\n originalMethod: method,\n };\n\n // Include stack trace if configured\n if (config.includeStackTrace) {\n const stack = new Error().stack;\n if (stack) {\n // Remove the first two lines (Error + this interceptor function)\n const stackLines = stack.split('\\n').slice(2);\n metadata.stackTrace = stackLines.join('\\n');\n\n // Extract caller location from first relevant stack line\n const callerLine = stackLines[0];\n if (callerLine) {\n const match = callerLine.match(/at\\s+(.+?)\\s+\\((.+):(\\d+):(\\d+)\\)/);\n if (match) {\n metadata.caller = {\n function: match[1],\n file: match[2],\n line: parseInt(match[3], 10),\n column: parseInt(match[4], 10),\n };\n } else {\n // Try alternative format: \"at file:line:column\"\n const altMatch = callerLine.match(/at\\s+(.+):(\\d+):(\\d+)/);\n if (altMatch) {\n metadata.caller = {\n file: altMatch[1],\n line: parseInt(altMatch[2], 10),\n column: parseInt(altMatch[3], 10),\n };\n }\n }\n }\n }\n }\n\n // Include raw arguments for complex objects\n if (args.length > 1 || (args.length === 1 && typeof args[0] !== 'string')) {\n metadata.args = args.map((arg) => {\n if (arg instanceof Error) {\n return serializeError(arg);\n }\n return arg;\n });\n }\n\n // Log to LogTide\n this.log({\n service: config.service!,\n level,\n message,\n metadata,\n });\n };\n };\n\n // Replace console methods\n console.log = createInterceptor('log', 'info');\n console.info = createInterceptor('info', 'info');\n console.warn = createInterceptor('warn', 'warn');\n console.error = createInterceptor('error', 'error');\n console.debug = createInterceptor('debug', 'debug');\n\n if (this.debugMode) {\n this.originalConsole.log('[LogTide] Console interception started');\n }\n }\n\n /**\n * Stop intercepting console methods and restore originals\n */\n stopConsoleInterception() {\n if (!this.originalConsole) {\n return;\n }\n\n // Restore original console methods\n console.log = this.originalConsole.log;\n console.info = this.originalConsole.info;\n console.warn = this.originalConsole.warn;\n console.error = this.originalConsole.error;\n console.debug = this.originalConsole.debug;\n\n if (this.debugMode) {\n console.log('[LogTide] Console interception stopped');\n }\n\n this.originalConsole = null;\n this.consoleInterceptOptions = null;\n }\n\n /**\n * Check if console interception is active\n */\n isConsoleInterceptionActive(): boolean {\n return this.originalConsole !== null;\n }\n\n // ==================== Payload Processing ====================\n\n /**\n * Check if a string looks like base64 encoded data\n */\n private looksLikeBase64(str: string): boolean {\n if (typeof str !== 'string' || str.length < 100) return false;\n // Check for common base64 patterns: data URLs or long base64 strings\n if (str.startsWith('data:')) return true;\n // Check if it's a long string with only base64 characters\n const base64Regex = /^[A-Za-z0-9+/=]{100,}$/;\n return base64Regex.test(str.replace(/\\s/g, ''));\n }\n\n /**\n * Process a value for payload limits (truncation, base64 removal, etc.)\n */\n private processValue(value: unknown, fieldPath: string): unknown {\n // Check if this field should be excluded\n const fieldName = fieldPath.split('.').pop() || fieldPath;\n if (this.payloadLimits.excludeFields.includes(fieldName)) {\n return '[EXCLUDED]';\n }\n\n if (value === null || value === undefined) {\n return value;\n }\n\n if (typeof value === 'string') {\n // Check for base64 data\n if (this.looksLikeBase64(value)) {\n return '[BASE64 DATA REMOVED]';\n }\n // Truncate if too long\n if (value.length > this.payloadLimits.maxFieldSize) {\n return value.substring(0, this.payloadLimits.maxFieldSize) + this.payloadLimits.truncationMarker;\n }\n return value;\n }\n\n if (Array.isArray(value)) {\n return value.map((item, index) => this.processValue(item, `${fieldPath}[${index}]`));\n }\n\n if (typeof value === 'object') {\n const processed: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n processed[key] = this.processValue(val, `${fieldPath}.${key}`);\n }\n return processed;\n }\n\n return value;\n }\n\n /**\n * Process metadata to apply payload limits\n */\n private processMetadata(metadata: Record<string, unknown> | undefined): Record<string, unknown> | undefined {\n if (!metadata) return metadata;\n return this.processValue(metadata, 'metadata') as Record<string, unknown>;\n }\n\n /**\n * Ensure log entry doesn't exceed max size\n */\n private enforceMaxLogSize(entry: InternalLogEntry): InternalLogEntry {\n const serialized = JSON.stringify(entry);\n if (serialized.length <= this.payloadLimits.maxLogSize) {\n return entry;\n }\n\n // Log is too large, progressively truncate metadata\n if (this.debugMode) {\n console.warn(`[LogTide] Log entry too large (${serialized.length} bytes), truncating metadata`);\n }\n\n // Create a copy and truncate metadata heavily\n const truncated: InternalLogEntry = {\n ...entry,\n metadata: {\n _truncated: true,\n _originalSize: serialized.length,\n message: entry.message,\n },\n };\n\n return truncated;\n }\n\n // ==================== Logging Methods ====================\n\n private startFlushTimer() {\n this.timer = setInterval(() => {\n this.flush();\n }, this.flushInterval);\n }\n\n log(entry: LogEntry) {\n // Check buffer size limit\n if (this.buffer.length >= this.maxBufferSize) {\n this.metrics.logsDropped++;\n if (this.debugMode) {\n console.warn(`[LogTide] Buffer full, dropping log: ${entry.message}`);\n }\n return;\n }\n\n // Determine trace_id: use entry's trace_id, current context, or auto-generate if enabled\n const traceId = entry.trace_id || this.currentTraceId || (this.autoTraceId ? randomUUID() : undefined);\n\n // Merge and process metadata (applies truncation, exclusion, base64 removal)\n const mergedMetadata = {\n ...this.globalMetadata,\n ...entry.metadata,\n };\n const processedMetadata = this.processMetadata(mergedMetadata);\n\n let internalEntry: InternalLogEntry = {\n ...entry,\n time: entry.time || new Date().toISOString(),\n metadata: processedMetadata,\n trace_id: traceId,\n };\n\n // Enforce max log size\n internalEntry = this.enforceMaxLogSize(internalEntry);\n\n this.buffer.push(internalEntry);\n\n if (this.buffer.length >= this.batchSize) {\n this.flush();\n }\n }\n\n debug(service: string, message: string, metadata?: Record<string, unknown>) {\n this.log({ service, level: 'debug', message, metadata });\n }\n\n info(service: string, message: string, metadata?: Record<string, unknown>) {\n this.log({ service, level: 'info', message, metadata });\n }\n\n warn(service: string, message: string, metadata?: Record<string, unknown>) {\n this.log({ service, level: 'warn', message, metadata });\n }\n\n error(service: string, message: string, metadataOrError?: Record<string, unknown> | Error) {\n let metadata: Record<string, unknown> = {};\n\n if (metadataOrError instanceof Error) {\n metadata = { error: serializeError(metadataOrError) };\n } else if (metadataOrError) {\n metadata = metadataOrError;\n }\n\n this.log({ service, level: 'error', message, metadata });\n }\n\n critical(service: string, message: string, metadataOrError?: Record<string, unknown> | Error) {\n let metadata: Record<string, unknown> = {};\n\n if (metadataOrError instanceof Error) {\n metadata = { error: serializeError(metadataOrError) };\n } else if (metadataOrError) {\n metadata = metadataOrError;\n }\n\n this.log({ service, level: 'critical', message, metadata });\n }\n\n // ==================== Flush with Retry & Circuit Breaker ====================\n\n async flush() {\n if (this.buffer.length === 0) return;\n\n // Check circuit breaker\n if (!this.circuitBreaker.canAttempt()) {\n this.metrics.circuitBreakerTrips++;\n if (this.debugMode) {\n console.warn('[LogTide] Circuit breaker OPEN, skipping flush');\n }\n return;\n }\n\n const logs = [...this.buffer];\n this.buffer = [];\n\n const startTime = Date.now();\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n try {\n const response = await fetch(`${this.apiUrl}/api/v1/ingest`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-API-Key': this.apiKey,\n },\n body: JSON.stringify({ logs }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`HTTP ${response.status}: ${errorText}`);\n }\n\n // Success\n this.circuitBreaker.recordSuccess();\n this.metrics.logsSent += logs.length;\n\n if (this.enableMetrics) {\n const latency = Date.now() - startTime;\n this.latencies.push(latency);\n if (this.latencies.length > 100) {\n this.latencies.shift();\n }\n this.metrics.avgLatencyMs =\n this.latencies.reduce((a, b) => a + b, 0) / this.latencies.length;\n }\n\n if (this.debugMode) {\n console.log(`[LogTide] Sent ${logs.length} logs successfully`);\n }\n\n return;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n this.metrics.errors++;\n\n if (attempt < this.maxRetries) {\n this.metrics.retries++;\n const delay = this.retryDelayMs * Math.pow(2, attempt);\n if (this.debugMode) {\n console.warn(\n `[LogTide] Retry ${attempt + 1}/${this.maxRetries} after ${delay}ms: ${lastError.message}`,\n );\n }\n await this.sleep(delay);\n }\n }\n }\n\n // All retries failed\n this.circuitBreaker.recordFailure();\n\n if (this.debugMode) {\n console.error(`[LogTide] Failed to send logs after ${this.maxRetries} retries:`, lastError);\n }\n\n // Re-add logs to buffer if not full\n if (this.buffer.length + logs.length <= this.maxBufferSize) {\n this.buffer.unshift(...logs);\n } else {\n this.metrics.logsDropped += logs.length;\n }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n // ==================== Query Methods ====================\n\n async query(options: QueryOptions = {}): Promise<LogsResponse> {\n const params = new URLSearchParams();\n\n if (options.service) params.append('service', options.service);\n if (options.level) params.append('level', options.level);\n if (options.from) {\n const from = options.from instanceof Date ? options.from.toISOString() : options.from;\n params.append('from', from);\n }\n if (options.to) {\n const to = options.to instanceof Date ? options.to.toISOString() : options.to;\n params.append('to', to);\n }\n if (options.q) params.append('q', options.q);\n if (options.limit) params.append('limit', String(options.limit));\n if (options.offset) params.append('offset', String(options.offset));\n\n const url = `${this.apiUrl}/api/v1/logs?${params.toString()}`;\n\n const response = await fetch(url, {\n headers: {\n 'X-API-Key': this.apiKey,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Query failed: HTTP ${response.status}: ${errorText}`);\n }\n\n return (await response.json()) as LogsResponse;\n }\n\n async getByTraceId(traceId: string): Promise<InternalLogEntry[]> {\n const url = `${this.apiUrl}/api/v1/logs/trace/${traceId}`;\n\n const response = await fetch(url, {\n headers: {\n 'X-API-Key': this.apiKey,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Get by trace ID failed: HTTP ${response.status}: ${errorText}`);\n }\n\n const data = (await response.json()) as { logs?: InternalLogEntry[] };\n return data.logs || [];\n }\n\n async getAggregatedStats(options: AggregatedStatsOptions): Promise<AggregatedStatsResponse> {\n const params = new URLSearchParams();\n\n const from = options.from instanceof Date ? options.from.toISOString() : options.from;\n const to = options.to instanceof Date ? options.to.toISOString() : options.to;\n\n params.append('from', from);\n params.append('to', to);\n if (options.interval) params.append('interval', options.interval);\n if (options.service) params.append('service', options.service);\n\n const url = `${this.apiUrl}/api/v1/logs/aggregated?${params.toString()}`;\n\n const response = await fetch(url, {\n headers: {\n 'X-API-Key': this.apiKey,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Get aggregated stats failed: HTTP ${response.status}: ${errorText}`);\n }\n\n return (await response.json()) as AggregatedStatsResponse;\n }\n\n // ==================== Live Tail (SSE) ====================\n\n stream(options: StreamOptions): () => void {\n const params = new URLSearchParams();\n params.append('token', this.apiKey);\n if (options.service) params.append('service', options.service);\n if (options.level) params.append('level', options.level);\n\n const url = `${this.apiUrl}/api/v1/logs/stream?${params.toString()}`;\n\n const eventSource = new EventSource(url);\n\n eventSource.addEventListener('log', (event: Event) => {\n try {\n const messageEvent = event as MessageEvent;\n const log = JSON.parse(messageEvent.data) as InternalLogEntry;\n options.onLog(log);\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n options.onError?.(err);\n }\n });\n\n eventSource.addEventListener('error', () => {\n const error = new Error('SSE connection error');\n options.onError?.(error);\n });\n\n // Return cleanup function\n return () => {\n eventSource.close();\n };\n }\n\n // ==================== Metrics ====================\n\n getMetrics(): ClientMetrics {\n return { ...this.metrics };\n }\n\n resetMetrics() {\n this.metrics = {\n logsSent: 0,\n logsDropped: 0,\n errors: 0,\n retries: 0,\n avgLatencyMs: 0,\n circuitBreakerTrips: 0,\n };\n this.latencies = [];\n }\n\n getCircuitBreakerState(): string {\n return this.circuitBreaker.getState();\n }\n\n // ==================== Cleanup ====================\n\n async close() {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n this.stopConsoleInterception();\n await this.flush();\n }\n}\n\nexport default LogTideClient;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { randomUUID } from 'crypto';\n\n// ==================== Types ====================\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'critical';\n\nexport interface ConsoleInterceptOptions {\n enabled: boolean;\n service?: string;\n preserveOriginal?: boolean;\n includeStackTrace?: boolean;\n levels?: {\n log?: boolean;\n info?: boolean;\n warn?: boolean;\n error?: boolean;\n debug?: boolean;\n };\n}\n\nexport interface PayloadLimitsOptions {\n /** Maximum size in bytes for a single field value (default: 10KB) */\n maxFieldSize?: number;\n /** Maximum size in bytes for the entire log entry (default: 100KB) */\n maxLogSize?: number;\n /** Fields to exclude from metadata (e.g., ['body', 'requestBody', 'responseBody']) */\n excludeFields?: string[];\n /** Marker to append when a field is truncated (default: '...[TRUNCATED]') */\n truncationMarker?: string;\n}\n\nexport interface LogTideClientOptions {\n apiUrl: string;\n apiKey: string;\n batchSize?: number;\n flushInterval?: number;\n maxBufferSize?: number;\n maxRetries?: number;\n retryDelayMs?: number;\n circuitBreakerThreshold?: number;\n circuitBreakerResetMs?: number;\n enableMetrics?: boolean;\n debug?: boolean;\n globalMetadata?: Record<string, unknown>;\n autoTraceId?: boolean;\n interceptConsole?: ConsoleInterceptOptions;\n /** Payload size limits to prevent 413 errors */\n payloadLimits?: PayloadLimitsOptions;\n}\n\nexport interface LogEntry {\n service: string;\n level: LogLevel;\n message: string;\n time?: string;\n metadata?: Record<string, unknown>;\n trace_id?: string;\n}\n\nexport interface InternalLogEntry extends LogEntry {\n time: string;\n}\n\nexport interface QueryOptions {\n service?: string;\n level?: LogLevel;\n from?: Date | string;\n to?: Date | string;\n q?: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface LogsResponse {\n logs: InternalLogEntry[];\n total: number;\n limit: number;\n offset: number;\n}\n\nexport interface AggregatedStatsOptions {\n from: Date | string;\n to: Date | string;\n interval?: '1m' | '5m' | '1h' | '1d';\n service?: string;\n}\n\nexport interface AggregatedStatsResponse {\n timeseries: Array<{\n bucket: string;\n total: number;\n by_level: Record<string, number>;\n }>;\n top_services: Array<{ service: string; count: number }>;\n top_errors: Array<{ message: string; count: number }>;\n}\n\nexport interface ClientMetrics {\n logsSent: number;\n logsDropped: number;\n errors: number;\n retries: number;\n avgLatencyMs: number;\n circuitBreakerTrips: number;\n}\n\nexport interface StreamOptions {\n service?: string;\n level?: LogLevel;\n onLog: (log: InternalLogEntry) => void;\n onError?: (error: Error) => void;\n}\n\n// ==================== Circuit Breaker ====================\n\nenum CircuitState {\n CLOSED = 'CLOSED',\n OPEN = 'OPEN',\n HALF_OPEN = 'HALF_OPEN',\n}\n\nclass CircuitBreaker {\n private state: CircuitState = CircuitState.CLOSED;\n private failureCount = 0;\n private lastFailureTime: number | null = null;\n\n constructor(\n private threshold: number,\n private resetMs: number,\n ) {}\n\n recordSuccess() {\n this.failureCount = 0;\n this.state = CircuitState.CLOSED;\n }\n\n recordFailure() {\n this.failureCount++;\n this.lastFailureTime = Date.now();\n\n if (this.failureCount >= this.threshold) {\n this.state = CircuitState.OPEN;\n }\n }\n\n canAttempt(): boolean {\n if (this.state === CircuitState.CLOSED) {\n return true;\n }\n\n if (this.state === CircuitState.OPEN) {\n const now = Date.now();\n if (this.lastFailureTime && now - this.lastFailureTime >= this.resetMs) {\n this.state = CircuitState.HALF_OPEN;\n return true;\n }\n return false;\n }\n\n // HALF_OPEN state - allow one attempt\n return true;\n }\n\n getState(): CircuitState {\n return this.state;\n }\n}\n\n\n// ==================== Structured Exception Types ====================\n\nexport interface StructuredStackFrame {\n /** File path or module name */\n file?: string;\n /** Function/method name */\n function?: string;\n /** Line number (1-based) */\n line?: number;\n /** Column number */\n column?: number;\n /** Additional frame metadata */\n metadata?: Record<string, unknown>;\n}\n\nexport interface StructuredException {\n /** Exception type/class name (e.g., \"TypeError\", \"Error\") */\n type: string;\n /** Human-readable error message */\n message: string;\n /** Stack trace as an array of frames (top to bottom) */\n stacktrace?: StructuredStackFrame[];\n /** Language hint for better fingerprinting */\n language?: string;\n /** Inner/cause exception (for wrapped exceptions) */\n cause?: StructuredException;\n /** Additional exception metadata */\n metadata?: Record<string, unknown>;\n /** Original raw stack trace as a string (fallback) */\n raw?: string;\n}\n\n// ==================== Error Serialization ====================\n\n/**\n * Parse a V8/Node.js stack trace string into structured frames\n */\nfunction parseNodeStackTrace(stack: string | undefined): StructuredStackFrame[] {\n if (!stack) return [];\n\n const frames: StructuredStackFrame[] = [];\n const lines = stack.split('\\n');\n\n for (const line of lines) {\n // Skip the first line (error message) and empty lines\n const trimmed = line.trim();\n if (!trimmed.startsWith('at ')) continue;\n\n // Format 1: \"at functionName (file:line:column)\"\n const match1 = trimmed.match(/^at\\s+(.+?)\\s+\\((.+):(\\d+):(\\d+)\\)$/);\n if (match1) {\n frames.push({\n function: match1[1],\n file: match1[2],\n line: parseInt(match1[3], 10),\n column: parseInt(match1[4], 10),\n });\n continue;\n }\n\n // Format 2: \"at file:line:column\" (anonymous function)\n const match2 = trimmed.match(/^at\\s+(.+):(\\d+):(\\d+)$/);\n if (match2) {\n frames.push({\n file: match2[1],\n line: parseInt(match2[2], 10),\n column: parseInt(match2[3], 10),\n });\n continue;\n }\n\n // Format 3: \"at functionName (native)\" or similar\n const match3 = trimmed.match(/^at\\s+(.+?)\\s+\\((.+)\\)$/);\n if (match3) {\n frames.push({\n function: match3[1],\n file: match3[2],\n });\n continue;\n }\n\n // Format 4: \"at functionName\" (no file info)\n const match4 = trimmed.match(/^at\\s+(.+)$/);\n if (match4) {\n frames.push({\n function: match4[1],\n });\n }\n }\n\n return frames;\n}\n\n/**\n * Serialize an error into the StructuredException format\n */\nexport function serializeError(error: unknown): StructuredException {\n if (error instanceof Error) {\n const result: StructuredException = {\n type: error.name,\n message: error.message,\n language: 'nodejs',\n stacktrace: parseNodeStackTrace(error.stack),\n raw: error.stack,\n };\n\n // Handle error.cause (Node.js 16.9+)\n if (error.cause) {\n result.cause = serializeError(error.cause);\n }\n\n // Extract additional error properties as metadata\n const errorMetadata: Record<string, unknown> = {};\n const standardProps = ['name', 'message', 'stack', 'cause'];\n\n for (const key of Object.keys(error)) {\n if (!standardProps.includes(key)) {\n errorMetadata[key] = (error as unknown as Record<string, unknown>)[key];\n }\n }\n\n // Include common Node.js error properties\n if ('code' in error) errorMetadata.code = (error as NodeJS.ErrnoException).code;\n if ('errno' in error) errorMetadata.errno = (error as NodeJS.ErrnoException).errno;\n if ('syscall' in error) errorMetadata.syscall = (error as NodeJS.ErrnoException).syscall;\n if ('path' in error) errorMetadata.path = (error as NodeJS.ErrnoException).path;\n\n if (Object.keys(errorMetadata).length > 0) {\n result.metadata = errorMetadata;\n }\n\n return result;\n }\n\n if (typeof error === 'string') {\n return {\n type: 'Error',\n message: error,\n language: 'nodejs',\n };\n }\n\n if (typeof error === 'object' && error !== null) {\n // Try to extract type and message from the object\n const obj = error as Record<string, unknown>;\n return {\n type: (typeof obj.type === 'string' ? obj.type : typeof obj.name === 'string' ? obj.name : 'Error'),\n message: (typeof obj.message === 'string' ? obj.message : JSON.stringify(error)),\n language: 'nodejs',\n metadata: obj,\n };\n }\n\n return {\n type: 'Error',\n message: String(error),\n language: 'nodejs',\n };\n}\n\n// ==================== Main Client ====================\n\nexport class LogTideClient {\n private apiUrl: string;\n private apiKey: string;\n private batchSize: number;\n private flushInterval: number;\n private maxBufferSize: number;\n private maxRetries: number;\n private retryDelayMs: number;\n private enableMetrics: boolean;\n private debugMode: boolean;\n private globalMetadata: Record<string, unknown>;\n private autoTraceId: boolean;\n\n private buffer: InternalLogEntry[] = [];\n private timer: NodeJS.Timeout | null = null;\n private circuitBreaker: CircuitBreaker;\n\n // Metrics\n private metrics: ClientMetrics = {\n logsSent: 0,\n logsDropped: 0,\n errors: 0,\n retries: 0,\n avgLatencyMs: 0,\n circuitBreakerTrips: 0,\n };\n private latencies: number[] = [];\n\n // Context tracking\n private currentTraceId: string | null = null;\n\n // Console interception\n private consoleInterceptOptions: ConsoleInterceptOptions | null = null;\n private originalConsole: {\n log: typeof console.log;\n info: typeof console.info;\n warn: typeof console.warn;\n error: typeof console.error;\n debug: typeof console.debug;\n } | null = null;\n\n // Payload limits\n private payloadLimits: Required<PayloadLimitsOptions>;\n\n constructor(options: LogTideClientOptions) {\n this.apiUrl = options.apiUrl.replace(/\\/$/, '');\n this.apiKey = options.apiKey;\n this.batchSize = options.batchSize || 100;\n this.flushInterval = options.flushInterval || 5000;\n this.maxBufferSize = options.maxBufferSize || 10000;\n this.maxRetries = options.maxRetries || 3;\n this.retryDelayMs = options.retryDelayMs || 1000;\n this.enableMetrics = options.enableMetrics ?? true;\n this.debugMode = options.debug ?? false;\n this.globalMetadata = options.globalMetadata || {};\n this.autoTraceId = options.autoTraceId ?? false;\n\n this.circuitBreaker = new CircuitBreaker(\n options.circuitBreakerThreshold || 5,\n options.circuitBreakerResetMs || 30000,\n );\n\n // Initialize payload limits with defaults\n this.payloadLimits = {\n maxFieldSize: options.payloadLimits?.maxFieldSize ?? 10 * 1024, // 10KB\n maxLogSize: options.payloadLimits?.maxLogSize ?? 100 * 1024, // 100KB\n excludeFields: options.payloadLimits?.excludeFields ?? [],\n truncationMarker: options.payloadLimits?.truncationMarker ?? '...[TRUNCATED]',\n };\n\n this.startFlushTimer();\n\n // Start console interception if configured\n if (options.interceptConsole?.enabled) {\n this.startConsoleInterception(options.interceptConsole);\n }\n }\n\n // ==================== Context Helpers ====================\n\n /**\n * Set trace ID for subsequent logs\n */\n setTraceId(traceId: string | null) {\n this.currentTraceId = traceId;\n }\n\n /**\n * Get current trace ID\n */\n getTraceId(): string | null {\n return this.currentTraceId;\n }\n\n /**\n * Execute function with a specific trace ID context\n */\n withTraceId<T>(traceId: string, fn: () => T): T {\n const previousTraceId = this.currentTraceId;\n this.currentTraceId = traceId;\n try {\n return fn();\n } finally {\n this.currentTraceId = previousTraceId;\n }\n }\n\n /**\n * Execute function with a new auto-generated trace ID\n */\n withNewTraceId<T>(fn: () => T): T {\n return this.withTraceId(randomUUID(), fn);\n }\n\n // ==================== Console Interception ====================\n\n /**\n * Start intercepting console methods and forward them to LogTide\n */\n startConsoleInterception(options?: Partial<ConsoleInterceptOptions>) {\n if (this.originalConsole) {\n // Already intercepting\n return;\n }\n\n const config: ConsoleInterceptOptions = {\n enabled: true,\n service: options?.service ?? 'console',\n preserveOriginal: options?.preserveOriginal ?? true,\n includeStackTrace: options?.includeStackTrace ?? false,\n levels: {\n log: options?.levels?.log ?? true,\n info: options?.levels?.info ?? true,\n warn: options?.levels?.warn ?? true,\n error: options?.levels?.error ?? true,\n debug: options?.levels?.debug ?? true,\n },\n };\n\n this.consoleInterceptOptions = config;\n\n // Save original console methods\n this.originalConsole = {\n log: console.log.bind(console),\n info: console.info.bind(console),\n warn: console.warn.bind(console),\n error: console.error.bind(console),\n debug: console.debug.bind(console),\n };\n\n const createInterceptor = (\n method: 'log' | 'info' | 'warn' | 'error' | 'debug',\n level: LogLevel,\n ) => {\n const original = this.originalConsole![method];\n\n return (...args: unknown[]) => {\n // Always call original if preserveOriginal is true\n if (config.preserveOriginal) {\n original(...args);\n }\n\n // Skip if this method is not configured for interception\n if (!config.levels?.[method]) {\n return;\n }\n\n // Skip internal LogTide logs to prevent infinite loops\n const message = args\n .map((arg) => {\n if (typeof arg === 'string') return arg;\n if (arg instanceof Error) return arg.message;\n try {\n return JSON.stringify(arg);\n } catch {\n return String(arg);\n }\n })\n .join(' ');\n\n if (message.startsWith('[LogTide]')) {\n return;\n }\n\n // Build metadata\n const metadata: Record<string, unknown> = {\n source: 'console',\n originalMethod: method,\n };\n\n // Include stack trace if configured\n if (config.includeStackTrace) {\n const stack = new Error().stack;\n if (stack) {\n // Remove the first two lines (Error + this interceptor function)\n const stackLines = stack.split('\\n').slice(2);\n metadata.stackTrace = stackLines.join('\\n');\n\n // Extract caller location from first relevant stack line\n const callerLine = stackLines[0];\n if (callerLine) {\n const match = callerLine.match(/at\\s+(.+?)\\s+\\((.+):(\\d+):(\\d+)\\)/);\n if (match) {\n metadata.caller = {\n function: match[1],\n file: match[2],\n line: parseInt(match[3], 10),\n column: parseInt(match[4], 10),\n };\n } else {\n // Try alternative format: \"at file:line:column\"\n const altMatch = callerLine.match(/at\\s+(.+):(\\d+):(\\d+)/);\n if (altMatch) {\n metadata.caller = {\n file: altMatch[1],\n line: parseInt(altMatch[2], 10),\n column: parseInt(altMatch[3], 10),\n };\n }\n }\n }\n }\n }\n\n // Include raw arguments for complex objects\n if (args.length > 1 || (args.length === 1 && typeof args[0] !== 'string')) {\n metadata.args = args.map((arg) => {\n if (arg instanceof Error) {\n return serializeError(arg);\n }\n return arg;\n });\n }\n\n // For error level, if any argument is an Error, add it to metadata.exception\n if (level === 'error' || level === 'critical') {\n const errorArg = args.find((arg) => arg instanceof Error);\n if (errorArg instanceof Error) {\n metadata.exception = serializeError(errorArg);\n }\n }\n\n // Log to LogTide\n this.log({\n service: config.service!,\n level,\n message,\n metadata,\n });\n };\n };\n\n // Replace console methods\n console.log = createInterceptor('log', 'info');\n console.info = createInterceptor('info', 'info');\n console.warn = createInterceptor('warn', 'warn');\n console.error = createInterceptor('error', 'error');\n console.debug = createInterceptor('debug', 'debug');\n\n if (this.debugMode) {\n this.originalConsole.log('[LogTide] Console interception started');\n }\n }\n\n /**\n * Stop intercepting console methods and restore originals\n */\n stopConsoleInterception() {\n if (!this.originalConsole) {\n return;\n }\n\n // Restore original console methods\n console.log = this.originalConsole.log;\n console.info = this.originalConsole.info;\n console.warn = this.originalConsole.warn;\n console.error = this.originalConsole.error;\n console.debug = this.originalConsole.debug;\n\n if (this.debugMode) {\n console.log('[LogTide] Console interception stopped');\n }\n\n this.originalConsole = null;\n this.consoleInterceptOptions = null;\n }\n\n /**\n * Check if console interception is active\n */\n isConsoleInterceptionActive(): boolean {\n return this.originalConsole !== null;\n }\n\n // ==================== Payload Processing ====================\n\n /**\n * Check if a string looks like base64 encoded data\n */\n private looksLikeBase64(str: string): boolean {\n if (typeof str !== 'string' || str.length < 100) return false;\n // Check for common base64 patterns: data URLs or long base64 strings\n if (str.startsWith('data:')) return true;\n // Check if it's a long string with only base64 characters\n const base64Regex = /^[A-Za-z0-9+/=]{100,}$/;\n return base64Regex.test(str.replace(/\\s/g, ''));\n }\n\n /**\n * Process a value for payload limits (truncation, base64 removal, etc.)\n */\n private processValue(value: unknown, fieldPath: string): unknown {\n // Check if this field should be excluded\n const fieldName = fieldPath.split('.').pop() || fieldPath;\n if (this.payloadLimits.excludeFields.includes(fieldName)) {\n return '[EXCLUDED]';\n }\n\n if (value === null || value === undefined) {\n return value;\n }\n\n if (typeof value === 'string') {\n // Check for base64 data\n if (this.looksLikeBase64(value)) {\n return '[BASE64 DATA REMOVED]';\n }\n // Truncate if too long\n if (value.length > this.payloadLimits.maxFieldSize) {\n return value.substring(0, this.payloadLimits.maxFieldSize) + this.payloadLimits.truncationMarker;\n }\n return value;\n }\n\n if (Array.isArray(value)) {\n return value.map((item, index) => this.processValue(item, `${fieldPath}[${index}]`));\n }\n\n if (typeof value === 'object') {\n const processed: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n processed[key] = this.processValue(val, `${fieldPath}.${key}`);\n }\n return processed;\n }\n\n return value;\n }\n\n /**\n * Process metadata to apply payload limits\n */\n private processMetadata(metadata: Record<string, unknown> | undefined): Record<string, unknown> | undefined {\n if (!metadata) return metadata;\n return this.processValue(metadata, 'metadata') as Record<string, unknown>;\n }\n\n /**\n * Ensure log entry doesn't exceed max size\n */\n private enforceMaxLogSize(entry: InternalLogEntry): InternalLogEntry {\n const serialized = JSON.stringify(entry);\n if (serialized.length <= this.payloadLimits.maxLogSize) {\n return entry;\n }\n\n // Log is too large, progressively truncate metadata\n if (this.debugMode) {\n console.warn(`[LogTide] Log entry too large (${serialized.length} bytes), truncating metadata`);\n }\n\n // Create a copy and truncate metadata heavily\n const truncated: InternalLogEntry = {\n ...entry,\n metadata: {\n _truncated: true,\n _originalSize: serialized.length,\n message: entry.message,\n },\n };\n\n return truncated;\n }\n\n // ==================== Logging Methods ====================\n\n private startFlushTimer() {\n this.timer = setInterval(() => {\n this.flush();\n }, this.flushInterval);\n }\n\n log(entry: LogEntry) {\n // Check buffer size limit\n if (this.buffer.length >= this.maxBufferSize) {\n this.metrics.logsDropped++;\n if (this.debugMode) {\n console.warn(`[LogTide] Buffer full, dropping log: ${entry.message}`);\n }\n return;\n }\n\n // Determine trace_id: use entry's trace_id, current context, or auto-generate if enabled\n const traceId = entry.trace_id || this.currentTraceId || (this.autoTraceId ? randomUUID() : undefined);\n\n // Merge and process metadata (applies truncation, exclusion, base64 removal)\n const mergedMetadata = {\n ...this.globalMetadata,\n ...entry.metadata,\n };\n const processedMetadata = this.processMetadata(mergedMetadata);\n\n let internalEntry: InternalLogEntry = {\n ...entry,\n time: entry.time || new Date().toISOString(),\n metadata: processedMetadata,\n trace_id: traceId,\n };\n\n // Enforce max log size\n internalEntry = this.enforceMaxLogSize(internalEntry);\n\n this.buffer.push(internalEntry);\n\n if (this.buffer.length >= this.batchSize) {\n this.flush();\n }\n }\n\n debug(service: string, message: string, metadata?: Record<string, unknown>) {\n this.log({ service, level: 'debug', message, metadata });\n }\n\n info(service: string, message: string, metadata?: Record<string, unknown>) {\n this.log({ service, level: 'info', message, metadata });\n }\n\n warn(service: string, message: string, metadata?: Record<string, unknown>) {\n this.log({ service, level: 'warn', message, metadata });\n }\n\n error(service: string, message: string, metadataOrError?: Record<string, unknown> | Error) {\n let metadata: Record<string, unknown> = {};\n\n if (metadataOrError instanceof Error) {\n metadata = { exception: serializeError(metadataOrError) };\n } else if (metadataOrError) {\n metadata = metadataOrError;\n }\n\n this.log({ service, level: 'error', message, metadata });\n }\n\n critical(service: string, message: string, metadataOrError?: Record<string, unknown> | Error) {\n let metadata: Record<string, unknown> = {};\n\n if (metadataOrError instanceof Error) {\n metadata = { exception: serializeError(metadataOrError) };\n } else if (metadataOrError) {\n metadata = metadataOrError;\n }\n\n this.log({ service, level: 'critical', message, metadata });\n }\n\n // ==================== Flush with Retry & Circuit Breaker ====================\n\n async flush() {\n if (this.buffer.length === 0) return;\n\n // Check circuit breaker\n if (!this.circuitBreaker.canAttempt()) {\n this.metrics.circuitBreakerTrips++;\n if (this.debugMode) {\n console.warn('[LogTide] Circuit breaker OPEN, skipping flush');\n }\n return;\n }\n\n const logs = [...this.buffer];\n this.buffer = [];\n\n const startTime = Date.now();\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n try {\n const response = await fetch(`${this.apiUrl}/api/v1/ingest`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-API-Key': this.apiKey,\n },\n body: JSON.stringify({ logs }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`HTTP ${response.status}: ${errorText}`);\n }\n\n // Success\n this.circuitBreaker.recordSuccess();\n this.metrics.logsSent += logs.length;\n\n if (this.enableMetrics) {\n const latency = Date.now() - startTime;\n this.latencies.push(latency);\n if (this.latencies.length > 100) {\n this.latencies.shift();\n }\n this.metrics.avgLatencyMs =\n this.latencies.reduce((a, b) => a + b, 0) / this.latencies.length;\n }\n\n if (this.debugMode) {\n console.log(`[LogTide] Sent ${logs.length} logs successfully`);\n }\n\n return;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n this.metrics.errors++;\n\n if (attempt < this.maxRetries) {\n this.metrics.retries++;\n const delay = this.retryDelayMs * Math.pow(2, attempt);\n if (this.debugMode) {\n console.warn(\n `[LogTide] Retry ${attempt + 1}/${this.maxRetries} after ${delay}ms: ${lastError.message}`,\n );\n }\n await this.sleep(delay);\n }\n }\n }\n\n // All retries failed\n this.circuitBreaker.recordFailure();\n\n if (this.debugMode) {\n console.error(`[LogTide] Failed to send logs after ${this.maxRetries} retries:`, lastError);\n }\n\n // Re-add logs to buffer if not full\n if (this.buffer.length + logs.length <= this.maxBufferSize) {\n this.buffer.unshift(...logs);\n } else {\n this.metrics.logsDropped += logs.length;\n }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n // ==================== Query Methods ====================\n\n async query(options: QueryOptions = {}): Promise<LogsResponse> {\n const params = new URLSearchParams();\n\n if (options.service) params.append('service', options.service);\n if (options.level) params.append('level', options.level);\n if (options.from) {\n const from = options.from instanceof Date ? options.from.toISOString() : options.from;\n params.append('from', from);\n }\n if (options.to) {\n const to = options.to instanceof Date ? options.to.toISOString() : options.to;\n params.append('to', to);\n }\n if (options.q) params.append('q', options.q);\n if (options.limit) params.append('limit', String(options.limit));\n if (options.offset) params.append('offset', String(options.offset));\n\n const url = `${this.apiUrl}/api/v1/logs?${params.toString()}`;\n\n const response = await fetch(url, {\n headers: {\n 'X-API-Key': this.apiKey,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Query failed: HTTP ${response.status}: ${errorText}`);\n }\n\n return (await response.json()) as LogsResponse;\n }\n\n async getByTraceId(traceId: string): Promise<InternalLogEntry[]> {\n const url = `${this.apiUrl}/api/v1/logs/trace/${traceId}`;\n\n const response = await fetch(url, {\n headers: {\n 'X-API-Key': this.apiKey,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Get by trace ID failed: HTTP ${response.status}: ${errorText}`);\n }\n\n const data = (await response.json()) as { logs?: InternalLogEntry[] };\n return data.logs || [];\n }\n\n async getAggregatedStats(options: AggregatedStatsOptions): Promise<AggregatedStatsResponse> {\n const params = new URLSearchParams();\n\n const from = options.from instanceof Date ? options.from.toISOString() : options.from;\n const to = options.to instanceof Date ? options.to.toISOString() : options.to;\n\n params.append('from', from);\n params.append('to', to);\n if (options.interval) params.append('interval', options.interval);\n if (options.service) params.append('service', options.service);\n\n const url = `${this.apiUrl}/api/v1/logs/aggregated?${params.toString()}`;\n\n const response = await fetch(url, {\n headers: {\n 'X-API-Key': this.apiKey,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Get aggregated stats failed: HTTP ${response.status}: ${errorText}`);\n }\n\n return (await response.json()) as AggregatedStatsResponse;\n }\n\n // ==================== Live Tail (SSE) ====================\n\n stream(options: StreamOptions): () => void {\n const params = new URLSearchParams();\n params.append('token', this.apiKey);\n if (options.service) params.append('service', options.service);\n if (options.level) params.append('level', options.level);\n\n const url = `${this.apiUrl}/api/v1/logs/stream?${params.toString()}`;\n\n const eventSource = new EventSource(url);\n\n eventSource.addEventListener('log', (event: Event) => {\n try {\n const messageEvent = event as MessageEvent;\n const log = JSON.parse(messageEvent.data) as InternalLogEntry;\n options.onLog(log);\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n options.onError?.(err);\n }\n });\n\n eventSource.addEventListener('error', () => {\n const error = new Error('SSE connection error');\n options.onError?.(error);\n });\n\n // Return cleanup function\n return () => {\n eventSource.close();\n };\n }\n\n // ==================== Metrics ====================\n\n getMetrics(): ClientMetrics {\n return { ...this.metrics };\n }\n\n resetMetrics() {\n this.metrics = {\n logsSent: 0,\n logsDropped: 0,\n errors: 0,\n retries: 0,\n avgLatencyMs: 0,\n circuitBreakerTrips: 0,\n };\n this.latencies = [];\n }\n\n getCircuitBreakerState(): string {\n return this.circuitBreaker.getState();\n }\n\n // ==================== Cleanup ====================\n\n async close() {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n this.stopConsoleInterception();\n await this.flush();\n }\n}\n\nexport default LogTideClient;\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@logtide/sdk-node",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Official Node.js SDK for LogTide (logtide.dev) - Self-hosted log management with advanced features: retry logic, circuit breaker, query API, live streaming, and middleware support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|