@mastra/loggers 1.3.6-alpha.3 → 1.3.6-alpha.4
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/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/reference-core-mastra-class.md +12 -4
- package/dist/upstash/index.cjs +31 -5
- package/dist/upstash/index.cjs.map +1 -1
- package/dist/upstash/index.d.ts +11 -0
- package/dist/upstash/index.d.ts.map +1 -1
- package/dist/upstash/index.js +31 -5
- package/dist/upstash/index.js.map +1 -1
- package/package.json +2 -2
package/dist/docs/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: mastra-loggers
|
|
|
3
3
|
description: Documentation for @mastra/loggers. Use when working with @mastra/loggers APIs, configuration, or implementation.
|
|
4
4
|
metadata:
|
|
5
5
|
package: "@mastra/loggers"
|
|
6
|
-
version: "1.3.6-alpha.
|
|
6
|
+
version: "1.3.6-alpha.4"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## When to use
|
|
@@ -131,10 +131,14 @@ Visit the [Configuration reference](https://mastra.ai/reference/configuration) f
|
|
|
131
131
|
|
|
132
132
|
**scheduler.enabled** (`boolean`): Explicitly enable or disable the scheduler.
|
|
133
133
|
|
|
134
|
-
**recovery** (`MastraRecoveryConfig`): Boot-time recovery behavior for orphaned agent and workflow runs. See Crash recovery. (Default: `{ durableAgents: 'off' }`)
|
|
134
|
+
**recovery** (`MastraRecoveryConfig`): Boot-time recovery behavior for orphaned agent and workflow runs. See Crash recovery. (Default: `{ durableAgents: 'off', workflows: 'auto', workflowConcurrency: 5 }`)
|
|
135
135
|
|
|
136
136
|
**recovery.durableAgents** (`'auto' | 'off'`): Set to 'auto' to automatically re-drive orphaned RUNNING durable agent runs on server boot. This also controls the default snapshot-persistence policy for durable agents: running checkpoints are only written when set to 'auto' (or when an agent sets a custom shouldPersistSnapshot that includes running). Recovery re-issues LLM calls and re-executes tool calls, so tools must be idempotent. See Crash recovery.
|
|
137
137
|
|
|
138
|
+
**recovery.workflows** (`'auto' | 'off'`): Set to 'off' to skip restarting active workflow runs on server boot. Individual workflows can also opt out with autoRestartActiveRuns: false.
|
|
139
|
+
|
|
140
|
+
**recovery.workflowConcurrency** (`number`): Maximum number of workflow runs restarted at the same time during boot recovery. Use Infinity for no limit. Workflow and durable agent recovery run in parallel.
|
|
141
|
+
|
|
138
142
|
## Methods
|
|
139
143
|
|
|
140
144
|
### `recoverAllDurableAgents()`
|
|
@@ -143,17 +147,21 @@ Re-drives every orphaned `running` durable-agent run across all registered durab
|
|
|
143
147
|
|
|
144
148
|
Requires persistent storage. With an in-memory store, there's nothing to recover after a process restart.
|
|
145
149
|
|
|
150
|
+
A run that another execution still drives isn't taken over. It's counted in `skipped` and checked again once that execution's claim could have lapsed, so a run whose process crashed is recovered without another call. `shutdown()` cancels pending re-checks. See [run ownership](https://mastra.ai/docs/harness/durable-agents).
|
|
151
|
+
|
|
146
152
|
```typescript
|
|
147
153
|
const result = await mastra.recoverAllDurableAgents()
|
|
148
|
-
// { agents: 2, recovered: 3, succeeded: 3, failed: 0 }
|
|
154
|
+
// { agents: 2, recovered: 3, succeeded: 3, failed: 0, skipped: 1 }
|
|
149
155
|
```
|
|
150
156
|
|
|
151
157
|
Returns:
|
|
152
158
|
|
|
153
159
|
**agents** (`number`): Number of durable agents scanned.
|
|
154
160
|
|
|
155
|
-
**recovered** (`number`): Total number of runs that were re-driven.
|
|
161
|
+
**recovered** (`number`): Total number of runs that were re-driven: succeeded plus failed.
|
|
156
162
|
|
|
157
163
|
**succeeded** (`number`): Runs that restarted successfully.
|
|
158
164
|
|
|
159
|
-
**failed** (`number`): Runs whose restart threw an error.
|
|
165
|
+
**failed** (`number`): Runs whose restart threw an error.
|
|
166
|
+
|
|
167
|
+
**skipped** (`number`): Runs that another execution still drives. Each is checked again later.
|
package/dist/upstash/index.cjs
CHANGED
|
@@ -6,11 +6,15 @@ var UpstashTransport = class extends _mastra_core_logger.LoggerTransport {
|
|
|
6
6
|
upstashToken;
|
|
7
7
|
listName;
|
|
8
8
|
maxListLength;
|
|
9
|
+
maxBufferSize;
|
|
10
|
+
/** Number of buffered records discarded because the buffer exceeded `maxBufferSize`. */
|
|
11
|
+
droppedRecords = 0;
|
|
9
12
|
batchSize;
|
|
10
13
|
flushInterval;
|
|
11
14
|
logBuffer;
|
|
12
15
|
lastFlush;
|
|
13
16
|
flushIntervalId;
|
|
17
|
+
flushPromise = null;
|
|
14
18
|
constructor(opts) {
|
|
15
19
|
super({ objectMode: true });
|
|
16
20
|
if (!opts.upstashUrl || !opts.upstashToken) throw new Error("Upstash URL and token are required");
|
|
@@ -18,6 +22,8 @@ var UpstashTransport = class extends _mastra_core_logger.LoggerTransport {
|
|
|
18
22
|
this.upstashToken = opts.upstashToken;
|
|
19
23
|
this.listName = opts.listName || "application-logs";
|
|
20
24
|
this.maxListLength = opts.maxListLength || 1e4;
|
|
25
|
+
this.maxBufferSize = opts.maxBufferSize ?? (this.maxListLength > 0 ? this.maxListLength : 1e4);
|
|
26
|
+
if (!Number.isInteger(this.maxBufferSize) || this.maxBufferSize < 1) throw new Error("maxBufferSize must be a positive integer");
|
|
21
27
|
this.batchSize = opts.batchSize || 100;
|
|
22
28
|
this.flushInterval = opts.flushInterval || 1e4;
|
|
23
29
|
this.logBuffer = [];
|
|
@@ -40,8 +46,17 @@ var UpstashTransport = class extends _mastra_core_logger.LoggerTransport {
|
|
|
40
46
|
if (!response.ok) throw new Error(`Failed to execute Upstash command: ${response.statusText}`);
|
|
41
47
|
return response.json();
|
|
42
48
|
}
|
|
43
|
-
|
|
44
|
-
|
|
49
|
+
/** Sends the next batch to Upstash. Callers share the in-flight flush instead of starting a new request. */
|
|
50
|
+
_flush() {
|
|
51
|
+
if (this.flushPromise) return this.flushPromise;
|
|
52
|
+
if (this.logBuffer.length === 0) return Promise.resolve();
|
|
53
|
+
this.flushPromise = this.flushBatch().finally(() => {
|
|
54
|
+
this.flushPromise = null;
|
|
55
|
+
});
|
|
56
|
+
return this.flushPromise;
|
|
57
|
+
}
|
|
58
|
+
/** Pushes one batch to Upstash, returning the records to the front of the buffer if the request fails. */
|
|
59
|
+
async flushBatch() {
|
|
45
60
|
const now = Date.now();
|
|
46
61
|
const logs = this.logBuffer.splice(0, this.batchSize);
|
|
47
62
|
try {
|
|
@@ -60,9 +75,18 @@ var UpstashTransport = class extends _mastra_core_logger.LoggerTransport {
|
|
|
60
75
|
this.lastFlush = now;
|
|
61
76
|
} catch (error) {
|
|
62
77
|
this.logBuffer.unshift(...logs);
|
|
78
|
+
this.enforceBufferLimit();
|
|
63
79
|
throw error;
|
|
64
80
|
}
|
|
65
81
|
}
|
|
82
|
+
/** Drops the oldest buffered records once the buffer exceeds `maxBufferSize`. */
|
|
83
|
+
enforceBufferLimit() {
|
|
84
|
+
const overflow = this.logBuffer.length - this.maxBufferSize;
|
|
85
|
+
if (overflow > 0) {
|
|
86
|
+
this.logBuffer.splice(0, overflow);
|
|
87
|
+
this.droppedRecords += overflow;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
66
90
|
_write(chunk, encoding, callback) {
|
|
67
91
|
if (typeof callback === "function") {
|
|
68
92
|
this._transform(chunk, encoding || "utf8", callback);
|
|
@@ -78,9 +102,10 @@ var UpstashTransport = class extends _mastra_core_logger.LoggerTransport {
|
|
|
78
102
|
const log = typeof chunk === "string" ? JSON.parse(chunk) : chunk;
|
|
79
103
|
if (!log.time) log.time = Date.now();
|
|
80
104
|
this.logBuffer.push(log);
|
|
81
|
-
if (this.logBuffer.length >= this.batchSize) this._flush().catch((err) => {
|
|
105
|
+
if (this.logBuffer.length >= Math.min(this.batchSize, this.maxBufferSize)) this._flush().catch((err) => {
|
|
82
106
|
console.error("Error flushing logs to Upstash:", err);
|
|
83
107
|
});
|
|
108
|
+
this.enforceBufferLimit();
|
|
84
109
|
cb(null, chunk);
|
|
85
110
|
} catch (error) {
|
|
86
111
|
cb(error);
|
|
@@ -88,14 +113,15 @@ var UpstashTransport = class extends _mastra_core_logger.LoggerTransport {
|
|
|
88
113
|
}
|
|
89
114
|
_destroy(err, cb) {
|
|
90
115
|
clearInterval(this.flushIntervalId);
|
|
91
|
-
if (this.logBuffer.length > 0) this.drainBuffer().then(() => cb(err)).catch((flushErr) => {
|
|
116
|
+
if (this.logBuffer.length > 0 || this.flushPromise) this.drainBuffer().then(() => cb(err)).catch((flushErr) => {
|
|
92
117
|
console.error("Error in final flush:", flushErr);
|
|
93
118
|
cb(err || flushErr);
|
|
94
119
|
});
|
|
95
120
|
else cb(err);
|
|
96
121
|
}
|
|
97
122
|
async drainBuffer() {
|
|
98
|
-
|
|
123
|
+
await this.flushPromise?.catch(() => {});
|
|
124
|
+
while (this.logBuffer.length > 0 || this.flushPromise) await (this.flushPromise ?? this._flush());
|
|
99
125
|
}
|
|
100
126
|
parseLogs(logs) {
|
|
101
127
|
if (!Array.isArray(logs)) return [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["LoggerTransport"],"sources":["../../src/upstash/index.ts"],"sourcesContent":["import { LoggerTransport } from '@mastra/core/logger';\nimport type { BaseLogMessage, LogLevel } from '@mastra/core/logger';\n\nexport class UpstashTransport extends LoggerTransport {\n upstashUrl: string;\n upstashToken: string;\n listName: string;\n maxListLength: number;\n batchSize: number;\n flushInterval: number;\n logBuffer: any[];\n lastFlush: number;\n flushIntervalId: NodeJS.Timeout;\n\n constructor(opts: {\n listName?: string;\n maxListLength?: number;\n batchSize?: number;\n upstashUrl: string;\n flushInterval?: number;\n upstashToken: string;\n }) {\n super({ objectMode: true });\n\n if (!opts.upstashUrl || !opts.upstashToken) {\n throw new Error('Upstash URL and token are required');\n }\n\n this.upstashUrl = opts.upstashUrl;\n this.upstashToken = opts.upstashToken;\n this.listName = opts.listName || 'application-logs';\n this.maxListLength = opts.maxListLength || 10000;\n this.batchSize = opts.batchSize || 100;\n this.flushInterval = opts.flushInterval || 10000;\n\n this.logBuffer = [];\n this.lastFlush = Date.now();\n\n // Start flush interval\n this.flushIntervalId = setInterval(() => {\n this._flush().catch(err => {\n console.error('Error flushing logs to Upstash:', err);\n });\n }, this.flushInterval);\n }\n\n private async executeUpstashCommands(commands: any[][]): Promise<any> {\n const response = await fetch(`${this.upstashUrl}/pipeline`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.upstashToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(commands),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to execute Upstash command: ${response.statusText}`);\n }\n\n return response.json();\n }\n\n async _flush() {\n if (this.logBuffer.length === 0) {\n return;\n }\n\n const now = Date.now();\n const logs = this.logBuffer.splice(0, this.batchSize);\n\n try {\n const commands: any[][] = [['LPUSH', this.listName, ...logs.map(log => JSON.stringify(log))]];\n\n // Trim the list if it exceeds maxListLength (must be a separate pipeline command)\n if (this.maxListLength > 0) {\n commands.push(['LTRIM', this.listName, 0, this.maxListLength - 1]);\n }\n\n await this.executeUpstashCommands(commands);\n this.lastFlush = now;\n } catch (error) {\n // On error, put logs back in the buffer\n this.logBuffer.unshift(...logs);\n throw error;\n }\n }\n\n _write(chunk: any, encoding?: string, callback?: (error?: Error | null) => void): boolean {\n if (typeof callback === 'function') {\n this._transform(chunk, encoding || 'utf8', callback);\n return true;\n }\n\n this._transform(chunk, encoding || 'utf8', (error: Error | null) => {\n if (error) console.error('Transform error in write:', error);\n });\n return true;\n }\n\n _transform(chunk: string, _enc: string, cb: Function) {\n try {\n // Parse the log line if it's a string\n const log = typeof chunk === 'string' ? JSON.parse(chunk) : chunk;\n\n // Add timestamp if not present\n if (!log.time) {\n log.time = Date.now();\n }\n\n // Add to buffer\n this.logBuffer.push(log);\n\n // Flush if buffer reaches batch size\n if (this.logBuffer.length >= this.batchSize) {\n this._flush().catch(err => {\n console.error('Error flushing logs to Upstash:', err);\n });\n }\n\n // Pass through the log\n cb(null, chunk);\n } catch (error) {\n cb(error);\n }\n }\n\n _destroy(err: Error, cb: Function) {\n clearInterval(this.flushIntervalId);\n\n // Final flush\n if (this.logBuffer.length > 0) {\n this.drainBuffer()\n .then(() => cb(err))\n .catch(flushErr => {\n console.error('Error in final flush:', flushErr);\n cb(err || flushErr);\n });\n } else {\n cb(err);\n }\n }\n\n private async drainBuffer(): Promise<void> {\n while (this.logBuffer.length > 0) {\n await this._flush();\n }\n }\n\n private parseLogs(logs: unknown): BaseLogMessage[] {\n if (!Array.isArray(logs)) return [];\n\n return logs.flatMap((log: string) => {\n try {\n const parsedLog = JSON.parse(log);\n return parsedLog !== null && typeof parsedLog === 'object' ? [parsedLog] : [];\n } catch {\n return [{} as BaseLogMessage];\n }\n });\n }\n\n private matchesLog(\n log: BaseLogMessage,\n {\n fromDate,\n toDate,\n logLevel,\n filters,\n runId,\n }: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n runId?: string;\n },\n ): boolean {\n if (runId !== undefined && log.runId !== runId) return false;\n if (logLevel && log.level !== logLevel) return false;\n const logTime = new Date(log.time).getTime();\n if (fromDate && !(logTime >= fromDate.getTime())) return false;\n if (toDate && !(logTime <= toDate.getTime())) return false;\n\n return !filters || Object.entries(filters).every(([key, value]) => log[key as keyof BaseLogMessage] === value);\n }\n\n async listLogs(params?: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n returnPaginationResults?: boolean; // default true\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n try {\n const {\n fromDate,\n toDate,\n logLevel,\n filters,\n returnPaginationResults: returnPaginationResultsInput,\n page: pageInput,\n perPage: perPageInput,\n } = params || {};\n\n const page = pageInput === 0 ? 1 : (pageInput ?? 1);\n const perPage = perPageInput || 100;\n const returnPaginationResults = returnPaginationResultsInput ?? true;\n const hasFilters = Boolean(fromDate || toDate || logLevel || (filters && Object.keys(filters).length > 0));\n\n if (returnPaginationResults && !hasFilters) {\n const start = (page - 1) * perPage;\n const end = start + perPage;\n const response = await this.executeUpstashCommands([\n ['LLEN', this.listName],\n ['LRANGE', this.listName, start, end - 1],\n ]);\n const total = Number(response?.[0]?.result) || 0;\n const logs = this.parseLogs(response?.[1]?.result);\n\n return {\n logs,\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n }\n\n const response = await this.executeUpstashCommands([['LRANGE', this.listName, 0, -1]]);\n const filteredLogs = this.parseLogs(response?.[0]?.result).filter(log =>\n this.matchesLog(log, { fromDate, toDate, logLevel, filters }),\n );\n\n if (!returnPaginationResults) {\n return {\n logs: filteredLogs,\n total: filteredLogs.length,\n page,\n perPage: filteredLogs.length,\n hasMore: false,\n };\n }\n\n const total = filteredLogs.length;\n const start = (page - 1) * perPage;\n const end = start + perPage;\n\n return {\n logs: filteredLogs.slice(start, end),\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n } catch (error) {\n console.error('Error getting logs from Upstash:', error);\n return {\n logs: [],\n total: 0,\n page: params?.page ?? 1,\n perPage: params?.perPage ?? 100,\n hasMore: false,\n };\n }\n }\n\n async listLogsByRunId({\n runId,\n fromDate,\n toDate,\n logLevel,\n filters,\n page: pageInput,\n perPage: perPageInput,\n }: {\n runId: string;\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n try {\n const page = pageInput === 0 ? 1 : (pageInput ?? 1);\n const perPage = perPageInput || 100;\n\n const allLogs = await this.listLogs({ fromDate, toDate, logLevel, filters, returnPaginationResults: false });\n const logs = allLogs.logs.filter(log => this.matchesLog(log, { runId }));\n const total = logs.length;\n const start = (page - 1) * perPage;\n const end = start + perPage;\n\n return {\n logs: logs.slice(start, end),\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n } catch (error) {\n console.error('Error getting logs by runId from Upstash:', error);\n return {\n logs: [],\n total: 0,\n page: pageInput ?? 1,\n perPage: perPageInput ?? 100,\n hasMore: false,\n };\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["LoggerTransport"],"sources":["../../src/upstash/index.ts"],"sourcesContent":["import { LoggerTransport } from '@mastra/core/logger';\nimport type { BaseLogMessage, LogLevel } from '@mastra/core/logger';\n\nexport class UpstashTransport extends LoggerTransport {\n upstashUrl: string;\n upstashToken: string;\n listName: string;\n maxListLength: number;\n maxBufferSize: number;\n /** Number of buffered records discarded because the buffer exceeded `maxBufferSize`. */\n droppedRecords = 0;\n batchSize: number;\n flushInterval: number;\n logBuffer: any[];\n lastFlush: number;\n flushIntervalId: NodeJS.Timeout;\n private flushPromise: Promise<void> | null = null;\n\n constructor(opts: {\n listName?: string;\n maxListLength?: number;\n /** Maximum number of records held in memory while Upstash is unreachable. Must be a positive integer. Defaults to `maxListLength`, or 10000 when `maxListLength` disables trimming. */\n maxBufferSize?: number;\n batchSize?: number;\n upstashUrl: string;\n flushInterval?: number;\n upstashToken: string;\n }) {\n super({ objectMode: true });\n\n if (!opts.upstashUrl || !opts.upstashToken) {\n throw new Error('Upstash URL and token are required');\n }\n\n this.upstashUrl = opts.upstashUrl;\n this.upstashToken = opts.upstashToken;\n this.listName = opts.listName || 'application-logs';\n this.maxListLength = opts.maxListLength || 10000;\n // A non-positive maxListLength disables LTRIM, so it cannot serve as the buffer limit.\n this.maxBufferSize = opts.maxBufferSize ?? (this.maxListLength > 0 ? this.maxListLength : 10000);\n if (!Number.isInteger(this.maxBufferSize) || this.maxBufferSize < 1) {\n throw new Error('maxBufferSize must be a positive integer');\n }\n this.batchSize = opts.batchSize || 100;\n this.flushInterval = opts.flushInterval || 10000;\n\n this.logBuffer = [];\n this.lastFlush = Date.now();\n\n // Start flush interval\n this.flushIntervalId = setInterval(() => {\n this._flush().catch(err => {\n console.error('Error flushing logs to Upstash:', err);\n });\n }, this.flushInterval);\n }\n\n private async executeUpstashCommands(commands: any[][]): Promise<any> {\n const response = await fetch(`${this.upstashUrl}/pipeline`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.upstashToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(commands),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to execute Upstash command: ${response.statusText}`);\n }\n\n return response.json();\n }\n\n /** Sends the next batch to Upstash. Callers share the in-flight flush instead of starting a new request. */\n _flush(): Promise<void> {\n if (this.flushPromise) {\n return this.flushPromise;\n }\n if (this.logBuffer.length === 0) {\n return Promise.resolve();\n }\n\n this.flushPromise = this.flushBatch().finally(() => {\n this.flushPromise = null;\n });\n return this.flushPromise;\n }\n\n /** Pushes one batch to Upstash, returning the records to the front of the buffer if the request fails. */\n private async flushBatch() {\n const now = Date.now();\n const logs = this.logBuffer.splice(0, this.batchSize);\n\n try {\n const commands: any[][] = [['LPUSH', this.listName, ...logs.map(log => JSON.stringify(log))]];\n\n // Trim the list if it exceeds maxListLength (must be a separate pipeline command)\n if (this.maxListLength > 0) {\n commands.push(['LTRIM', this.listName, 0, this.maxListLength - 1]);\n }\n\n await this.executeUpstashCommands(commands);\n this.lastFlush = now;\n } catch (error) {\n // On error, put logs back in the buffer\n this.logBuffer.unshift(...logs);\n this.enforceBufferLimit();\n throw error;\n }\n }\n\n /** Drops the oldest buffered records once the buffer exceeds `maxBufferSize`. */\n private enforceBufferLimit() {\n const overflow = this.logBuffer.length - this.maxBufferSize;\n if (overflow > 0) {\n this.logBuffer.splice(0, overflow);\n this.droppedRecords += overflow;\n }\n }\n\n _write(chunk: any, encoding?: string, callback?: (error?: Error | null) => void): boolean {\n if (typeof callback === 'function') {\n this._transform(chunk, encoding || 'utf8', callback);\n return true;\n }\n\n this._transform(chunk, encoding || 'utf8', (error: Error | null) => {\n if (error) console.error('Transform error in write:', error);\n });\n return true;\n }\n\n _transform(chunk: string, _enc: string, cb: Function) {\n try {\n // Parse the log line if it's a string\n const log = typeof chunk === 'string' ? JSON.parse(chunk) : chunk;\n\n // Add timestamp if not present\n if (!log.time) {\n log.time = Date.now();\n }\n\n // Add to buffer\n this.logBuffer.push(log);\n\n // Flush once a batch is ready, or earlier if the buffer limit is smaller than a batch\n if (this.logBuffer.length >= Math.min(this.batchSize, this.maxBufferSize)) {\n this._flush().catch(err => {\n console.error('Error flushing logs to Upstash:', err);\n });\n }\n\n this.enforceBufferLimit();\n\n // Pass through the log\n cb(null, chunk);\n } catch (error) {\n cb(error);\n }\n }\n\n _destroy(err: Error, cb: Function) {\n clearInterval(this.flushIntervalId);\n\n // Final flush\n if (this.logBuffer.length > 0 || this.flushPromise) {\n this.drainBuffer()\n .then(() => cb(err))\n .catch(flushErr => {\n console.error('Error in final flush:', flushErr);\n cb(err || flushErr);\n });\n } else {\n cb(err);\n }\n }\n\n // Wait out any in-flight request, ignoring its failure since its records are back in the buffer,\n // then keep sending until the buffer is empty. A failed request ends the drain instead of retrying forever.\n private async drainBuffer(): Promise<void> {\n await this.flushPromise?.catch(() => {});\n while (this.logBuffer.length > 0 || this.flushPromise) {\n await (this.flushPromise ?? this._flush());\n }\n }\n\n private parseLogs(logs: unknown): BaseLogMessage[] {\n if (!Array.isArray(logs)) return [];\n\n return logs.flatMap((log: string) => {\n try {\n const parsedLog = JSON.parse(log);\n return parsedLog !== null && typeof parsedLog === 'object' ? [parsedLog] : [];\n } catch {\n return [{} as BaseLogMessage];\n }\n });\n }\n\n private matchesLog(\n log: BaseLogMessage,\n {\n fromDate,\n toDate,\n logLevel,\n filters,\n runId,\n }: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n runId?: string;\n },\n ): boolean {\n if (runId !== undefined && log.runId !== runId) return false;\n if (logLevel && log.level !== logLevel) return false;\n const logTime = new Date(log.time).getTime();\n if (fromDate && !(logTime >= fromDate.getTime())) return false;\n if (toDate && !(logTime <= toDate.getTime())) return false;\n\n return !filters || Object.entries(filters).every(([key, value]) => log[key as keyof BaseLogMessage] === value);\n }\n\n async listLogs(params?: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n returnPaginationResults?: boolean; // default true\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n try {\n const {\n fromDate,\n toDate,\n logLevel,\n filters,\n returnPaginationResults: returnPaginationResultsInput,\n page: pageInput,\n perPage: perPageInput,\n } = params || {};\n\n const page = pageInput === 0 ? 1 : (pageInput ?? 1);\n const perPage = perPageInput || 100;\n const returnPaginationResults = returnPaginationResultsInput ?? true;\n const hasFilters = Boolean(fromDate || toDate || logLevel || (filters && Object.keys(filters).length > 0));\n\n if (returnPaginationResults && !hasFilters) {\n const start = (page - 1) * perPage;\n const end = start + perPage;\n const response = await this.executeUpstashCommands([\n ['LLEN', this.listName],\n ['LRANGE', this.listName, start, end - 1],\n ]);\n const total = Number(response?.[0]?.result) || 0;\n const logs = this.parseLogs(response?.[1]?.result);\n\n return {\n logs,\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n }\n\n const response = await this.executeUpstashCommands([['LRANGE', this.listName, 0, -1]]);\n const filteredLogs = this.parseLogs(response?.[0]?.result).filter(log =>\n this.matchesLog(log, { fromDate, toDate, logLevel, filters }),\n );\n\n if (!returnPaginationResults) {\n return {\n logs: filteredLogs,\n total: filteredLogs.length,\n page,\n perPage: filteredLogs.length,\n hasMore: false,\n };\n }\n\n const total = filteredLogs.length;\n const start = (page - 1) * perPage;\n const end = start + perPage;\n\n return {\n logs: filteredLogs.slice(start, end),\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n } catch (error) {\n console.error('Error getting logs from Upstash:', error);\n return {\n logs: [],\n total: 0,\n page: params?.page ?? 1,\n perPage: params?.perPage ?? 100,\n hasMore: false,\n };\n }\n }\n\n async listLogsByRunId({\n runId,\n fromDate,\n toDate,\n logLevel,\n filters,\n page: pageInput,\n perPage: perPageInput,\n }: {\n runId: string;\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n try {\n const page = pageInput === 0 ? 1 : (pageInput ?? 1);\n const perPage = perPageInput || 100;\n\n const allLogs = await this.listLogs({ fromDate, toDate, logLevel, filters, returnPaginationResults: false });\n const logs = allLogs.logs.filter(log => this.matchesLog(log, { runId }));\n const total = logs.length;\n const start = (page - 1) * perPage;\n const end = start + perPage;\n\n return {\n logs: logs.slice(start, end),\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n } catch (error) {\n console.error('Error getting logs by runId from Upstash:', error);\n return {\n logs: [],\n total: 0,\n page: pageInput ?? 1,\n perPage: perPageInput ?? 100,\n hasMore: false,\n };\n }\n }\n}\n"],"mappings":"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"}
|
package/dist/upstash/index.d.ts
CHANGED
|
@@ -5,21 +5,32 @@ export declare class UpstashTransport extends LoggerTransport {
|
|
|
5
5
|
upstashToken: string;
|
|
6
6
|
listName: string;
|
|
7
7
|
maxListLength: number;
|
|
8
|
+
maxBufferSize: number;
|
|
9
|
+
/** Number of buffered records discarded because the buffer exceeded `maxBufferSize`. */
|
|
10
|
+
droppedRecords: number;
|
|
8
11
|
batchSize: number;
|
|
9
12
|
flushInterval: number;
|
|
10
13
|
logBuffer: any[];
|
|
11
14
|
lastFlush: number;
|
|
12
15
|
flushIntervalId: NodeJS.Timeout;
|
|
16
|
+
private flushPromise;
|
|
13
17
|
constructor(opts: {
|
|
14
18
|
listName?: string;
|
|
15
19
|
maxListLength?: number;
|
|
20
|
+
/** Maximum number of records held in memory while Upstash is unreachable. Must be a positive integer. Defaults to `maxListLength`, or 10000 when `maxListLength` disables trimming. */
|
|
21
|
+
maxBufferSize?: number;
|
|
16
22
|
batchSize?: number;
|
|
17
23
|
upstashUrl: string;
|
|
18
24
|
flushInterval?: number;
|
|
19
25
|
upstashToken: string;
|
|
20
26
|
});
|
|
21
27
|
private executeUpstashCommands;
|
|
28
|
+
/** Sends the next batch to Upstash. Callers share the in-flight flush instead of starting a new request. */
|
|
22
29
|
_flush(): Promise<void>;
|
|
30
|
+
/** Pushes one batch to Upstash, returning the records to the front of the buffer if the request fails. */
|
|
31
|
+
private flushBatch;
|
|
32
|
+
/** Drops the oldest buffered records once the buffer exceeds `maxBufferSize`. */
|
|
33
|
+
private enforceBufferLimit;
|
|
23
34
|
_write(chunk: any, encoding?: string, callback?: (error?: Error | null) => void): boolean;
|
|
24
35
|
_transform(chunk: string, _enc: string, cb: Function): void;
|
|
25
36
|
_destroy(err: Error, cb: Function): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/upstash/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpE,qBAAa,gBAAiB,SAAQ,eAAe;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,GAAG,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/upstash/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpE,qBAAa,gBAAiB,SAAQ,eAAe;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,wFAAwF;IACxF,cAAc,SAAK;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,GAAG,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC,OAAO,CAAC;IAChC,OAAO,CAAC,YAAY,CAA8B;IAElD,YAAY,IAAI,EAAE;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,uLAAuL;QACvL,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;KACtB,EA4BA;YAEa,sBAAsB;IAiBpC,4GAA4G;IAC5G,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAYtB;IAED,0GAA0G;YAC5F,UAAU;IAsBxB,iFAAiF;IACjF,OAAO,CAAC,kBAAkB;IAQ1B,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,GAAG,OAAO,CAUxF;IAED,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,QA2BnD;IAED,QAAQ,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,QAchC;YAIa,WAAW;IAOzB,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,UAAU;IAyBZ,QAAQ,CAAC,MAAM,CAAC,EAAE;QACtB,QAAQ,CAAC,EAAE,IAAI,CAAC;QAChB,MAAM,CAAC,EAAE,IAAI,CAAC;QACd,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC9B,uBAAuB,CAAC,EAAE,OAAO,CAAC;QAClC,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC;QACV,IAAI,EAAE,cAAc,EAAE,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC,CAwED;IAEK,eAAe,CAAC,EACpB,KAAK,EACL,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,OAAO,EACP,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,YAAY,GACtB,EAAE;QACD,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,IAAI,CAAC;QAChB,MAAM,CAAC,EAAE,IAAI,CAAC;QACd,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC;QACV,IAAI,EAAE,cAAc,EAAE,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC,CA4BD;CACF"}
|
package/dist/upstash/index.js
CHANGED
|
@@ -5,11 +5,15 @@ var UpstashTransport = class extends LoggerTransport {
|
|
|
5
5
|
upstashToken;
|
|
6
6
|
listName;
|
|
7
7
|
maxListLength;
|
|
8
|
+
maxBufferSize;
|
|
9
|
+
/** Number of buffered records discarded because the buffer exceeded `maxBufferSize`. */
|
|
10
|
+
droppedRecords = 0;
|
|
8
11
|
batchSize;
|
|
9
12
|
flushInterval;
|
|
10
13
|
logBuffer;
|
|
11
14
|
lastFlush;
|
|
12
15
|
flushIntervalId;
|
|
16
|
+
flushPromise = null;
|
|
13
17
|
constructor(opts) {
|
|
14
18
|
super({ objectMode: true });
|
|
15
19
|
if (!opts.upstashUrl || !opts.upstashToken) throw new Error("Upstash URL and token are required");
|
|
@@ -17,6 +21,8 @@ var UpstashTransport = class extends LoggerTransport {
|
|
|
17
21
|
this.upstashToken = opts.upstashToken;
|
|
18
22
|
this.listName = opts.listName || "application-logs";
|
|
19
23
|
this.maxListLength = opts.maxListLength || 1e4;
|
|
24
|
+
this.maxBufferSize = opts.maxBufferSize ?? (this.maxListLength > 0 ? this.maxListLength : 1e4);
|
|
25
|
+
if (!Number.isInteger(this.maxBufferSize) || this.maxBufferSize < 1) throw new Error("maxBufferSize must be a positive integer");
|
|
20
26
|
this.batchSize = opts.batchSize || 100;
|
|
21
27
|
this.flushInterval = opts.flushInterval || 1e4;
|
|
22
28
|
this.logBuffer = [];
|
|
@@ -39,8 +45,17 @@ var UpstashTransport = class extends LoggerTransport {
|
|
|
39
45
|
if (!response.ok) throw new Error(`Failed to execute Upstash command: ${response.statusText}`);
|
|
40
46
|
return response.json();
|
|
41
47
|
}
|
|
42
|
-
|
|
43
|
-
|
|
48
|
+
/** Sends the next batch to Upstash. Callers share the in-flight flush instead of starting a new request. */
|
|
49
|
+
_flush() {
|
|
50
|
+
if (this.flushPromise) return this.flushPromise;
|
|
51
|
+
if (this.logBuffer.length === 0) return Promise.resolve();
|
|
52
|
+
this.flushPromise = this.flushBatch().finally(() => {
|
|
53
|
+
this.flushPromise = null;
|
|
54
|
+
});
|
|
55
|
+
return this.flushPromise;
|
|
56
|
+
}
|
|
57
|
+
/** Pushes one batch to Upstash, returning the records to the front of the buffer if the request fails. */
|
|
58
|
+
async flushBatch() {
|
|
44
59
|
const now = Date.now();
|
|
45
60
|
const logs = this.logBuffer.splice(0, this.batchSize);
|
|
46
61
|
try {
|
|
@@ -59,9 +74,18 @@ var UpstashTransport = class extends LoggerTransport {
|
|
|
59
74
|
this.lastFlush = now;
|
|
60
75
|
} catch (error) {
|
|
61
76
|
this.logBuffer.unshift(...logs);
|
|
77
|
+
this.enforceBufferLimit();
|
|
62
78
|
throw error;
|
|
63
79
|
}
|
|
64
80
|
}
|
|
81
|
+
/** Drops the oldest buffered records once the buffer exceeds `maxBufferSize`. */
|
|
82
|
+
enforceBufferLimit() {
|
|
83
|
+
const overflow = this.logBuffer.length - this.maxBufferSize;
|
|
84
|
+
if (overflow > 0) {
|
|
85
|
+
this.logBuffer.splice(0, overflow);
|
|
86
|
+
this.droppedRecords += overflow;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
65
89
|
_write(chunk, encoding, callback) {
|
|
66
90
|
if (typeof callback === "function") {
|
|
67
91
|
this._transform(chunk, encoding || "utf8", callback);
|
|
@@ -77,9 +101,10 @@ var UpstashTransport = class extends LoggerTransport {
|
|
|
77
101
|
const log = typeof chunk === "string" ? JSON.parse(chunk) : chunk;
|
|
78
102
|
if (!log.time) log.time = Date.now();
|
|
79
103
|
this.logBuffer.push(log);
|
|
80
|
-
if (this.logBuffer.length >= this.batchSize) this._flush().catch((err) => {
|
|
104
|
+
if (this.logBuffer.length >= Math.min(this.batchSize, this.maxBufferSize)) this._flush().catch((err) => {
|
|
81
105
|
console.error("Error flushing logs to Upstash:", err);
|
|
82
106
|
});
|
|
107
|
+
this.enforceBufferLimit();
|
|
83
108
|
cb(null, chunk);
|
|
84
109
|
} catch (error) {
|
|
85
110
|
cb(error);
|
|
@@ -87,14 +112,15 @@ var UpstashTransport = class extends LoggerTransport {
|
|
|
87
112
|
}
|
|
88
113
|
_destroy(err, cb) {
|
|
89
114
|
clearInterval(this.flushIntervalId);
|
|
90
|
-
if (this.logBuffer.length > 0) this.drainBuffer().then(() => cb(err)).catch((flushErr) => {
|
|
115
|
+
if (this.logBuffer.length > 0 || this.flushPromise) this.drainBuffer().then(() => cb(err)).catch((flushErr) => {
|
|
91
116
|
console.error("Error in final flush:", flushErr);
|
|
92
117
|
cb(err || flushErr);
|
|
93
118
|
});
|
|
94
119
|
else cb(err);
|
|
95
120
|
}
|
|
96
121
|
async drainBuffer() {
|
|
97
|
-
|
|
122
|
+
await this.flushPromise?.catch(() => {});
|
|
123
|
+
while (this.logBuffer.length > 0 || this.flushPromise) await (this.flushPromise ?? this._flush());
|
|
98
124
|
}
|
|
99
125
|
parseLogs(logs) {
|
|
100
126
|
if (!Array.isArray(logs)) return [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/upstash/index.ts"],"sourcesContent":["import { LoggerTransport } from '@mastra/core/logger';\nimport type { BaseLogMessage, LogLevel } from '@mastra/core/logger';\n\nexport class UpstashTransport extends LoggerTransport {\n upstashUrl: string;\n upstashToken: string;\n listName: string;\n maxListLength: number;\n batchSize: number;\n flushInterval: number;\n logBuffer: any[];\n lastFlush: number;\n flushIntervalId: NodeJS.Timeout;\n\n constructor(opts: {\n listName?: string;\n maxListLength?: number;\n batchSize?: number;\n upstashUrl: string;\n flushInterval?: number;\n upstashToken: string;\n }) {\n super({ objectMode: true });\n\n if (!opts.upstashUrl || !opts.upstashToken) {\n throw new Error('Upstash URL and token are required');\n }\n\n this.upstashUrl = opts.upstashUrl;\n this.upstashToken = opts.upstashToken;\n this.listName = opts.listName || 'application-logs';\n this.maxListLength = opts.maxListLength || 10000;\n this.batchSize = opts.batchSize || 100;\n this.flushInterval = opts.flushInterval || 10000;\n\n this.logBuffer = [];\n this.lastFlush = Date.now();\n\n // Start flush interval\n this.flushIntervalId = setInterval(() => {\n this._flush().catch(err => {\n console.error('Error flushing logs to Upstash:', err);\n });\n }, this.flushInterval);\n }\n\n private async executeUpstashCommands(commands: any[][]): Promise<any> {\n const response = await fetch(`${this.upstashUrl}/pipeline`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.upstashToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(commands),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to execute Upstash command: ${response.statusText}`);\n }\n\n return response.json();\n }\n\n async _flush() {\n if (this.logBuffer.length === 0) {\n return;\n }\n\n const now = Date.now();\n const logs = this.logBuffer.splice(0, this.batchSize);\n\n try {\n const commands: any[][] = [['LPUSH', this.listName, ...logs.map(log => JSON.stringify(log))]];\n\n // Trim the list if it exceeds maxListLength (must be a separate pipeline command)\n if (this.maxListLength > 0) {\n commands.push(['LTRIM', this.listName, 0, this.maxListLength - 1]);\n }\n\n await this.executeUpstashCommands(commands);\n this.lastFlush = now;\n } catch (error) {\n // On error, put logs back in the buffer\n this.logBuffer.unshift(...logs);\n throw error;\n }\n }\n\n _write(chunk: any, encoding?: string, callback?: (error?: Error | null) => void): boolean {\n if (typeof callback === 'function') {\n this._transform(chunk, encoding || 'utf8', callback);\n return true;\n }\n\n this._transform(chunk, encoding || 'utf8', (error: Error | null) => {\n if (error) console.error('Transform error in write:', error);\n });\n return true;\n }\n\n _transform(chunk: string, _enc: string, cb: Function) {\n try {\n // Parse the log line if it's a string\n const log = typeof chunk === 'string' ? JSON.parse(chunk) : chunk;\n\n // Add timestamp if not present\n if (!log.time) {\n log.time = Date.now();\n }\n\n // Add to buffer\n this.logBuffer.push(log);\n\n // Flush if buffer reaches batch size\n if (this.logBuffer.length >= this.batchSize) {\n this._flush().catch(err => {\n console.error('Error flushing logs to Upstash:', err);\n });\n }\n\n // Pass through the log\n cb(null, chunk);\n } catch (error) {\n cb(error);\n }\n }\n\n _destroy(err: Error, cb: Function) {\n clearInterval(this.flushIntervalId);\n\n // Final flush\n if (this.logBuffer.length > 0) {\n this.drainBuffer()\n .then(() => cb(err))\n .catch(flushErr => {\n console.error('Error in final flush:', flushErr);\n cb(err || flushErr);\n });\n } else {\n cb(err);\n }\n }\n\n private async drainBuffer(): Promise<void> {\n while (this.logBuffer.length > 0) {\n await this._flush();\n }\n }\n\n private parseLogs(logs: unknown): BaseLogMessage[] {\n if (!Array.isArray(logs)) return [];\n\n return logs.flatMap((log: string) => {\n try {\n const parsedLog = JSON.parse(log);\n return parsedLog !== null && typeof parsedLog === 'object' ? [parsedLog] : [];\n } catch {\n return [{} as BaseLogMessage];\n }\n });\n }\n\n private matchesLog(\n log: BaseLogMessage,\n {\n fromDate,\n toDate,\n logLevel,\n filters,\n runId,\n }: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n runId?: string;\n },\n ): boolean {\n if (runId !== undefined && log.runId !== runId) return false;\n if (logLevel && log.level !== logLevel) return false;\n const logTime = new Date(log.time).getTime();\n if (fromDate && !(logTime >= fromDate.getTime())) return false;\n if (toDate && !(logTime <= toDate.getTime())) return false;\n\n return !filters || Object.entries(filters).every(([key, value]) => log[key as keyof BaseLogMessage] === value);\n }\n\n async listLogs(params?: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n returnPaginationResults?: boolean; // default true\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n try {\n const {\n fromDate,\n toDate,\n logLevel,\n filters,\n returnPaginationResults: returnPaginationResultsInput,\n page: pageInput,\n perPage: perPageInput,\n } = params || {};\n\n const page = pageInput === 0 ? 1 : (pageInput ?? 1);\n const perPage = perPageInput || 100;\n const returnPaginationResults = returnPaginationResultsInput ?? true;\n const hasFilters = Boolean(fromDate || toDate || logLevel || (filters && Object.keys(filters).length > 0));\n\n if (returnPaginationResults && !hasFilters) {\n const start = (page - 1) * perPage;\n const end = start + perPage;\n const response = await this.executeUpstashCommands([\n ['LLEN', this.listName],\n ['LRANGE', this.listName, start, end - 1],\n ]);\n const total = Number(response?.[0]?.result) || 0;\n const logs = this.parseLogs(response?.[1]?.result);\n\n return {\n logs,\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n }\n\n const response = await this.executeUpstashCommands([['LRANGE', this.listName, 0, -1]]);\n const filteredLogs = this.parseLogs(response?.[0]?.result).filter(log =>\n this.matchesLog(log, { fromDate, toDate, logLevel, filters }),\n );\n\n if (!returnPaginationResults) {\n return {\n logs: filteredLogs,\n total: filteredLogs.length,\n page,\n perPage: filteredLogs.length,\n hasMore: false,\n };\n }\n\n const total = filteredLogs.length;\n const start = (page - 1) * perPage;\n const end = start + perPage;\n\n return {\n logs: filteredLogs.slice(start, end),\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n } catch (error) {\n console.error('Error getting logs from Upstash:', error);\n return {\n logs: [],\n total: 0,\n page: params?.page ?? 1,\n perPage: params?.perPage ?? 100,\n hasMore: false,\n };\n }\n }\n\n async listLogsByRunId({\n runId,\n fromDate,\n toDate,\n logLevel,\n filters,\n page: pageInput,\n perPage: perPageInput,\n }: {\n runId: string;\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n try {\n const page = pageInput === 0 ? 1 : (pageInput ?? 1);\n const perPage = perPageInput || 100;\n\n const allLogs = await this.listLogs({ fromDate, toDate, logLevel, filters, returnPaginationResults: false });\n const logs = allLogs.logs.filter(log => this.matchesLog(log, { runId }));\n const total = logs.length;\n const start = (page - 1) * perPage;\n const end = start + perPage;\n\n return {\n logs: logs.slice(start, end),\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n } catch (error) {\n console.error('Error getting logs by runId from Upstash:', error);\n return {\n logs: [],\n total: 0,\n page: pageInput ?? 1,\n perPage: perPageInput ?? 100,\n hasMore: false,\n };\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/upstash/index.ts"],"sourcesContent":["import { LoggerTransport } from '@mastra/core/logger';\nimport type { BaseLogMessage, LogLevel } from '@mastra/core/logger';\n\nexport class UpstashTransport extends LoggerTransport {\n upstashUrl: string;\n upstashToken: string;\n listName: string;\n maxListLength: number;\n maxBufferSize: number;\n /** Number of buffered records discarded because the buffer exceeded `maxBufferSize`. */\n droppedRecords = 0;\n batchSize: number;\n flushInterval: number;\n logBuffer: any[];\n lastFlush: number;\n flushIntervalId: NodeJS.Timeout;\n private flushPromise: Promise<void> | null = null;\n\n constructor(opts: {\n listName?: string;\n maxListLength?: number;\n /** Maximum number of records held in memory while Upstash is unreachable. Must be a positive integer. Defaults to `maxListLength`, or 10000 when `maxListLength` disables trimming. */\n maxBufferSize?: number;\n batchSize?: number;\n upstashUrl: string;\n flushInterval?: number;\n upstashToken: string;\n }) {\n super({ objectMode: true });\n\n if (!opts.upstashUrl || !opts.upstashToken) {\n throw new Error('Upstash URL and token are required');\n }\n\n this.upstashUrl = opts.upstashUrl;\n this.upstashToken = opts.upstashToken;\n this.listName = opts.listName || 'application-logs';\n this.maxListLength = opts.maxListLength || 10000;\n // A non-positive maxListLength disables LTRIM, so it cannot serve as the buffer limit.\n this.maxBufferSize = opts.maxBufferSize ?? (this.maxListLength > 0 ? this.maxListLength : 10000);\n if (!Number.isInteger(this.maxBufferSize) || this.maxBufferSize < 1) {\n throw new Error('maxBufferSize must be a positive integer');\n }\n this.batchSize = opts.batchSize || 100;\n this.flushInterval = opts.flushInterval || 10000;\n\n this.logBuffer = [];\n this.lastFlush = Date.now();\n\n // Start flush interval\n this.flushIntervalId = setInterval(() => {\n this._flush().catch(err => {\n console.error('Error flushing logs to Upstash:', err);\n });\n }, this.flushInterval);\n }\n\n private async executeUpstashCommands(commands: any[][]): Promise<any> {\n const response = await fetch(`${this.upstashUrl}/pipeline`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.upstashToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(commands),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to execute Upstash command: ${response.statusText}`);\n }\n\n return response.json();\n }\n\n /** Sends the next batch to Upstash. Callers share the in-flight flush instead of starting a new request. */\n _flush(): Promise<void> {\n if (this.flushPromise) {\n return this.flushPromise;\n }\n if (this.logBuffer.length === 0) {\n return Promise.resolve();\n }\n\n this.flushPromise = this.flushBatch().finally(() => {\n this.flushPromise = null;\n });\n return this.flushPromise;\n }\n\n /** Pushes one batch to Upstash, returning the records to the front of the buffer if the request fails. */\n private async flushBatch() {\n const now = Date.now();\n const logs = this.logBuffer.splice(0, this.batchSize);\n\n try {\n const commands: any[][] = [['LPUSH', this.listName, ...logs.map(log => JSON.stringify(log))]];\n\n // Trim the list if it exceeds maxListLength (must be a separate pipeline command)\n if (this.maxListLength > 0) {\n commands.push(['LTRIM', this.listName, 0, this.maxListLength - 1]);\n }\n\n await this.executeUpstashCommands(commands);\n this.lastFlush = now;\n } catch (error) {\n // On error, put logs back in the buffer\n this.logBuffer.unshift(...logs);\n this.enforceBufferLimit();\n throw error;\n }\n }\n\n /** Drops the oldest buffered records once the buffer exceeds `maxBufferSize`. */\n private enforceBufferLimit() {\n const overflow = this.logBuffer.length - this.maxBufferSize;\n if (overflow > 0) {\n this.logBuffer.splice(0, overflow);\n this.droppedRecords += overflow;\n }\n }\n\n _write(chunk: any, encoding?: string, callback?: (error?: Error | null) => void): boolean {\n if (typeof callback === 'function') {\n this._transform(chunk, encoding || 'utf8', callback);\n return true;\n }\n\n this._transform(chunk, encoding || 'utf8', (error: Error | null) => {\n if (error) console.error('Transform error in write:', error);\n });\n return true;\n }\n\n _transform(chunk: string, _enc: string, cb: Function) {\n try {\n // Parse the log line if it's a string\n const log = typeof chunk === 'string' ? JSON.parse(chunk) : chunk;\n\n // Add timestamp if not present\n if (!log.time) {\n log.time = Date.now();\n }\n\n // Add to buffer\n this.logBuffer.push(log);\n\n // Flush once a batch is ready, or earlier if the buffer limit is smaller than a batch\n if (this.logBuffer.length >= Math.min(this.batchSize, this.maxBufferSize)) {\n this._flush().catch(err => {\n console.error('Error flushing logs to Upstash:', err);\n });\n }\n\n this.enforceBufferLimit();\n\n // Pass through the log\n cb(null, chunk);\n } catch (error) {\n cb(error);\n }\n }\n\n _destroy(err: Error, cb: Function) {\n clearInterval(this.flushIntervalId);\n\n // Final flush\n if (this.logBuffer.length > 0 || this.flushPromise) {\n this.drainBuffer()\n .then(() => cb(err))\n .catch(flushErr => {\n console.error('Error in final flush:', flushErr);\n cb(err || flushErr);\n });\n } else {\n cb(err);\n }\n }\n\n // Wait out any in-flight request, ignoring its failure since its records are back in the buffer,\n // then keep sending until the buffer is empty. A failed request ends the drain instead of retrying forever.\n private async drainBuffer(): Promise<void> {\n await this.flushPromise?.catch(() => {});\n while (this.logBuffer.length > 0 || this.flushPromise) {\n await (this.flushPromise ?? this._flush());\n }\n }\n\n private parseLogs(logs: unknown): BaseLogMessage[] {\n if (!Array.isArray(logs)) return [];\n\n return logs.flatMap((log: string) => {\n try {\n const parsedLog = JSON.parse(log);\n return parsedLog !== null && typeof parsedLog === 'object' ? [parsedLog] : [];\n } catch {\n return [{} as BaseLogMessage];\n }\n });\n }\n\n private matchesLog(\n log: BaseLogMessage,\n {\n fromDate,\n toDate,\n logLevel,\n filters,\n runId,\n }: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n runId?: string;\n },\n ): boolean {\n if (runId !== undefined && log.runId !== runId) return false;\n if (logLevel && log.level !== logLevel) return false;\n const logTime = new Date(log.time).getTime();\n if (fromDate && !(logTime >= fromDate.getTime())) return false;\n if (toDate && !(logTime <= toDate.getTime())) return false;\n\n return !filters || Object.entries(filters).every(([key, value]) => log[key as keyof BaseLogMessage] === value);\n }\n\n async listLogs(params?: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n returnPaginationResults?: boolean; // default true\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n try {\n const {\n fromDate,\n toDate,\n logLevel,\n filters,\n returnPaginationResults: returnPaginationResultsInput,\n page: pageInput,\n perPage: perPageInput,\n } = params || {};\n\n const page = pageInput === 0 ? 1 : (pageInput ?? 1);\n const perPage = perPageInput || 100;\n const returnPaginationResults = returnPaginationResultsInput ?? true;\n const hasFilters = Boolean(fromDate || toDate || logLevel || (filters && Object.keys(filters).length > 0));\n\n if (returnPaginationResults && !hasFilters) {\n const start = (page - 1) * perPage;\n const end = start + perPage;\n const response = await this.executeUpstashCommands([\n ['LLEN', this.listName],\n ['LRANGE', this.listName, start, end - 1],\n ]);\n const total = Number(response?.[0]?.result) || 0;\n const logs = this.parseLogs(response?.[1]?.result);\n\n return {\n logs,\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n }\n\n const response = await this.executeUpstashCommands([['LRANGE', this.listName, 0, -1]]);\n const filteredLogs = this.parseLogs(response?.[0]?.result).filter(log =>\n this.matchesLog(log, { fromDate, toDate, logLevel, filters }),\n );\n\n if (!returnPaginationResults) {\n return {\n logs: filteredLogs,\n total: filteredLogs.length,\n page,\n perPage: filteredLogs.length,\n hasMore: false,\n };\n }\n\n const total = filteredLogs.length;\n const start = (page - 1) * perPage;\n const end = start + perPage;\n\n return {\n logs: filteredLogs.slice(start, end),\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n } catch (error) {\n console.error('Error getting logs from Upstash:', error);\n return {\n logs: [],\n total: 0,\n page: params?.page ?? 1,\n perPage: params?.perPage ?? 100,\n hasMore: false,\n };\n }\n }\n\n async listLogsByRunId({\n runId,\n fromDate,\n toDate,\n logLevel,\n filters,\n page: pageInput,\n perPage: perPageInput,\n }: {\n runId: string;\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n try {\n const page = pageInput === 0 ? 1 : (pageInput ?? 1);\n const perPage = perPageInput || 100;\n\n const allLogs = await this.listLogs({ fromDate, toDate, logLevel, filters, returnPaginationResults: false });\n const logs = allLogs.logs.filter(log => this.matchesLog(log, { runId }));\n const total = logs.length;\n const start = (page - 1) * perPage;\n const end = start + perPage;\n\n return {\n logs: logs.slice(start, end),\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n } catch (error) {\n console.error('Error getting logs by runId from Upstash:', error);\n return {\n logs: [],\n total: 0,\n page: pageInput ?? 1,\n perPage: perPageInput ?? 100,\n hasMore: false,\n };\n }\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/loggers",
|
|
3
|
-
"version": "1.3.6-alpha.
|
|
3
|
+
"version": "1.3.6-alpha.4",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"vitest": "4.1.11",
|
|
79
79
|
"@internal/lint": "0.0.141",
|
|
80
80
|
"@internal/types-builder": "0.0.116",
|
|
81
|
-
"@mastra/core": "1.76.0-alpha.
|
|
81
|
+
"@mastra/core": "1.76.0-alpha.8"
|
|
82
82
|
},
|
|
83
83
|
"peerDependencies": {
|
|
84
84
|
"@mastra/core": ">=1.0.0-0 <2.0.0-0"
|