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

Split ratpack into client and server #12853

Merged
merged 17 commits into from
Dec 16, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.ratpack.v1_7;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.ratpack.v1_7.internal.OpenTelemetryHttpClient;
import ratpack.http.client.HttpClient;
import ratpack.http.client.HttpResponse;
import ratpack.http.client.RequestSpec;

/**
* Entrypoint for instrumenting Ratpack http client.
*
* <p>To apply OpenTelemetry instrumentation to a http client, wrap the {@link HttpClient} using
* {@link #instrument(HttpClient)}.
*
* <pre>{@code
* RatpackClientTelemetry telemetry = RatpackClientTelemetry.create(OpenTelemetrySdk.builder()
* ...
* .build());
* HttpClient instrumentedHttpClient = telemetry.instrument(httpClient);
* }</pre>
*/
public final class RatpackClientTelemetry {

/**
* Returns a new {@link RatpackClientTelemetry} configured with the given {@link OpenTelemetry}.
*/
public static RatpackClientTelemetry create(OpenTelemetry openTelemetry) {
return builder(openTelemetry).build();
}

/**
* Returns a new {@link RatpackClientTelemetryBuilder} configured with the given {@link
* OpenTelemetry}.
*/
public static RatpackClientTelemetryBuilder builder(OpenTelemetry openTelemetry) {
return new RatpackClientTelemetryBuilder(openTelemetry);
}

private final OpenTelemetryHttpClient httpClientInstrumenter;

RatpackClientTelemetry(Instrumenter<RequestSpec, HttpResponse> clientInstrumenter) {
httpClientInstrumenter = new OpenTelemetryHttpClient(clientInstrumenter);
}

/** Returns instrumented instance of {@link HttpClient} with OpenTelemetry. */
public HttpClient instrument(HttpClient httpClient) throws Exception {
return httpClientInstrumenter.instrument(httpClient);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.ratpack.v1_7;

import com.google.errorprone.annotations.CanIgnoreReturnValue;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.incubator.builder.internal.DefaultHttpClientInstrumenterBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
import io.opentelemetry.instrumentation.api.semconv.http.HttpClientAttributesExtractorBuilder;
import io.opentelemetry.instrumentation.ratpack.v1_7.internal.Experimental;
import io.opentelemetry.instrumentation.ratpack.v1_7.internal.RatpackClientInstrumenterBuilderFactory;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import ratpack.http.client.HttpResponse;
import ratpack.http.client.RequestSpec;

/** A builder for {@link RatpackClientTelemetry}. */
public final class RatpackClientTelemetryBuilder {

private static final String INSTRUMENTATION_NAME = "io.opentelemetry.ratpack-1.7";

private final DefaultHttpClientInstrumenterBuilder<RequestSpec, HttpResponse> builder;

static {
Experimental.setSetEmitExperimentalClientTelemetry(
(builder, emit) -> builder.builder.setEmitExperimentalHttpClientMetrics(emit));
}

RatpackClientTelemetryBuilder(OpenTelemetry openTelemetry) {
builder = RatpackClientInstrumenterBuilderFactory.create(INSTRUMENTATION_NAME, openTelemetry);
}

@CanIgnoreReturnValue
public RatpackClientTelemetryBuilder addAttributesExtractor(
AttributesExtractor<? super RequestSpec, ? super HttpResponse> attributesExtractor) {
builder.addAttributesExtractor(attributesExtractor);
return this;
}

/**
* Configures the HTTP client request headers that will be captured as span attributes.
*
* @param requestHeaders A list of HTTP header names.
*/
@CanIgnoreReturnValue
public RatpackClientTelemetryBuilder setCapturedRequestHeaders(List<String> requestHeaders) {
builder.setCapturedRequestHeaders(requestHeaders);
return this;
}

/**
* Configures the HTTP client response headers that will be captured as span attributes.
*
* @param responseHeaders A list of HTTP header names.
*/
@CanIgnoreReturnValue
public RatpackClientTelemetryBuilder setCapturedResponseHeaders(List<String> responseHeaders) {
builder.setCapturedResponseHeaders(responseHeaders);
return this;
}

/**
* Configures the instrumentation to recognize an alternative set of HTTP request methods.
*
* <p>By default, this instrumentation defines "known" methods as the ones listed in <a
* href="https://www.rfc-editor.org/rfc/rfc9110.html#name-methods">RFC9110</a> and the PATCH
* method defined in <a href="https://www.rfc-editor.org/rfc/rfc5789.html">RFC5789</a>.
*
* <p>Note: calling this method <b>overrides</b> the default known method sets completely; it does
* not supplement it.
*
* @param knownMethods A set of recognized HTTP request methods.
* @see HttpClientAttributesExtractorBuilder#setKnownMethods(Set)
*/
@CanIgnoreReturnValue
public RatpackClientTelemetryBuilder setKnownMethods(Set<String> knownMethods) {
builder.setKnownMethods(knownMethods);
return this;
}

/** Sets custom client {@link SpanNameExtractor} via transform function. */
@CanIgnoreReturnValue
public RatpackClientTelemetryBuilder setSpanNameExtractor(
Function<
SpanNameExtractor<? super RequestSpec>,
? extends SpanNameExtractor<? super RequestSpec>>
clientSpanNameExtractor) {
builder.setSpanNameExtractor(clientSpanNameExtractor);
return this;
}

/** Returns a new {@link RatpackClientTelemetry} with the configuration of this builder. */
public RatpackClientTelemetry build() {
return new RatpackClientTelemetry(builder.build());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.ratpack.v1_7;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.ratpack.v1_7.internal.OpenTelemetryExecInitializer;
import io.opentelemetry.instrumentation.ratpack.v1_7.internal.OpenTelemetryExecInterceptor;
import io.opentelemetry.instrumentation.ratpack.v1_7.internal.OpenTelemetryServerHandler;
import ratpack.exec.ExecInitializer;
import ratpack.exec.ExecInterceptor;
import ratpack.handling.Handler;
import ratpack.handling.HandlerDecorator;
import ratpack.http.Request;
import ratpack.http.Response;
import ratpack.registry.RegistrySpec;

/**
* Entrypoint for instrumenting Ratpack server.
*
* <p>To apply OpenTelemetry instrumentation to a server, configure the {@link RegistrySpec} using
* {@link #configureRegistry(RegistrySpec)}.
*
* <pre>{@code
* RatpackServerTelemetry telemetry = RatpackServerTelemetry.create(OpenTelemetrySdk.builder()
* ...
* .build());
* RatpackServer.start(server -> {
* server.registryOf(telemetry::configureRegistry);
* server.handlers(chain -> ...);
* });
* }</pre>
*/
public final class RatpackServerTelemetry {

/**
* Returns a new {@link RatpackServerTelemetry} configured with the given {@link OpenTelemetry}.
*/
public static RatpackServerTelemetry create(OpenTelemetry openTelemetry) {
return builder(openTelemetry).build();
}

/**
* Returns a new {@link RatpackServerTelemetryBuilder} configured with the given {@link
* OpenTelemetry}.
*/
public static RatpackServerTelemetryBuilder builder(OpenTelemetry openTelemetry) {
return new RatpackServerTelemetryBuilder(openTelemetry);
}

private final OpenTelemetryServerHandler serverHandler;

RatpackServerTelemetry(Instrumenter<Request, Response> serverInstrumenter) {
serverHandler = new OpenTelemetryServerHandler(serverInstrumenter);
}

/** Returns a {@link Handler} to support Ratpack Registry binding. */
public Handler getHandler() {
return serverHandler;
}

/** Returns instance of {@link ExecInterceptor} to support Ratpack Registry binding. */
public ExecInterceptor getExecInterceptor() {
return OpenTelemetryExecInterceptor.INSTANCE;
}

/** Returns instance of {@link ExecInitializer} to support Ratpack Registry binding. */
public ExecInitializer getExecInitializer() {
return OpenTelemetryExecInitializer.INSTANCE;
}

/** Configures the {@link RegistrySpec} with OpenTelemetry. */
public void configureRegistry(RegistrySpec registry) {
registry.add(HandlerDecorator.prepend(serverHandler));
registry.add(OpenTelemetryExecInterceptor.INSTANCE);
registry.add(OpenTelemetryExecInitializer.INSTANCE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.ratpack.v1_7;

import com.google.errorprone.annotations.CanIgnoreReturnValue;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.incubator.builder.internal.DefaultHttpServerInstrumenterBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
import io.opentelemetry.instrumentation.api.semconv.http.HttpServerAttributesExtractorBuilder;
import io.opentelemetry.instrumentation.ratpack.v1_7.internal.Experimental;
import io.opentelemetry.instrumentation.ratpack.v1_7.internal.RatpackServerInstrumenterBuilderFactory;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import ratpack.http.Request;
import ratpack.http.Response;

/** A builder for {@link RatpackServerTelemetry}. */
public final class RatpackServerTelemetryBuilder {

private static final String INSTRUMENTATION_NAME = "io.opentelemetry.ratpack-1.7";

private final DefaultHttpServerInstrumenterBuilder<Request, Response> builder;

static {
Experimental.setSetEmitExperimentalServerTelemetry(
(builder, emit) -> builder.builder.setEmitExperimentalHttpServerMetrics(emit));
}

RatpackServerTelemetryBuilder(OpenTelemetry openTelemetry) {
builder = RatpackServerInstrumenterBuilderFactory.create(INSTRUMENTATION_NAME, openTelemetry);
}

/**
* Adds an additional {@link AttributesExtractor} to invoke to set attributes to instrumented
* items. The {@link AttributesExtractor} will be executed after all default extractors.
*/
@CanIgnoreReturnValue
public RatpackServerTelemetryBuilder addAttributesExtractor(
AttributesExtractor<? super Request, ? super Response> attributesExtractor) {
builder.addAttributesExtractor(attributesExtractor);
return this;
}

/**
* Configures the HTTP server request headers that will be captured as span attributes.
*
* @param requestHeaders A list of HTTP header names.
*/
@CanIgnoreReturnValue
public RatpackServerTelemetryBuilder setCapturedRequestHeaders(List<String> requestHeaders) {
builder.setCapturedRequestHeaders(requestHeaders);
return this;
}

/**
* Configures the HTTP server response headers that will be captured as span attributes.
*
* @param responseHeaders A list of HTTP header names.
*/
@CanIgnoreReturnValue
public RatpackServerTelemetryBuilder setCapturedResponseHeaders(List<String> responseHeaders) {
builder.setCapturedResponseHeaders(responseHeaders);
return this;
}

/**
* Configures the instrumentation to recognize an alternative set of HTTP request methods.
*
* <p>By default, this instrumentation defines "known" methods as the ones listed in <a
* href="https://www.rfc-editor.org/rfc/rfc9110.html#name-methods">RFC9110</a> and the PATCH
* method defined in <a href="https://www.rfc-editor.org/rfc/rfc5789.html">RFC5789</a>.
*
* <p>Note: calling this method <b>overrides</b> the default known method sets completely; it does
* not supplement it.
*
* @param knownMethods A set of recognized HTTP request methods.
* @see HttpServerAttributesExtractorBuilder#setKnownMethods(Set)
*/
@CanIgnoreReturnValue
public RatpackServerTelemetryBuilder setKnownMethods(Set<String> knownMethods) {
builder.setKnownMethods(knownMethods);
return this;
}

/** Sets custom server {@link SpanNameExtractor} via transform function. */
@CanIgnoreReturnValue
public RatpackServerTelemetryBuilder setSpanNameExtractor(
Function<SpanNameExtractor<? super Request>, ? extends SpanNameExtractor<? super Request>>
serverSpanNameExtractor) {
builder.setSpanNameExtractor(serverSpanNameExtractor);
return this;
}

/** Returns a new {@link RatpackServerTelemetry} with the configuration of this builder. */
public RatpackServerTelemetry build() {
return new RatpackServerTelemetry(builder.build());
}
}
Loading
Loading