Skip to content

Commit

Permalink
Add vertx-based exporters
Browse files Browse the repository at this point in the history
  • Loading branch information
jasondlee authored Dec 2, 2023
1 parent 4914577 commit e1a7795
Show file tree
Hide file tree
Showing 11 changed files with 1,000 additions and 0 deletions.
92 changes: 92 additions & 0 deletions implementation/exporters/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.smallrye.opentelemetry</groupId>
<artifactId>smallrye-opentelemetry-parent</artifactId>
<version>2.5.2-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

<artifactId>smallrye-opentelemetry-exporters</artifactId>
<name>SmallRye OpenTelemetry: Exporters</name>

<dependencies>
<dependency>
<groupId>io.smallrye.opentelemetry</groupId>
<artifactId>smallrye-opentelemetry-api</artifactId>
</dependency>
<dependency>
<groupId>io.smallrye.config</groupId>
<artifactId>smallrye-config</artifactId>
</dependency>

<dependency>
<groupId>jakarta.enterprise</groupId>
<artifactId>jakarta.enterprise.cdi-api</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-common</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-grpc-client</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp-common</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp</artifactId>
</dependency>

<!-- Test Dependencies -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-junit5</artifactId>
<exclusions>
<exclusion>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.smallrye.config</groupId>
<artifactId>smallrye-config</artifactId>
</dependency>
<dependency>
<groupId>io.smallrye.opentelemetry</groupId>
<artifactId>smallrye-opentelemetry-config</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>${version.testcontainers}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.smallrye.opentelemetry</groupId>
<artifactId>smallrye-opentelemetry-cdi</artifactId>
<scope>test</scope>
</dependency>

</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.smallrye.opentelemetry.implementation.exporters;

import java.io.IOException;
import java.io.OutputStream;

import io.vertx.core.buffer.Buffer;

final class BufferOutputStream extends OutputStream {

private final Buffer buffer;

public BufferOutputStream(Buffer buffer) {
this.buffer = buffer;
}

@Override
public void write(byte[] b, int off, int len) throws IOException {
buffer.appendBytes(b, off, len);
}

@Override
public void write(int b) throws IOException {
buffer.appendInt(b);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package io.smallrye.opentelemetry.implementation.exporters;

import java.net.URI;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent;

final class OtlpExporterUtil {
static final String OTEL_EXPORTER_OTLP_ENDPOINT = "otel.exporter.otlp.endpoint";
static final String OTEL_EXPORTER_OTLP_PROTOCOL = "otel.exporter.otlp.protocol";
static final String OTEL_EXPORTER_OTLP_TIMEOUT = "otel.exporter.otlp.timeout";
static final String OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = "otel.exporter.otlp.traces.endpoint";
static final String OTEL_EXPORTER_OTLP_TRACES_PROTOCOL = "otel.exporter.otlp.traces.protocol";
static final String PROTOCOL_GRPC = "grpc";
static final String PROTOCOL_HTTP_PROTOBUF = "http/protobuf";

private OtlpExporterUtil() {
}

static int getPort(URI uri) {
int originalPort = uri.getPort();
if (originalPort > -1) {
return originalPort;
}

if (isHttps(uri)) {
return 443;
}
return 80;
}

public static Map<String, String> populateTracingExportHttpHeaders() {
Map<String, String> headersMap = new HashMap<>();
OtlpUserAgent.addUserAgentHeader(headersMap::put);
return headersMap;
}

static boolean isHttps(URI uri) {
return "https".equals(uri.getScheme().toLowerCase(Locale.ROOT));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package io.smallrye.opentelemetry.implementation.exporters;

import static io.smallrye.opentelemetry.implementation.exporters.OtlpExporterUtil.OTEL_EXPORTER_OTLP_PROTOCOL;
import static io.smallrye.opentelemetry.implementation.exporters.OtlpExporterUtil.OTEL_EXPORTER_OTLP_TIMEOUT;
import static io.smallrye.opentelemetry.implementation.exporters.OtlpExporterUtil.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL;
import static io.smallrye.opentelemetry.implementation.exporters.OtlpExporterUtil.PROTOCOL_GRPC;
import static io.smallrye.opentelemetry.implementation.exporters.OtlpExporterUtil.PROTOCOL_HTTP_PROTOBUF;

import java.net.URI;
import java.net.URISyntaxException;
import java.time.Duration;

import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.exporter.internal.http.HttpExporter;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import io.vertx.core.Vertx;

public class VertxExporterProvider implements ConfigurableSpanExporterProvider {

protected static final String EXPORTER_NAME = "otlp";
protected static final String OTLP_GRPC_ENDPOINT = "http://localhost:4317";
protected static final String OTLP_HTTP_PROTOBUF_ENDPOINT = "http://localhost:4318";

@Override
public SpanExporter createExporter(final ConfigProperties config) {
try {
final String otlpProtocol = config.getString(OTEL_EXPORTER_OTLP_TRACES_PROTOCOL,
config.getString(OTEL_EXPORTER_OTLP_PROTOCOL, PROTOCOL_GRPC));

switch (otlpProtocol) {
case PROTOCOL_GRPC:
return new VertxGrpcExporter(
EXPORTER_NAME, // use the same as OTel does
"span", // use the same as OTel does
MeterProvider::noop,
new URI(getOtlpEndpoint(config, OTLP_GRPC_ENDPOINT)),
true,
config.getDuration(OTEL_EXPORTER_OTLP_TIMEOUT, Duration.ofSeconds(10)),
OtlpExporterUtil.populateTracingExportHttpHeaders(),
Vertx.vertx());
case PROTOCOL_HTTP_PROTOBUF:
return new VertxHttpExporter(
new HttpExporter<>(
EXPORTER_NAME, // use the same as OTel does
"span", // use the same as OTel does
new VertxHttpExporter.VertxHttpSender(
new URI(getOtlpEndpoint(config, OTLP_HTTP_PROTOBUF_ENDPOINT)),
true,
config.getDuration(OTEL_EXPORTER_OTLP_TIMEOUT, Duration.ofSeconds(10)),
OtlpExporterUtil.populateTracingExportHttpHeaders(),
"application/x-protobuf",
Vertx.vertx()),
MeterProvider::noop,
false));
default:
throw new RuntimeException("Unsupported OTLP protocol: " + otlpProtocol);
}
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}

@Override
public String getName() {
// Using the same name as the OpenTelemetry SDK ("otlp") allows us to override its definition, providing our
// Vertx-based exporters without any additional changes to the user's application.
return EXPORTER_NAME;
}

/**
* Gets the OTLP traces endpoint, if defined. If it is not, it returns the OTLP endpoint. If that is not defined,
* it returns defaultEndpoint.
*
* @param config
* @param defaultEndpoint The default endpoint for the desired protocol
* @return
*/
private static String getOtlpEndpoint(ConfigProperties config, String defaultEndpoint) {
return config.getString(OtlpExporterUtil.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
config.getString(OtlpExporterUtil.OTEL_EXPORTER_OTLP_ENDPOINT, defaultEndpoint));
}
}
Loading

0 comments on commit e1a7795

Please sign in to comment.