@@ -93,13 +93,56 @@ const retriableGetTraceIds = (options: GetXRayTraceIdsOptions) =>
93
93
}
94
94
} , retryOptions ) ;
95
95
96
+ /**
97
+ * Find the main Powertools subsegment in the trace
98
+ *
99
+ * A main Powertools subsegment is identified by the `## index.` suffix. Depending on the
100
+ * runtime, it may also be identified by the `Invocation` name.
101
+ *
102
+ * @param trace - The trace to find the main Powertools subsegment
103
+ * @param functionName - The function name to find the main Powertools subsegment
104
+ */
105
+ const findMainPowertoolsSubsegment = (
106
+ trace : XRayTraceDocumentParsed ,
107
+ functionName : string
108
+ ) => {
109
+ const maybePowertoolsSubsegment = trace . subsegments ?. find (
110
+ ( subsegment ) =>
111
+ subsegment . name . startsWith ( '## index.' ) ||
112
+ subsegment . name === 'Invocation'
113
+ ) ;
114
+
115
+ if ( ! maybePowertoolsSubsegment ) {
116
+ throw new Error ( `Main subsegment not found for ${ functionName } segment` ) ;
117
+ }
118
+
119
+ if ( maybePowertoolsSubsegment . name === 'Invocation' ) {
120
+ const powertoolsSubsegment = maybePowertoolsSubsegment . subsegments ?. find (
121
+ ( subsegment ) => subsegment . name . startsWith ( '## index.' )
122
+ ) ;
123
+
124
+ if ( ! powertoolsSubsegment ) {
125
+ throw new Error ( `Main subsegment not found for ${ functionName } segment` ) ;
126
+ }
127
+
128
+ return powertoolsSubsegment ;
129
+ }
130
+
131
+ return maybePowertoolsSubsegment ;
132
+ } ;
133
+
96
134
/**
97
135
* Parse and sort the trace segments by start time
98
136
*
99
137
* @param trace - The trace to parse and sort
100
138
* @param expectedSegmentsCount - The expected segments count for the trace
139
+ * @param functionName - The function name to find the main Powertools subsegment
101
140
*/
102
- const parseAndSortTrace = ( trace : Trace , expectedSegmentsCount : number ) => {
141
+ const parseAndSortTrace = (
142
+ trace : Trace ,
143
+ expectedSegmentsCount : number ,
144
+ functionName : string
145
+ ) => {
103
146
const { Id : id , Segments : segments } = trace ;
104
147
if ( segments === undefined || segments . length !== expectedSegmentsCount ) {
105
148
throw new Error (
@@ -116,9 +159,14 @@ const parseAndSortTrace = (trace: Trace, expectedSegmentsCount: number) => {
116
159
) ;
117
160
}
118
161
162
+ const parsedDocument = JSON . parse ( Document ) as XRayTraceDocumentParsed ;
163
+ if ( parsedDocument . origin === 'AWS::Lambda::Function' ) {
164
+ findMainPowertoolsSubsegment ( parsedDocument , functionName ) ;
165
+ }
166
+
119
167
parsedSegments . push ( {
120
168
Id,
121
- Document : JSON . parse ( Document ) as XRayTraceDocumentParsed ,
169
+ Document : parsedDocument ,
122
170
} ) ;
123
171
}
124
172
@@ -141,15 +189,14 @@ const parseAndSortTrace = (trace: Trace, expectedSegmentsCount: number) => {
141
189
const getTraceDetails = async (
142
190
options : GetXRayTraceDetailsOptions
143
191
) : Promise < XRayTraceParsed [ ] > => {
144
- const { traceIds, expectedSegmentsCount } = options ;
192
+ const { traceIds, expectedSegmentsCount, functionName } = options ;
145
193
const response = await xrayClient . send (
146
194
new BatchGetTracesCommand ( {
147
195
TraceIds : traceIds ,
148
196
} )
149
197
) ;
150
198
151
- const traces = response . Traces ;
152
-
199
+ const { Traces : traces } = response ;
153
200
if ( traces === undefined || traces . length !== traceIds . length ) {
154
201
throw new Error (
155
202
`Expected ${ traceIds . length } traces, got ${ traces ? traces . length : 0 } `
@@ -158,7 +205,9 @@ const getTraceDetails = async (
158
205
159
206
const parsedAndSortedTraces : XRayTraceParsed [ ] = [ ] ;
160
207
for ( const trace of traces ) {
161
- parsedAndSortedTraces . push ( parseAndSortTrace ( trace , expectedSegmentsCount ) ) ;
208
+ parsedAndSortedTraces . push (
209
+ parseAndSortTrace ( trace , expectedSegmentsCount , functionName )
210
+ ) ;
162
211
}
163
212
164
213
return parsedAndSortedTraces . sort (
@@ -194,7 +243,7 @@ const retriableGetTraceDetails = (options: GetXRayTraceDetailsOptions) =>
194
243
} , retryOptions ) ;
195
244
196
245
/**
197
- * Find the main function segment in the trace identified by the `## index.` suffix
246
+ * Find the main function segment within the `AWS::Lambda::Function` segment
198
247
*/
199
248
const findPowertoolsFunctionSegment = (
200
249
trace : XRayTraceParsed ,
@@ -211,30 +260,7 @@ const findPowertoolsFunctionSegment = (
211
260
}
212
261
213
262
const document = functionSegment . Document ;
214
-
215
- const maybePowertoolsSubsegment = document . subsegments ?. find (
216
- ( subsegment ) =>
217
- subsegment . name . startsWith ( '## index.' ) ||
218
- subsegment . name === 'Invocation'
219
- ) ;
220
-
221
- if ( ! maybePowertoolsSubsegment ) {
222
- throw new Error ( `Main subsegment not found for ${ functionName } segment` ) ;
223
- }
224
-
225
- if ( maybePowertoolsSubsegment . name === 'Invocation' ) {
226
- const powertoolsSubsegment = maybePowertoolsSubsegment . subsegments ?. find (
227
- ( subsegment ) => subsegment . name . startsWith ( '## index.' )
228
- ) ;
229
-
230
- if ( ! powertoolsSubsegment ) {
231
- throw new Error ( `Main subsegment not found for ${ functionName } segment` ) ;
232
- }
233
-
234
- return powertoolsSubsegment ;
235
- }
236
-
237
- return maybePowertoolsSubsegment ;
263
+ return findMainPowertoolsSubsegment ( document , functionName ) ;
238
264
} ;
239
265
240
266
/**
@@ -288,6 +314,7 @@ const getXRayTraceData = async (
288
314
const traces = await retriableGetTraceDetails ( {
289
315
traceIds,
290
316
expectedSegmentsCount,
317
+ functionName : resourceName ,
291
318
} ) ;
292
319
293
320
if ( ! traces ) {
@@ -303,9 +330,15 @@ const getXRayTraceData = async (
303
330
* @param options - The options to get the X-Ray trace data, including the start time, resource name, expected traces count, and expected segments count
304
331
*/
305
332
const getTraces = async (
306
- options : GetXRayTraceIdsOptions & Omit < GetXRayTraceDetailsOptions , 'traceIds' >
333
+ options : GetXRayTraceIdsOptions &
334
+ Omit < GetXRayTraceDetailsOptions , 'traceIds' | 'functionName' > & {
335
+ resourceName : string ;
336
+ }
307
337
) : Promise < EnrichedXRayTraceDocumentParsed [ ] > => {
308
- const traces = await getXRayTraceData ( options ) ;
338
+ const traces = await getXRayTraceData ( {
339
+ ...options ,
340
+ functionName : options . resourceName ,
341
+ } ) ;
309
342
310
343
const { resourceName } = options ;
311
344
0 commit comments