Repository: serverless/dashboard (language: python)

Issue:
AWS Lambda SDK: Adapt to rely on `@serverless/sdk`
_Depends on https://github.com/serverless/console/pull/330 being merged and released first_


Discussion / hints:

Fix patch:
diff --git a/node/packages/aws-lambda-sdk/instrument/index.js b/node/packages/aws-lambda-sdk/instrument/index.js
index 3da276335..0319b80ad 100644
--- a/node/packages/aws-lambda-sdk/instrument/index.js
+++ b/node/packages/aws-lambda-sdk/instrument/index.js
@@ -16,6 +16,11 @@ const pkgJson = require('../package');
 
 const serverlessSdk = require('./lib/sdk');
 
+const capturedEvents = [];
+serverlessSdk._eventEmitter.on('captured-event', (capturedEvent) =>
+  capturedEvents.push(capturedEvent)
+);
+
 const { traceSpans } = serverlessSdk;
 const { awsLambda: awsLambdaSpan, awsLambdaInitialization: awsLambdaInitializationSpan } =
   traceSpans;
@@ -95,7 +100,7 @@ const reportTrace = () => {
       delete spanPayload.output;
       return spanPayload;
     }),
-    events: [],
+    events: capturedEvents.map((capturedEvent) => capturedEvent.toProtobufObject()),
   });
   const payloadBuffer = (serverlessSdk._lastTraceBuffer =
     traceProto.TracePayload.encode(payload).finish());
@@ -155,6 +160,7 @@ module.exports = (originalHandler, options = {}) => {
           delete awsLambdaSpan.endTime;
           awsLambdaSpan.tags.reset();
           awsLambdaSpan.subSpans.clear();
+          capturedEvents.length = 0;
           isRootSpanReset = true;
         };
         try {


Test patch:
diff --git a/node/packages/aws-lambda-sdk/test/fixtures/lambdas/sdk.js b/node/packages/aws-lambda-sdk/test/fixtures/lambdas/sdk.js
index 77455ff1c..35883c6e3 100644
--- a/node/packages/aws-lambda-sdk/test/fixtures/lambdas/sdk.js
+++ b/node/packages/aws-lambda-sdk/test/fixtures/lambdas/sdk.js
@@ -2,7 +2,9 @@
 
 const sdk = require('@serverless/sdk');
 
+let counter = 0;
 module.exports.handler = async (event) => {
+  const invocationId = ++counter;
   if (!sdk) throw new Error('SDK not exported');
   if (!event.isTriggeredByUnitTest) {
     // eslint-disable-next-line import/no-unresolved
@@ -12,6 +14,10 @@ module.exports.handler = async (event) => {
 
   sdk.createTraceSpan('user.span').close();
 
+  sdk.captureError(new Error('Captured error'), {
+    tags: { 'user.tag': 'example', 'invocationid': invocationId },
+  });
+
   return {
     name: sdk.name,
     version: sdk.version,
diff --git a/node/packages/aws-lambda-sdk/test/integration/index.test.js b/node/packages/aws-lambda-sdk/test/integration/index.test.js
index b193ca983..e09d890ac 100644
--- a/node/packages/aws-lambda-sdk/test/integration/index.test.js
+++ b/node/packages/aws-lambda-sdk/test/integration/index.test.js
@@ -1316,8 +1316,10 @@ describe('integration', function () {
           isCustomResponse: true,
           test: ({ invocationsData }) => {
             for (const [index, { trace, responsePayload }] of invocationsData.entries()) {
-              const { spans } = trace;
+              const { spans, events } = trace;
+              let awsLambdaInvocationSpan;
               if (index === 0) {
+                awsLambdaInvocationSpan = spans[2];
                 expect(spans.map(({ name }) => name)).to.deep.equal([
                   'aws.lambda',
                   'aws.lambda.initialization',
@@ -1325,6 +1327,7 @@ describe('integration', function () {
                   'user.span',
                 ]);
               } else {
+                awsLambdaInvocationSpan = spans[1];
                 expect(spans.map(({ name }) => name)).to.deep.equal([
                   'aws.lambda',
                   'aws.lambda.invocation',
@@ -1335,6 +1338,26 @@ describe('integration', function () {
               expect(payload.name).to.equal(pkgJson.name);
               expect(payload.version).to.equal(pkgJson.version);
               expect(payload.rootSpanName).to.equal('aws.lambda');
+
+              const userEvent = events[0];
+              expect(events).to.deep.equal([
+                {
+                  id: userEvent.id,
+                  traceId: awsLambdaInvocationSpan.traceId,
+                  spanId: awsLambdaInvocationSpan.id,
+                  timestampUnixNano: userEvent.timestampUnixNano,
+                  eventName: userEvent.eventName,
+                  customTags: JSON.stringify({ 'user.tag': 'example', 'invocationid': index + 1 }),
+                  tags: {
+                    error: {
+                      name: 'Error',
+                      message: 'Captured error',
+                      stacktrace: userEvent.tags.error.stacktrace,
+                      type: 2,
+                    },
+                  },
+                },
+              ]);
             }
           },
         },
diff --git a/node/packages/aws-lambda-sdk/test/unit/internal-extension/index.test.js b/node/packages/aws-lambda-sdk/test/unit/internal-extension/index.test.js
index 4f1ed592d..fa1a5a842 100644
--- a/node/packages/aws-lambda-sdk/test/unit/internal-extension/index.test.js
+++ b/node/packages/aws-lambda-sdk/test/unit/internal-extension/index.test.js
@@ -803,7 +803,7 @@ describe('internal-extension/index.test.js', () => {
       payload: { isTriggeredByUnitTest: true },
     });
 
-    const { spans } = trace;
+    const { spans, events } = trace;
 
     expect(spans.map(({ name }) => name)).to.deep.equal([
       'aws.lambda',
@@ -814,6 +814,26 @@ describe('internal-extension/index.test.js', () => {
     expect(result.name).to.equal(pkgJson.name);
     expect(result.version).to.equal(pkgJson.version);
     expect(result.rootSpanName).to.equal('aws.lambda');
+
+    const userEvent = events[0];
+    expect(events).to.deep.equal([
+      {
+        id: userEvent.id,
+        traceId: spans[0].traceId,
+        spanId: spans[2].id,
+        timestampUnixNano: userEvent.timestampUnixNano,
+        eventName: userEvent.eventName,
+        customTags: JSON.stringify({ 'user.tag': 'example', 'invocationid': 1 }),
+        tags: {
+          error: {
+            name: 'Error',
+            message: 'Captured error',
+            stacktrace: userEvent.tags.error.stacktrace,
+            type: 2,
+          },
+        },
+      },
+    ]);
   });
 
   describe('dev mode', () => {