(
runId: string,
organizationId?: string | null,
lastCursor?: string | null,
)
| 119 | } |
| 120 | |
| 121 | async fetchRecentLogs( |
| 122 | runId: string, |
| 123 | organizationId?: string | null, |
| 124 | lastCursor?: string | null, |
| 125 | ): Promise<{ |
| 126 | logs: { |
| 127 | id: string; |
| 128 | runId: string; |
| 129 | nodeId: string; |
| 130 | level: string; |
| 131 | message: string; |
| 132 | timestamp: string; |
| 133 | sequence: number; |
| 134 | }[]; |
| 135 | cursor: string | null; |
| 136 | }> { |
| 137 | const selector = this.buildSelector({ run_id: runId }); |
| 138 | const startTime = |
| 139 | lastCursor ?? |
| 140 | (await this.resolveEarliestTimestamp(runId, organizationId))?.toISOString() ?? |
| 141 | new Date(Date.now() - this.defaultTailWindowMs).toISOString(); |
| 142 | const endTime = new Date().toISOString(); |
| 143 | |
| 144 | const entries = await this.queryLokiTimeRange(selector, startTime, endTime, 500); |
| 145 | const filtered = entries.filter((entry) => { |
| 146 | if (!lastCursor) { |
| 147 | return true; |
| 148 | } |
| 149 | const ts = Date.parse(entry.timestamp); |
| 150 | const lastTs = Date.parse(lastCursor); |
| 151 | if (Number.isNaN(ts) || Number.isNaN(lastTs)) { |
| 152 | return true; |
| 153 | } |
| 154 | return ts > lastTs; |
| 155 | }); |
| 156 | |
| 157 | if (filtered.length === 0) { |
| 158 | return { logs: [], cursor: lastCursor ?? startTime ?? null }; |
| 159 | } |
| 160 | |
| 161 | const logs = filtered.map((entry, index) => { |
| 162 | const timestampValue = Date.parse(entry.timestamp); |
| 163 | const sequence = |
| 164 | Number.isNaN(timestampValue) || timestampValue < 0 ? Date.now() + index : timestampValue; |
| 165 | return { |
| 166 | id: `${runId}-${sequence}-${index}`, |
| 167 | runId, |
| 168 | nodeId: entry.nodeId || 'unknown', |
| 169 | level: entry.level || 'info', |
| 170 | message: entry.message, |
| 171 | timestamp: entry.timestamp, |
| 172 | sequence, |
| 173 | }; |
| 174 | }); |
| 175 | |
| 176 | const nextCursor = logs[logs.length - 1]?.timestamp ?? lastCursor ?? startTime ?? null; |
| 177 | return { |
| 178 | logs, |
no test coverage detected