| title | Trace exporter | ||
|---|---|---|---|
| draft | false | ||
| weight | 3 | ||
| aliases |
|
A trace exporter must extend the abstract class SpanExporter.Handler implementing the export method
which for purposes of brevity is:
import java.util.Collection;
import io.opencensus.trace.export.SpanData;
public void export(Collection<SpanData> spanDataList);The sole method export will be used to process and translate a collection of SpanData to your desired trace backend's data.
After an exporter is created, it must be registered with SpanExporter.registerHandler
SpanExporter.registerHandler(nameOfTheExporter, anInstanceOfTheExporter);For example, let's make a custom trace exporter that will print span data to standard output.
Inside file src/main/java/oc/tutorials/CustomTraceExporter.java we'll write the following code
package oc.tutorials;
import java.util.Collection;
import io.opencensus.trace.SpanContext;
import io.opencensus.trace.Tracing;
import io.opencensus.trace.export.SpanData;
import io.opencensus.trace.export.SpanExporter;
public class CustomTraceExporter extends SpanExporter.Handler {
@Override
public void export(Collection<SpanData> spanDataList) {
for (SpanData sd : spanDataList) {
SpanContext sc = sd.getContext();
System.out.println(String.format(
"Name: %s\nTraceID: %s\nSpanID: %s\nParentSpanID: %s\nStartTime: %d\nEndTime: %d\nAnnotations: %s\n\n",
sd.getName(), sc.getTraceId(), sc.getSpanId(), sd.getParentSpanId(),
sd.getStartTimestamp().getSeconds(), sd.getEndTimestamp().getSeconds(), sd.getAnnotations()));
}
}
public static void createAndRegister() {
// Please remember to register your exporter
// so that it can receive exportered spanData.
Tracing.getExportComponent().getSpanExporter().registerHandler(CustomTraceExporter.class.getName(), new CustomTraceExporter());
}
}With the previous implementation, here is a fully runnable example, that we'll run using Maven.
{{}} {{}} package oc.tutorials;
import java.util.Collection;
import io.opencensus.common.Scope; import io.opencensus.trace.Span; import io.opencensus.trace.SpanContext; import io.opencensus.trace.Tracer; import io.opencensus.trace.Tracing; import io.opencensus.trace.config.TraceConfig; import io.opencensus.trace.export.SpanData; import io.opencensus.trace.export.SpanExporter; import io.opencensus.trace.samplers.Samplers;
public class CustomTraceExporter extends SpanExporter.Handler { private static Tracer tracer = Tracing.getTracer();
public static void main(String ...args) {
// Firstly create and register the exporter
CustomTraceExporter.createAndRegister();
// For demo purposes, we'll always sample
TraceConfig traceConfig = Tracing.getTraceConfig();
traceConfig.updateActiveTraceParams(
traceConfig.getActiveTraceParams().toBuilder().setSampler(Samplers.alwaysSample()).build());
// Do some work
for (int i = 0; i < 5; i++) {
String name = String.format("sample-%d", i);
Scope ss = tracer.spanBuilder(name).startScopedSpan();
tracer.getCurrentSpan().addAnnotation("This annotation is for " + name);
sleep(200); // Sleep for 200 milliseconds
ss.close();
}
sleep(8000); // Sleep for 8 seconds to give exporting time to complete
System.exit(0);
}
@Override
public void export(Collection<SpanData> spanDataList) {
for (SpanData sd : spanDataList) {
SpanContext sc = sd.getContext();
System.out.println(String.format(
"Name: %s\nTraceID: %s\nSpanID: %s\nParentSpanID: %s\nStartTime: %d\nEndTime: %d\nAnnotations: %s\n\n",
sd.getName(), sc.getTraceId(), sc.getSpanId(), sd.getParentSpanId(),
sd.getStartTimestamp().getSeconds(), sd.getEndTimestamp().getSeconds(), sd.getAnnotations()));
}
}
public static void createAndRegister() {
// Please remember to register your exporter
// so that it can receive exportered spanData.
Tracing.getExportComponent().getSpanExporter().registerHandler(CustomTraceExporter.class.getName(), new CustomTraceExporter());
}
private static void sleep(int ms) {
// A helper to avoid try-catch when invoking Thread.sleep so that
// sleeps can be succinct and not permeated by exception handling.
try {
Thread.sleep(ms);
} catch(Exception e) {
System.err.println(String.format("Failed to sleep for %dms. Exception: %s", ms, e));
}
}
} {{}}
{{}} 4.0.0 oc.tutorial tracetutorial jar 1.0-SNAPSHOT quickstart http://maven.apache.org
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<opencensus.version>0.17.0</opencensus.version> <!-- The OpenCensus version to use -->
</properties>
<dependencies>
<dependency>
<groupId>io.opencensus</groupId>
<artifactId>opencensus-api</artifactId>
<version>${opencensus.version}</version>
</dependency>
<dependency>
<groupId>io.opencensus</groupId>
<artifactId>opencensus-impl</artifactId>
<version>${opencensus.version}</version>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.5.0.Final</version>
</extension>
</extensions>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.10</version>
<configuration>
<programs>
<program>
<id>CustomTraceExporter</id>
<mainClass>oc.tutorials.CustomTraceExporter</mainClass>
</program>
</programs>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
will print out something like this
$ mvn exec:java -Dexec.mainClass=oc.tutorials.CustomTraceExporter
Name: sample-0
TraceID: TraceId{traceId=1cdffe16132f7682f94b1777da7b41c7}
SpanID: SpanId{spanId=e7c7c30546527d21}
ParentSpanID: null
StartTime: 1533768923
EndTime: 1533768923
Annotations: TimedEvents{events=[TimedEvent{timestamp=Timestamp{seconds=1533768923, nanos=227544959}, event=Annotation{description=This annotation is for sample-0, attributes={}}}], droppedEventsCount=0}
Name: sample-1
TraceID: TraceId{traceId=3c4af55e485cd5b6bc8b2c45042f0458}
SpanID: SpanId{spanId=1e9a9ebe862f1a05}
ParentSpanID: null
StartTime: 1533768923
EndTime: 1533768923
Annotations: TimedEvents{events=[TimedEvent{timestamp=Timestamp{seconds=1533768923, nanos=431021767}, event=Annotation{description=This annotation is for sample-1, attributes={}}}], droppedEventsCount=0}
Name: sample-2
TraceID: TraceId{traceId=e20a916fed0ce71e9645f2ee1dde6cfd}
SpanID: SpanId{spanId=2ce49605d29994c1}
ParentSpanID: null
StartTime: 1533768923
EndTime: 1533768923
Annotations: TimedEvents{events=[TimedEvent{timestamp=Timestamp{seconds=1533768923, nanos=633038726}, event=Annotation{description=This annotation is for sample-2, attributes={}}}], droppedEventsCount=0}
Name: sample-3
TraceID: TraceId{traceId=1dbb12d52d7d03a75c5a28612bd46b30}
SpanID: SpanId{spanId=dfad460a90b67623}
ParentSpanID: null
StartTime: 1533768923
EndTime: 1533768924
Annotations: TimedEvents{events=[TimedEvent{timestamp=Timestamp{seconds=1533768923, nanos=833034459}, event=Annotation{description=This annotation is for sample-3, attributes={}}}], droppedEventsCount=0}
Name: sample-4
TraceID: TraceId{traceId=4991fe623a155ef9913bd5e9dc8f1ee8}
SpanID: SpanId{spanId=a2d301f9e8f0cbc8}
ParentSpanID: null
StartTime: 1533768924
EndTime: 1533768924
Annotations: TimedEvents{events=[TimedEvent{timestamp=Timestamp{seconds=1533768924, nanos=34021598}, event=Annotation{description=This annotation is for sample-4, attributes={}}}], droppedEventsCount=0}
-
Please remember to invoke SpanExporter.registerHandler for your created Trace exporter lest it won't receive exported span data
-
Your exporter's
exportmethod will receive exported span data only for spans that have been ended
| Name | Link |
|---|---|
| Trace JavaDoc | io.opencensus.trace.* |
| OpenCensus JavaDoc | io.opencensus.* |
| OpenCensus Java exporters | Some OpenCensus Java exporters |