diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 1acf515ea3..1175d838e4 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -33,7 +33,12 @@ Notes: See the <> guide. - + ==== Unreleased + [float] + ===== Features +* Add context propagation support for @aws-sdk/client-eventbrige events. + ({issues}4166[#4166]) + [[release-notes-4.7.3]] ==== 4.7.3 - 2024/08/09 diff --git a/lib/lambda.js b/lib/lambda.js index 587e50fbae..47a2b8ffb6 100644 --- a/lib/lambda.js +++ b/lib/lambda.js @@ -26,6 +26,7 @@ const TRIGGER_SNS = 3; const TRIGGER_SQS = 4; const TRIGGER_S3_SINGLE_EVENT = 5; const TRIGGER_ELB = 6; // Elastic Load Balancer, aka Application Load Balancer +const TRIGGER_EVENTBUS = 7; function triggerTypeFromEvent(event) { if (event.requestContext) { @@ -47,6 +48,9 @@ function triggerTypeFromEvent(event) { return TRIGGER_S3_SINGLE_EVENT; } } + if (event['detail-type'] && event.source && event.detail) { + return TRIGGER_EVENTBUS; + } return TRIGGER_GENERIC; } @@ -468,6 +472,40 @@ function setS3SingleData(trans, event, context, faasId, isColdStart) { trans.setCloudContext(cloudContext); } +function setEventBusData(trans, event, context, faasId, isColdStart) { + trans.setFaas(getFaasData(context, faasId, isColdStart, 'pubsub')); + + trans.setDefaultName(`RECEIVE ${event['detail-type']}`); + trans.type = 'messaging'; + + const serviceContext = { + origin: { + name: event.source, + id: event.resources && event.resources[event.resources.length - 1], + version: event.version, + }, + }; + trans.setServiceContext(serviceContext); + + const cloudContext = { + origin: { + provider: 'aws', + region: event.region, + service: { + name: 'eventbus', + }, + account: { + id: event.account, + }, + }, + }; + trans.setCloudContext(cloudContext); + + if (event.detail.traceparent) { + trans.addLink({ context: event.detail.traceparent }); + } +} + function elasticApmAwsLambda(agent) { const log = agent.logger; const ins = agent._instrumentation; @@ -745,6 +783,9 @@ function elasticApmAwsLambda(agent) { case TRIGGER_S3_SINGLE_EVENT: setS3SingleData(trans, event, context, gFaasId, isColdStart); break; + case TRIGGER_EVENTBUS: + setEventBusData(trans, event, context, gFaasId, isColdStart); + break; case TRIGGER_GENERIC: setGenericData(trans, event, context, gFaasId, isColdStart); break; diff --git a/test/lambda/fixtures/aws_eventbridge_test_data.json b/test/lambda/fixtures/aws_eventbridge_test_data.json new file mode 100644 index 0000000000..437eb35bd9 --- /dev/null +++ b/test/lambda/fixtures/aws_eventbridge_test_data.json @@ -0,0 +1,17 @@ +{ + "version": "0", + "id": "6a7e8feb-b491-4cf7-a9f1-bf3703467718", + "detail-type": "EC2 Instance State-change Notification", + "source": "aws.ec2", + "account": "111122223333", + "time": "2017-12-22T18:43:48Z", + "region": "us-east-1", + "resources": [ + "arn:aws:ec2:us-west-1:123456789012:instance/i-1234567890abcdef0" + ], + "detail": { + "instance-id": " i-1234567890abcdef0", + "state": "terminated", + "traceparent": "00-80e1afed08e019fc1110464cfa66635c-7a085853722dc6d2-01" + } + } \ No newline at end of file diff --git a/test/lambda/fixtures/aws_eventbridge_test_data_basic.json b/test/lambda/fixtures/aws_eventbridge_test_data_basic.json new file mode 100644 index 0000000000..b6da7ea169 --- /dev/null +++ b/test/lambda/fixtures/aws_eventbridge_test_data_basic.json @@ -0,0 +1,8 @@ +{ + "detail-type": "EC2 Instance State-change Notification", + "source": "aws.ec2", + "detail": { + "instance-id": " i-1234567890abcdef0", + "state": "terminated" + } +} \ No newline at end of file diff --git a/test/lambda/lambda.test.js b/test/lambda/lambda.test.js index b305757fe0..b23e8314f6 100644 --- a/test/lambda/lambda.test.js +++ b/test/lambda/lambda.test.js @@ -487,6 +487,110 @@ tape.test('lambda transactions', function (suite) { ); }, }, + { + name: 'trans data: EventBridge', + event: loadFixture('aws_eventbridge_test_data.json'), + handler: async () => { + return 'hi'; + }, + checkResults: (t, requests, events) => { + assertExpectedServerRequests(t, requests); + const trans = events[1].transaction; + t.equal(trans.type, 'messaging', 'transaction.type'); + t.equal(trans.name, 'RECEIVE EC2 Instance State-change Notification', 'transaction.name'); + t.ok(UUID_RE.test(trans.faas.execution), 'transaction.faas.execution'); + t.deepEqual( + trans.faas, + { + id: 'arn:aws:lambda:us-east-1:123456789012:function:fixture-function-name', + name: 'fixture-function-name', + version: '1.0', + coldstart: trans.faas.coldstart, + execution: trans.faas.execution, + trigger: { type: 'pubsub' }, + }, + 'transaction.faas', + ); + t.deepEqual( + trans.context.service, + { + origin: { + name: 'aws.ec2', + id: 'arn:aws:ec2:us-west-1:123456789012:instance/i-1234567890abcdef0', + version: '0' + }, + }, + 'transaction.context.service', + ); + t.deepEqual( + trans.context.cloud, + { + origin: { + provider: 'aws', + region: 'us-east-1', + service: { name: 'eventbus' }, + account: { id: '111122223333' }, + }, + }, + 'transaction.context.cloud', + ); + t.deepEqual( + trans.links, + [ + { + trace_id: '80e1afed08e019fc1110464cfa66635c', + span_id: '7a085853722dc6d2' + } + ] + ) + }, + }, + { + name: 'trans data: EventBridge Basic', + event: loadFixture('aws_eventbridge_test_data_basic.json'), + handler: async () => { + return 'hi'; + }, + checkResults: (t, requests, events) => { + assertExpectedServerRequests(t, requests); + const trans = events[1].transaction; + t.equal(trans.type, 'messaging', 'transaction.type'); + t.equal(trans.name, 'RECEIVE EC2 Instance State-change Notification', 'transaction.name'); + t.ok(UUID_RE.test(trans.faas.execution), 'transaction.faas.execution'); + t.deepEqual( + trans.faas, + { + id: 'arn:aws:lambda:us-east-1:123456789012:function:fixture-function-name', + name: 'fixture-function-name', + version: '1.0', + coldstart: trans.faas.coldstart, + execution: trans.faas.execution, + trigger: { type: 'pubsub' }, + }, + 'transaction.faas', + ); + t.deepEqual( + trans.context.service, + { + origin: { + name: 'aws.ec2', + }, + }, + 'transaction.context.service', + ); + t.deepEqual( + trans.context.cloud, + { + origin: { + provider: 'aws', + service: { name: 'eventbus' }, + account: { }, + }, + }, + 'transaction.context.cloud', + ); + }, + }, { name: 'trans data: generic event', event: loadFixture('generic.json'),