io.opentelemetry.exporter.zipkin.ZipkinSpanExporter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of opentelemetry-exporter-zipkin Show documentation
Show all versions of opentelemetry-exporter-zipkin Show documentation
OpenTelemetry - Zipkin Exporter
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.exporter.zipkin;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.exporter.internal.ExporterMetrics;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.internal.ThrottlingLogger;
import io.opentelemetry.sdk.trace.data.SpanData;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;
import zipkin2.Span;
import zipkin2.reporter.BytesEncoder;
import zipkin2.reporter.BytesMessageSender;
import zipkin2.reporter.Encoding;
/**
* This class was based on the OpenCensus
* zipkin exporter code.
*/
public final class ZipkinSpanExporter implements SpanExporter {
public static final Logger baseLogger = Logger.getLogger(ZipkinSpanExporter.class.getName());
public static final String DEFAULT_ENDPOINT = "http://localhost:9411/api/v2/spans";
private final ThrottlingLogger logger = new ThrottlingLogger(baseLogger);
private final AtomicBoolean isShutdown = new AtomicBoolean();
private final ZipkinSpanExporterBuilder builder;
private final BytesEncoder encoder;
private final BytesMessageSender sender;
private final ExporterMetrics exporterMetrics;
private final OtelToZipkinSpanTransformer transformer;
ZipkinSpanExporter(
ZipkinSpanExporterBuilder builder,
BytesEncoder encoder,
BytesMessageSender sender,
Supplier meterProviderSupplier,
OtelToZipkinSpanTransformer transformer) {
this.builder = builder;
this.encoder = encoder;
this.sender = sender;
this.exporterMetrics =
sender.encoding() == Encoding.JSON
? ExporterMetrics.createHttpJson("zipkin", "span", meterProviderSupplier)
: ExporterMetrics.createHttpProtobuf("zipkin", "span", meterProviderSupplier);
this.transformer = transformer;
}
@Override
public CompletableResultCode export(Collection spanDataList) {
if (isShutdown.get()) {
return CompletableResultCode.ofFailure();
}
int numItems = spanDataList.size();
exporterMetrics.addSeen(numItems);
List encodedSpans = new ArrayList<>(numItems);
for (SpanData spanData : spanDataList) {
Span zipkinSpan = transformer.generateSpan(spanData);
encodedSpans.add(encoder.encode(zipkinSpan));
}
try {
sender.send(encodedSpans);
exporterMetrics.addSuccess(numItems);
return CompletableResultCode.ofSuccess();
} catch (IOException | RuntimeException t) {
exporterMetrics.addFailed(numItems);
logger.log(Level.WARNING, "Failed to export spans", t);
return CompletableResultCode.ofFailure();
}
}
@Override
public CompletableResultCode flush() {
// nothing required here
return CompletableResultCode.ofSuccess();
}
@Override
public CompletableResultCode shutdown() {
if (!isShutdown.compareAndSet(false, true)) {
logger.log(Level.INFO, "Calling shutdown() multiple times.");
return CompletableResultCode.ofSuccess();
}
try {
sender.close();
} catch (IOException e) {
logger.log(Level.WARNING, "Exception while closing the Zipkin Sender instance", e);
}
return CompletableResultCode.ofSuccess();
}
@Override
public String toString() {
return "ZipkinSpanExporter{" + builder.toString(false) + "}";
}
/**
* Returns a new Builder for {@link ZipkinSpanExporter}.
*
* @return a new {@link ZipkinSpanExporter}.
*/
public static ZipkinSpanExporterBuilder builder() {
return new ZipkinSpanExporterBuilder();
}
}