15
15
*/
16
16
17
17
import {
18
+ SpanData ,
18
19
TraceDataSchema ,
19
20
type TraceData ,
20
21
type TraceQueryFilter ,
@@ -29,6 +30,7 @@ import { version as currentVersion } from './utils/version';
29
30
30
31
const MAX_TRACES = 1000 ;
31
32
const MAX_INDEX_FILES = 10 ;
33
+ const MAX_LIST_ATTR_LENGTH = 1000 ;
32
34
33
35
/**
34
36
* Implementation of trace store that persists traces on local disk.
@@ -148,7 +150,7 @@ export class LocalFileTraceStore implements TraceStore {
148
150
path . resolve ( this . storeRoot , `${ id } ` ) ,
149
151
JSON . stringify ( trace )
150
152
) ;
151
- const hasRootSpan = ! ! Object . values ( trace . spans ) . find (
153
+ const hasRootSpan = ! ! Object . values ( rawTrace . spans ) . find (
152
154
( s ) => ! s . parentSpanId
153
155
) ;
154
156
if ( this . index && hasRootSpan ) {
@@ -176,7 +178,7 @@ export class LocalFileTraceStore implements TraceStore {
176
178
} ) ;
177
179
178
180
const loadedTraces = await Promise . all (
179
- searchResult . data . map ( ( d ) => this . load ( d [ 'id' ] ) )
181
+ searchResult . data . map ( ( d ) => this . load ( d [ 'id' ] ) . then ( trucateTraceDetails ) )
180
182
) ;
181
183
182
184
return {
@@ -238,6 +240,48 @@ export class LocalFileTraceStore implements TraceStore {
238
240
}
239
241
}
240
242
243
+ function trucateTraceDetails ( t ?: TraceData ) : TraceData | undefined {
244
+ if ( ! t ) return t ;
245
+
246
+ const { spans : originalSpans , ...restOfTrace } = t ;
247
+
248
+ const spans = { } as Record < string , SpanData > ;
249
+ for ( const spanId of Object . keys ( originalSpans ) ) {
250
+ if ( ! originalSpans [ spanId ] . parentSpanId ) {
251
+ const { attributes : originalAttributes , ...restOfSpan } =
252
+ originalSpans [ spanId ] ;
253
+ spans [ spanId ] = {
254
+ attributes : trucateLargeAttrs ( originalAttributes ) ,
255
+ ...restOfSpan ,
256
+ } as SpanData ;
257
+ break ;
258
+ }
259
+ }
260
+
261
+ return { spans, ...restOfTrace } ;
262
+ }
263
+
264
+ export function trucateLargeAttrs < T > ( input : T ) : T {
265
+ if (
266
+ input === undefined ||
267
+ input === null ||
268
+ Array . isArray ( input ) ||
269
+ typeof input !== 'object'
270
+ ) {
271
+ return input ;
272
+ }
273
+ for ( const key in input ) {
274
+ if (
275
+ typeof input [ key ] === 'string' &&
276
+ ( input [ key ] as string ) . length > MAX_LIST_ATTR_LENGTH
277
+ ) {
278
+ input [ key ] = ( ( input [ key ] as string ) . substring ( 0 , MAX_LIST_ATTR_LENGTH ) +
279
+ '...' ) as any ;
280
+ }
281
+ }
282
+ return input ;
283
+ }
284
+
241
285
export interface IndexSearchResult {
242
286
pageLastIndex ?: number ;
243
287
data : Record < string , string > [ ] ;
0 commit comments