MCPcopy Create free account
hub / github.com/ShipSecAI/studio / fetch

Method fetch

backend/src/trace/log-stream.service.ts:39–119  ·  view source on GitHub ↗
(runId: string, auth: AuthContext | null, options: FetchLogsOptions = {})

Source from the content-addressed store, hash-verified

37 }
38
39 async fetch(runId: string, auth: AuthContext | null, options: FetchLogsOptions = {}) {
40 if (!this.baseUrl) {
41 console.warn(`[LogStreamService] Loki not configured (LOKI_URL not set) for runId: ${runId}`);
42 throw new ServiceUnavailableException('Loki integration is not configured');
43 }
44
45 const organizationId = this.requireOrganizationId(auth);
46 const limit = options.limit && options.limit > 0 ? Math.min(options.limit, 2000) : 500;
47 const streams = await this.repository.listByRunId(
48 runId,
49 organizationId,
50 options.nodeRef,
51 options.stream as 'stdout' | 'stderr' | 'console' | undefined,
52 );
53
54 let startTime = options.startTime;
55 let endTime = options.endTime;
56
57 if ((!startTime || !endTime) && streams.length > 0) {
58 const earliest = streams.reduce<Date | null>((acc, stream) => {
59 if (!acc || stream.firstTimestamp < acc) {
60 return stream.firstTimestamp;
61 }
62 return acc;
63 }, null);
64
65 const latest = streams.reduce<Date | null>((acc, stream) => {
66 if (!acc || stream.lastTimestamp > acc) {
67 return stream.lastTimestamp;
68 }
69 return acc;
70 }, null);
71
72 if (!startTime && earliest) {
73 startTime = earliest.toISOString();
74 }
75 if (!endTime && latest) {
76 endTime = latest.toISOString();
77 }
78 }
79
80 // Build Loki query selector
81 const selectorLabels: Record<string, string> = { run_id: runId };
82 if (options.nodeRef) selectorLabels.node = options.nodeRef;
83 if (options.stream) selectorLabels.stream = options.stream;
84 if (options.level) selectorLabels.level = options.level;
85
86 const selector = this.buildSelector(selectorLabels);
87 console.log(
88 `[LogStreamService] Fetching logs for runId: ${runId}, selector: ${selector}, limit: ${limit}`,
89 );
90
91 // Query Loki - use time range if provided (for timeline scrubbing), otherwise use pagination
92 const entries =
93 startTime && endTime
94 ? await this.queryLokiTimeRange(selector, startTime, endTime, limit)
95 : await this.queryLokiRange(selector, limit, options.cursor);
96

Callers 13

logsMethod · 0.80
executeFunction · 0.80
executeFunction · 0.80
executeFunction · 0.80
executeFunction · 0.80
createTestContextFunction · 0.80
createTestContextFunction · 0.80
executeFunction · 0.80
executeFunction · 0.80

Calls 6

requireOrganizationIdMethod · 0.95
buildSelectorMethod · 0.95
queryLokiTimeRangeMethod · 0.95
queryLokiRangeMethod · 0.95
warnMethod · 0.80
listByRunIdMethod · 0.45

Tested by 2

createTestContextFunction · 0.64
createTestContextFunction · 0.64