Search code examples
amazon-web-servicesaws-lambdaaws-xray

Use Xray sdk in Lambda to send segments over UDP


I am using Lambda. I want to send a subsegment to Xray with an custom end_time. Xray is enabled in my Lambda.

When I use the aws-xray-sdk-core and addNewSubsegment('postgres') I do not find the possibility to add an end_time. It looks like the end_time is being set when you close() the Segment.

To try and solve this limitation I base myself on the following to send a custom segment to the Xray Daemon using UDP. Use UDP to send segment to XRay

Below code is not sending a SubSegment to Xray. I am not receiving any errors when sending the segment with client.send(...).

Does someone knows more about this limitation of setting an custom end_time/ knows if it's possible with UDP inside a Lambda?

      import AWSXRay from 'aws-xray-sdk-core'
      const traceDocument = {
        trace_id,
        id: generateRandomHex(16),
        name: 'postgres',
        start_time,
        end_time,
        type: 'subsegment',
        parent_id,
        sql: { sanitized_query: query },
      }

      const client = createSocket('udp4')

      const udpSegment = `{"format": "json", "version": 1}\n${traceDocument}`

      client.send(udpSegment, 2000, '127.0.0.1', (e, b) => {
        console.log(e, b)
      })

Solution

  • Managed to find out the solution myself

    used the X-Ray SDK with a combination of

    addAttribute('in_progress', false) and streamSubsegments() to send the subsegments to X-Ray

    export const onQueryEvent = async (e) => {
      try {
       const segment = AWSXRay.getSegment()
         if (segment) {    
          const paramsArr = JSON.parse(e.params)
          const query = getQueryWithParams(e.query, paramsArr)      // X-Ray wants the time in seconds -> ms * 1e-3
          const start_time = e.timestamp.valueOf() * 1e-3 
          const end_time = (e.timestamp.valueOf() + e.duration) * 1e-3
         
          // Add a new Subsegment to parent Segment
          const subSegment = segment.addNewSubsegment('postgres')      // Add data to the segment
          subSegment.addSqlData({ sanitized_query: query })
          subSegment.addAttribute('start_time', start_time)
          subSegment.addAttribute('end_time', end_time)      // Set in_progress to false so subSegment 
          // will be send to xray on streamSubsegments()
          subSegment.addAttribute('in_progress', false)
          subSegment.streamSubsegments()
         }
      } catch (e) {
      console.log(e)
      }
    }