Skip to content

Commit 32fa3d2

Browse files
committed
feat: add support for @aws-sdk/client-eventbridge context propagation
<!-- Replace this comment with a description of what's being changed by this PR. If this PR should close an issue, please add one of the magic keywords (e.g. Fixes) followed by the issue number. For more info see: https://help.github.com/articles/closing-issues-using-keywords/ --> Resolves elastic#4166. Extends the aws lambda handled triggers with eventbridge specific events. The minimum event structure is based on https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-events-structure.html and it contains: ```json { "detail-type": "event name", "source": "event source", "detail": { JSON object } } ``` The full event that can be handled is the following: ```json { "version": "0", "id": "UUID", "detail-type": "event name", "source": "event source", "account": "ARN", "time": "timestamp", "region": "region", "resources": [ "ARN" ], "detail": { "traceparent": "00-traceId-spanId", ... } } ``` ### Checklist - [x] Implement code - [x] Add tests - [ ] Update TypeScript typings - [ ] Update documentation - [x] Add CHANGELOG.asciidoc entry - [x] Commit message follows [commit guidelines](https://github.com/elastic/apm-agent-nodejs/blob/main/CONTRIBUTING.md#commit-message-guidelines)
1 parent 069f9f5 commit 32fa3d2

File tree

5 files changed

+176
-1
lines changed

5 files changed

+176
-1
lines changed

CHANGELOG.asciidoc

+6-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,12 @@ Notes:
3333
3434
See the <<upgrade-to-v4>> guide.
3535
36-
36+
==== Unreleased
37+
[float]
38+
===== Features
39+
* Add context propagation support for @aws-sdk/client-eventbrige events.
40+
({issues}4166[#4166])
41+
3742
[[release-notes-4.7.3]]
3843
==== 4.7.3 - 2024/08/09
3944

lib/lambda.js

+41
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const TRIGGER_SNS = 3;
2626
const TRIGGER_SQS = 4;
2727
const TRIGGER_S3_SINGLE_EVENT = 5;
2828
const TRIGGER_ELB = 6; // Elastic Load Balancer, aka Application Load Balancer
29+
const TRIGGER_EVENTBUS = 7;
2930

3031
function triggerTypeFromEvent(event) {
3132
if (event.requestContext) {
@@ -47,6 +48,9 @@ function triggerTypeFromEvent(event) {
4748
return TRIGGER_S3_SINGLE_EVENT;
4849
}
4950
}
51+
if (event['detail-type'] && event.source && event.detail) {
52+
return TRIGGER_EVENTBUS;
53+
}
5054
return TRIGGER_GENERIC;
5155
}
5256

@@ -468,6 +472,40 @@ function setS3SingleData(trans, event, context, faasId, isColdStart) {
468472
trans.setCloudContext(cloudContext);
469473
}
470474

475+
function setEventBusData(trans, event, context, faasId, isColdStart) {
476+
trans.setFaas(getFaasData(context, faasId, isColdStart, 'pubsub'));
477+
478+
trans.setDefaultName(`RECEIVE ${event['detail-type']}`);
479+
trans.type = 'messaging';
480+
481+
const serviceContext = {
482+
origin: {
483+
name: event.source,
484+
id: event.resources && event.resources[event.resources.length - 1],
485+
version: event.version,
486+
},
487+
};
488+
trans.setServiceContext(serviceContext);
489+
490+
const cloudContext = {
491+
origin: {
492+
provider: 'aws',
493+
region: event.region,
494+
service: {
495+
name: 'eventbus',
496+
},
497+
account: {
498+
id: event.account,
499+
},
500+
},
501+
};
502+
trans.setCloudContext(cloudContext);
503+
504+
if (event.detail.traceparent) {
505+
trans.addLink({ context: event.detail.traceparent });
506+
}
507+
}
508+
471509
function elasticApmAwsLambda(agent) {
472510
const log = agent.logger;
473511
const ins = agent._instrumentation;
@@ -745,6 +783,9 @@ function elasticApmAwsLambda(agent) {
745783
case TRIGGER_S3_SINGLE_EVENT:
746784
setS3SingleData(trans, event, context, gFaasId, isColdStart);
747785
break;
786+
case TRIGGER_EVENTBUS:
787+
setEventBusData(trans, event, context, gFaasId, isColdStart);
788+
break;
748789
case TRIGGER_GENERIC:
749790
setGenericData(trans, event, context, gFaasId, isColdStart);
750791
break;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"version": "0",
3+
"id": "6a7e8feb-b491-4cf7-a9f1-bf3703467718",
4+
"detail-type": "EC2 Instance State-change Notification",
5+
"source": "aws.ec2",
6+
"account": "111122223333",
7+
"time": "2017-12-22T18:43:48Z",
8+
"region": "us-east-1",
9+
"resources": [
10+
"arn:aws:ec2:us-west-1:123456789012:instance/i-1234567890abcdef0"
11+
],
12+
"detail": {
13+
"instance-id": " i-1234567890abcdef0",
14+
"state": "terminated",
15+
"traceparent": "00-80e1afed08e019fc1110464cfa66635c-7a085853722dc6d2-01"
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"detail-type": "EC2 Instance State-change Notification",
3+
"source": "aws.ec2",
4+
"detail": {
5+
"instance-id": " i-1234567890abcdef0",
6+
"state": "terminated"
7+
}
8+
}

test/lambda/lambda.test.js

+104
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,110 @@ tape.test('lambda transactions', function (suite) {
487487
);
488488
},
489489
},
490+
{
491+
name: 'trans data: EventBridge',
492+
event: loadFixture('aws_eventbridge_test_data.json'),
493+
handler: async () => {
494+
return 'hi';
495+
},
496+
checkResults: (t, requests, events) => {
497+
assertExpectedServerRequests(t, requests);
498+
const trans = events[1].transaction;
499+
t.equal(trans.type, 'messaging', 'transaction.type');
500+
t.equal(trans.name, 'RECEIVE EC2 Instance State-change Notification', 'transaction.name');
501+
t.ok(UUID_RE.test(trans.faas.execution), 'transaction.faas.execution');
502+
t.deepEqual(
503+
trans.faas,
504+
{
505+
id: 'arn:aws:lambda:us-east-1:123456789012:function:fixture-function-name',
506+
name: 'fixture-function-name',
507+
version: '1.0',
508+
coldstart: trans.faas.coldstart,
509+
execution: trans.faas.execution,
510+
trigger: { type: 'pubsub' },
511+
},
512+
'transaction.faas',
513+
);
514+
t.deepEqual(
515+
trans.context.service,
516+
{
517+
origin: {
518+
name: 'aws.ec2',
519+
id: 'arn:aws:ec2:us-west-1:123456789012:instance/i-1234567890abcdef0',
520+
version: '0'
521+
},
522+
},
523+
'transaction.context.service',
524+
);
525+
t.deepEqual(
526+
trans.context.cloud,
527+
{
528+
origin: {
529+
provider: 'aws',
530+
region: 'us-east-1',
531+
service: { name: 'eventbus' },
532+
account: { id: '111122223333' },
533+
},
534+
},
535+
'transaction.context.cloud',
536+
);
537+
t.deepEqual(
538+
trans.links,
539+
[
540+
{
541+
trace_id: '80e1afed08e019fc1110464cfa66635c',
542+
span_id: '7a085853722dc6d2'
543+
}
544+
]
545+
)
546+
},
547+
},
548+
{
549+
name: 'trans data: EventBridge Basic',
550+
event: loadFixture('aws_eventbridge_test_data_basic.json'),
551+
handler: async () => {
552+
return 'hi';
553+
},
554+
checkResults: (t, requests, events) => {
555+
assertExpectedServerRequests(t, requests);
556+
const trans = events[1].transaction;
557+
t.equal(trans.type, 'messaging', 'transaction.type');
558+
t.equal(trans.name, 'RECEIVE EC2 Instance State-change Notification', 'transaction.name');
559+
t.ok(UUID_RE.test(trans.faas.execution), 'transaction.faas.execution');
560+
t.deepEqual(
561+
trans.faas,
562+
{
563+
id: 'arn:aws:lambda:us-east-1:123456789012:function:fixture-function-name',
564+
name: 'fixture-function-name',
565+
version: '1.0',
566+
coldstart: trans.faas.coldstart,
567+
execution: trans.faas.execution,
568+
trigger: { type: 'pubsub' },
569+
},
570+
'transaction.faas',
571+
);
572+
t.deepEqual(
573+
trans.context.service,
574+
{
575+
origin: {
576+
name: 'aws.ec2',
577+
},
578+
},
579+
'transaction.context.service',
580+
);
581+
t.deepEqual(
582+
trans.context.cloud,
583+
{
584+
origin: {
585+
provider: 'aws',
586+
service: { name: 'eventbus' },
587+
account: { },
588+
},
589+
},
590+
'transaction.context.cloud',
591+
);
592+
},
593+
},
490594
{
491595
name: 'trans data: generic event',
492596
event: loadFixture('generic.json'),

0 commit comments

Comments
 (0)