Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

differentiate Lambda url from api gateway #3417

Merged
merged 4 commits into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading