Skip to content

Commit

Permalink
differentiate Lambda url from api gateway (#3417)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Sylvain Juge <[email protected]>
  • Loading branch information
videnkz and SylvainJuge authored Mar 13, 2024
1 parent 4858631 commit 3c4a753
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 7 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ Use subheadings with the "=====" level for adding notes for unreleased changes:
===== Bug fixes
* Fixed problems with public API annotation inheritance - {pull}3551[#3551]
[float]
===== Features
* Differentiate Lambda URLs from API Gateway in AWS Lambda integration - {pull}3417[#3417]
[[release-notes-1.x]]
=== Java Agent version 1.x
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,15 @@ protected void setTransactionTriggerData(Transaction<?> transaction, APIGatewayP
}
}

@Override
public String getDomainName(APIGatewayProxyRequestEvent apiGatewayRequest) {
APIGatewayProxyRequestEvent.ProxyRequestContext rContext = apiGatewayRequest.getRequestContext();
if (null == rContext) {
return null;
}
return rContext.getDomainName();
}

@Override
protected String getApiGatewayVersion() {
return "1.0";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@
package co.elastic.apm.agent.awslambda.helper;

import co.elastic.apm.agent.awslambda.MapTextHeaderGetter;
import co.elastic.apm.agent.tracer.GlobalTracer;
import co.elastic.apm.agent.sdk.internal.util.PrivilegedActionUtils;
import co.elastic.apm.agent.tracer.Tracer;
import co.elastic.apm.agent.tracer.GlobalTracer;
import co.elastic.apm.agent.tracer.Transaction;
import co.elastic.apm.agent.sdk.internal.util.PrivilegedActionUtils;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPResponse;
Expand All @@ -45,8 +45,8 @@ public static APIGatewayProxyV2TransactionHelper getInstance() {
}

@Override
protected Transaction<?> doStartTransaction(APIGatewayV2HTTPEvent apiGatewayEvent, Context lambdaContext) {
Transaction<?> transaction = tracer.startChildTransaction(apiGatewayEvent.getHeaders(), MapTextHeaderGetter.INSTANCE, PrivilegedActionUtils.getClassLoader(apiGatewayEvent.getClass()));
protected Transaction doStartTransaction(APIGatewayV2HTTPEvent apiGatewayEvent, Context lambdaContext) {
Transaction transaction = tracer.startChildTransaction(apiGatewayEvent.getHeaders(), MapTextHeaderGetter.INSTANCE, PrivilegedActionUtils.getClassLoader(apiGatewayEvent.getClass()));

APIGatewayV2HTTPEvent.RequestContext requestContext = apiGatewayEvent.getRequestContext();
if (transaction != null) {
Expand All @@ -60,12 +60,12 @@ protected Transaction<?> doStartTransaction(APIGatewayV2HTTPEvent apiGatewayEven
}

@Override
public void captureOutputForTransaction(Transaction<?> transaction, APIGatewayV2HTTPResponse responseEvent) {
public void captureOutputForTransaction(Transaction transaction, APIGatewayV2HTTPResponse responseEvent) {
fillHttpResponseData(transaction, responseEvent.getHeaders(), responseEvent.getStatusCode());
}

@Override
protected void setTransactionTriggerData(Transaction<?> transaction, APIGatewayV2HTTPEvent apiGatewayRequest) {
protected void setTransactionTriggerData(Transaction transaction, APIGatewayV2HTTPEvent apiGatewayRequest) {
super.setTransactionTriggerData(transaction, apiGatewayRequest);
APIGatewayV2HTTPEvent.RequestContext rContext = apiGatewayRequest.getRequestContext();
setApiGatewayContextData(transaction, rContext.getRequestId(), rContext.getApiId(),
Expand Down Expand Up @@ -112,4 +112,11 @@ protected String getResourcePath(APIGatewayV2HTTPEvent event) {
}
return routeKey;
}

@Nullable
@Override
String getDomainName(APIGatewayV2HTTPEvent apiGatewayRequest) {
APIGatewayV2HTTPEvent.RequestContext requestContext = apiGatewayRequest.getRequestContext();
return requestContext != null ? requestContext.getDomainName() : null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import co.elastic.apm.agent.sdk.logging.LoggerFactory;
import co.elastic.apm.agent.tracer.AbstractSpan;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPEvent;

import javax.annotation.Nullable;
import java.nio.CharBuffer;
Expand Down Expand Up @@ -124,12 +125,27 @@ private boolean hasBody(@Nullable String contentTypeHeader, @Nullable String met
protected void setTransactionTriggerData(Transaction<?> transaction, I apiGatewayRequest) {
transaction.withType(TRANSACTION_TYPE);
CloudOrigin cloudOrigin = transaction.getContext().getCloudOrigin();
cloudOrigin.withServiceName("api gateway");
if (isLambdaUrl(apiGatewayRequest)) {
cloudOrigin.withServiceName("lambda url");
} else {
cloudOrigin.withServiceName("api gateway");
}
cloudOrigin.withProvider("aws");
transaction.getFaas().getTrigger().withType("http");
transaction.getContext().getServiceOrigin().withVersion(getApiGatewayVersion());
}

private boolean isLambdaUrl(I apiGatewayRequest) {
String domainName = getDomainName(apiGatewayRequest);
if (null == domainName) {
return false;
}
return domainName.contains(".lambda-url.");
}

@Nullable
abstract String getDomainName(I apiGatewayRequest);

protected void setApiGatewayContextData(Transaction<?> transaction, @Nullable String requestId, @Nullable String apiId,
@Nullable String domainName, @Nullable String accountId) {
transaction.getFaas().getTrigger().withRequestId(requestId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,17 @@ public void testTransactionNameWithUsePathAsName() {
assertThat(reporter.getFirstTransaction().getNameAsString()).isEqualTo("PUT /prod/proxy-test/12345");
}

@Test
public void testServiceNameAsLambdaUrl() {
APIGatewayProxyRequestEvent event = createInput();
event.getRequestContext().setDomainName("myurl.lambda-url.us-west-2.on.aws");
getFunction().handleRequest(event, context);
reporter.awaitTransactionCount(1);
reporter.awaitSpanCount(1);
Transaction transaction = reporter.getFirstTransaction();
assertThat(transaction.getContext().getCloudOrigin().getServiceName()).isEqualTo("lambda url");
}

@Override
protected AbstractFunction<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> createHandler() {
return new ApiGatewayV1LambdaFunction();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import co.elastic.apm.agent.impl.transaction.Transaction;
import co.elastic.apm.agent.tracer.Outcome;
import co.elastic.apm.agent.tracer.metadata.PotentiallyMultiValuedMap;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPResponse;
import org.junit.BeforeClass;
Expand Down Expand Up @@ -249,6 +250,17 @@ public void testTransactionNameWithUsePathAsName() {
assertThat(reporter.getFirstTransaction().getNameAsString()).isEqualTo("PUT /prod/proxy-test/12345");
}

@Test
public void testServiceNameAsLambdaUrl() {
APIGatewayV2HTTPEvent event = createInput();
event.getRequestContext().setDomainName("myurl.lambda-url.us-west-2.on.aws");
getFunction().handleRequest(event, context);
reporter.awaitTransactionCount(1);
reporter.awaitSpanCount(1);
Transaction transaction = reporter.getFirstTransaction();
assertThat(transaction.getContext().getCloudOrigin().getServiceName()).isEqualTo("lambda url");
}

@Override
protected AbstractFunction<APIGatewayV2HTTPEvent, APIGatewayV2HTTPResponse> createHandler() {
return new ApiGatewayV2LambdaFunction();
Expand Down

0 comments on commit 3c4a753

Please sign in to comment.