Fix javaagent armeria server instrumentation (#8281)

This commit is contained in:
Lauri Tulmin 2023-04-13 17:00:20 +03:00 committed by GitHub
parent b594b7f6f9
commit 9b9cf9692e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 52 additions and 71 deletions

View File

@ -13,6 +13,7 @@ muzzle {
dependencies {
implementation(project(":instrumentation:armeria-1.3:library"))
testInstrumentation(project(":instrumentation:netty:netty-4.1:javaagent"))
library("com.linecorp.armeria:armeria:1.3.0")

View File

@ -1,18 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.armeria.v1_3;
import com.linecorp.armeria.common.ResponseHeadersBuilder;
import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseMutator;
enum ArmeriaHttpResponseMutator implements HttpServerResponseMutator<ResponseHeadersBuilder> {
INSTANCE;
@Override
public void appendHeader(ResponseHeadersBuilder response, String name, String value) {
response.add(name, value);
}
}

View File

@ -26,8 +26,6 @@ public final class ArmeriaSingletons {
ArmeriaTelemetry.builder(GlobalOpenTelemetry.get())
.setCapturedClientRequestHeaders(CommonConfig.get().getClientRequestHeaders())
.setCapturedClientResponseHeaders(CommonConfig.get().getClientResponseHeaders())
.setCapturedServerRequestHeaders(CommonConfig.get().getServerRequestHeaders())
.setCapturedServerResponseHeaders(CommonConfig.get().getServerResponseHeaders())
.addClientAttributeExtractor(
PeerServiceAttributesExtractor.create(
new ArmeriaNetClientAttributesGetter(),
@ -35,10 +33,7 @@ public final class ArmeriaSingletons {
.build();
CLIENT_DECORATOR = telemetry.newClientDecorator();
SERVER_DECORATOR =
telemetry
.newServiceDecorator()
.compose(service -> new ResponseCustomizingDecorator(service));
SERVER_DECORATOR = service -> new ServerDecorator(service);
}
private ArmeriaSingletons() {}

View File

@ -1,47 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.armeria.v1_3;
import com.linecorp.armeria.common.FilteredHttpResponse;
import com.linecorp.armeria.common.HttpObject;
import com.linecorp.armeria.common.HttpRequest;
import com.linecorp.armeria.common.HttpResponse;
import com.linecorp.armeria.common.ResponseHeaders;
import com.linecorp.armeria.common.ResponseHeadersBuilder;
import com.linecorp.armeria.server.HttpService;
import com.linecorp.armeria.server.ServiceRequestContext;
import com.linecorp.armeria.server.SimpleDecoratingHttpService;
import io.opentelemetry.context.Context;
import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseCustomizerHolder;
class ResponseCustomizingDecorator extends SimpleDecoratingHttpService {
ResponseCustomizingDecorator(HttpService delegate) {
super(delegate);
}
@Override
public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) throws Exception {
HttpResponse response = unwrap().serve(ctx, req);
Context context = Context.current();
return new FilteredHttpResponse(response) {
@Override
public HttpObject filter(HttpObject obj) {
// Ignore other objects like HttpData.
if (!(obj instanceof ResponseHeaders)) {
return obj;
}
ResponseHeaders headers = (ResponseHeaders) obj;
ResponseHeadersBuilder headersBuilder = headers.toBuilder();
HttpServerResponseCustomizerHolder.getCustomizer()
.customize(context, headersBuilder, ArmeriaHttpResponseMutator.INSTANCE);
return headersBuilder.build();
}
};
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.armeria.v1_3;
import com.linecorp.armeria.common.HttpRequest;
import com.linecorp.armeria.common.HttpResponse;
import com.linecorp.armeria.server.HttpService;
import com.linecorp.armeria.server.ServiceRequestContext;
import com.linecorp.armeria.server.SimpleDecoratingHttpService;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.ErrorCauseExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpRouteHolder;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpRouteSource;
class ServerDecorator extends SimpleDecoratingHttpService {
ServerDecorator(HttpService delegate) {
super(delegate);
}
@Override
public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) throws Exception {
String matchedRoute = ctx.config().route().patternString();
if (matchedRoute == null || matchedRoute.isEmpty()) {
matchedRoute = "/";
} else if (!matchedRoute.startsWith("/")) {
matchedRoute = "/" + matchedRoute;
}
Context otelContext = Context.current();
HttpRouteHolder.updateHttpRoute(
otelContext, HttpRouteSource.SERVLET, (context, name) -> name, matchedRoute);
try {
return unwrap().serve(ctx, req);
} catch (Throwable throwable) {
Span span = Span.fromContext(otelContext);
span.setStatus(StatusCode.ERROR);
span.recordException(ErrorCauseExtractor.getDefault().extract(throwable));
throw throwable;
}
}
}