Skip to content
This repository was archived by the owner on Dec 23, 2023. It is now read-only.

Commit cae2744

Browse files
authored
Exporter/Trace: Refactor to use TimeLimitedHandler. (#1890)
1 parent ab23a9d commit cae2744

11 files changed

Lines changed: 42 additions & 257 deletions

File tree

buildscripts/import-control.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ General guidelines on imports:
224224
</subpackage>
225225
<subpackage name="trace">
226226
<allow pkg="io.opencensus.trace"/>
227+
<allow pkg="io.opencensus.exporter.trace.util"/>
227228
<subpackage name="instana">
228229
<allow pkg="io.opencensus.exporter.trace.instana"/>
229230
</subpackage>

exporters/trace/datadog/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ dependencies {
99
compileOnly libraries.findbugs_annotations
1010

1111
compile project(':opencensus-api'),
12+
project(':opencensus-exporter-trace-util'),
1213
libraries.guava,
1314
libraries.gson,
1415
libraries.auto_value

exporters/trace/datadog/src/main/java/io/opencensus/exporter/trace/datadog/DatadogExporterHandler.java

Lines changed: 6 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,19 @@
1616

1717
package io.opencensus.exporter.trace.datadog;
1818

19-
import com.google.common.util.concurrent.SimpleTimeLimiter;
20-
import com.google.common.util.concurrent.TimeLimiter;
2119
import com.google.gson.FieldNamingPolicy;
2220
import com.google.gson.Gson;
2321
import com.google.gson.GsonBuilder;
2422
import io.opencensus.common.Duration;
2523
import io.opencensus.common.Functions;
26-
import io.opencensus.common.Scope;
2724
import io.opencensus.common.Timestamp;
25+
import io.opencensus.exporter.trace.util.TimeLimitedHandler;
2826
import io.opencensus.trace.AttributeValue;
29-
import io.opencensus.trace.Sampler;
3027
import io.opencensus.trace.SpanContext;
3128
import io.opencensus.trace.SpanId;
3229
import io.opencensus.trace.Status;
33-
import io.opencensus.trace.Tracer;
3430
import io.opencensus.trace.Tracing;
3531
import io.opencensus.trace.export.SpanData;
36-
import io.opencensus.trace.export.SpanExporter;
37-
import io.opencensus.trace.samplers.Samplers;
38-
import java.io.IOException;
3932
import java.io.OutputStream;
4033
import java.net.HttpURLConnection;
4134
import java.net.MalformedURLException;
@@ -47,10 +40,7 @@
4740
import java.util.List;
4841
import java.util.Map;
4942
import java.util.Optional;
50-
import java.util.concurrent.Callable;
51-
import java.util.concurrent.Executors;
5243
import java.util.concurrent.TimeUnit;
53-
import java.util.concurrent.TimeoutException;
5444
import java.util.stream.Collectors;
5545
import javax.annotation.Nullable;
5646

@@ -59,10 +49,9 @@
5949
"AndroidJdkLibsChecker",
6050
"Java7ApiChecker"
6151
})
62-
final class DatadogExporterHandler extends SpanExporter.Handler {
52+
final class DatadogExporterHandler extends TimeLimitedHandler {
6353

64-
private static final Tracer tracer = Tracing.getTracer();
65-
private static final Sampler probabilitySpampler = Samplers.probabilitySampler(0.0001);
54+
private static final String EXPORT_SPAN_NAME = "ExportDatadogTraces";
6655
private static final Gson gson =
6756
new GsonBuilder()
6857
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
@@ -71,14 +60,13 @@ final class DatadogExporterHandler extends SpanExporter.Handler {
7160
private final URL agentEndpoint;
7261
private final String service;
7362
private final String type;
74-
private final Duration deadline;
7563

7664
DatadogExporterHandler(String agentEndpoint, String service, String type, Duration deadline)
7765
throws MalformedURLException {
66+
super(deadline, EXPORT_SPAN_NAME);
7867
this.agentEndpoint = new URL(agentEndpoint);
7968
this.service = service;
8069
this.type = type;
81-
this.deadline = deadline;
8270
}
8371

8472
private static String attributeValueToString(AttributeValue attributeValue) {
@@ -171,32 +159,7 @@ String convertToJson(Collection<SpanData> spanDataList) {
171159
}
172160

173161
@Override
174-
public void export(final Collection<SpanData> spanDataList) {
175-
// Start a new span with explicit 1/10000 sampling probability to avoid the case when user
176-
// sets the default sampler to always sample and we get the gRPC span of the datadog
177-
// export call always sampled and go to an infinite loop.
178-
try (Scope ss =
179-
tracer
180-
.spanBuilder("ExportDatadogTraces")
181-
.setSampler(probabilitySpampler)
182-
.startScopedSpan()) {
183-
TimeLimiter timeLimiter = SimpleTimeLimiter.create(Executors.newSingleThreadExecutor());
184-
timeLimiter.callWithTimeout(
185-
new Callable<Void>() {
186-
@Override
187-
public Void call() throws Exception {
188-
doExport(spanDataList);
189-
return null;
190-
}
191-
},
192-
deadline.toMillis(),
193-
TimeUnit.MILLISECONDS);
194-
} catch (Exception e) {
195-
handleException(e);
196-
}
197-
}
198-
199-
private void doExport(Collection<SpanData> spanDataList) throws IOException {
162+
public void timeLimitedExport(Collection<SpanData> spanDataList) throws Exception {
200163
final String data = convertToJson(spanDataList);
201164

202165
final HttpURLConnection connection = (HttpURLConnection) agentEndpoint.openConnection();
@@ -208,16 +171,7 @@ private void doExport(Collection<SpanData> spanDataList) throws IOException {
208171
outputStream.flush();
209172
outputStream.close();
210173
if (connection.getResponseCode() != 200) {
211-
handleException(new Exception("Response " + connection.getResponseCode()));
174+
throw new Exception("Response " + connection.getResponseCode());
212175
}
213176
}
214-
215-
private static void handleException(Exception e) {
216-
Status status = e instanceof TimeoutException ? Status.DEADLINE_EXCEEDED : Status.UNKNOWN;
217-
tracer
218-
.getCurrentSpan()
219-
.setStatus(
220-
status.withDescription(
221-
e.getMessage() == null ? e.getClass().getSimpleName() : e.getMessage()));
222-
}
223177
}

exporters/trace/elasticsearch/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ dependencies {
1111
compileOnly libraries.auto_value
1212

1313
compile project(':opencensus-api'),
14+
project(':opencensus-exporter-trace-util'),
1415
libraries.guava
1516

1617
testCompile project(':opencensus-api')

exporters/trace/elasticsearch/src/main/java/io/opencensus/exporter/trace/elasticsearch/ElasticsearchTraceHandler.java

Lines changed: 19 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,9 @@
1717
package io.opencensus.exporter.trace.elasticsearch;
1818

1919
import com.google.common.io.BaseEncoding;
20-
import com.google.common.util.concurrent.SimpleTimeLimiter;
21-
import com.google.common.util.concurrent.TimeLimiter;
22-
import io.opencensus.common.Duration;
23-
import io.opencensus.common.Scope;
24-
import io.opencensus.trace.Sampler;
25-
import io.opencensus.trace.Status;
26-
import io.opencensus.trace.Tracer;
27-
import io.opencensus.trace.Tracing;
20+
import io.opencensus.exporter.trace.util.TimeLimitedHandler;
2821
import io.opencensus.trace.export.SpanData;
29-
import io.opencensus.trace.export.SpanExporter;
30-
import io.opencensus.trace.samplers.Samplers;
22+
import java.io.Closeable;
3123
import java.io.IOException;
3224
import java.io.InputStream;
3325
import java.io.OutputStream;
@@ -37,34 +29,28 @@
3729
import java.nio.charset.Charset;
3830
import java.util.Collection;
3931
import java.util.List;
40-
import java.util.concurrent.Callable;
41-
import java.util.concurrent.Executors;
42-
import java.util.concurrent.TimeUnit;
43-
import java.util.concurrent.TimeoutException;
32+
import javax.annotation.Nullable;
4433

45-
final class ElasticsearchTraceHandler extends SpanExporter.Handler {
34+
final class ElasticsearchTraceHandler extends TimeLimitedHandler {
4635

4736
private final ElasticsearchTraceConfiguration elasticsearchTraceConfiguration;
4837
private final String appName;
4938
private final URL indexUrl;
50-
private final Duration deadline;
5139
private static final String CONTENT_TYPE = "application/json";
5240
private static final String REQUEST_METHOD = "POST";
5341
private static final int CONNECTION_TIMEOUT_MILLISECONDS = 6000;
54-
private static final Tracer tracer = Tracing.getTracer();
55-
private static final Sampler probabilitySampler = Samplers.probabilitySampler(0.0001);
42+
private static final String EXPORT_SPAN_NAME = "ExportElasticsearchTraces";
5643

5744
ElasticsearchTraceHandler(ElasticsearchTraceConfiguration elasticsearchTraceConfiguration)
5845
throws MalformedURLException {
59-
46+
super(elasticsearchTraceConfiguration.getDeadline(), EXPORT_SPAN_NAME);
6047
this.elasticsearchTraceConfiguration = elasticsearchTraceConfiguration;
6148
StringBuilder sb = new StringBuilder();
6249
sb.append(elasticsearchTraceConfiguration.getElasticsearchUrl()).append("/");
6350
sb.append(elasticsearchTraceConfiguration.getElasticsearchIndex()).append("/");
6451
sb.append(elasticsearchTraceConfiguration.getElasticsearchType()).append("/");
6552
indexUrl = new URL(sb.toString());
6653
appName = elasticsearchTraceConfiguration.getAppName();
67-
deadline = elasticsearchTraceConfiguration.getDeadline();
6854
}
6955

7056
/**
@@ -73,33 +59,7 @@ final class ElasticsearchTraceHandler extends SpanExporter.Handler {
7359
* @param spanDataList Collection of {@code SpanData} to be exported.
7460
*/
7561
@Override
76-
public void export(final Collection<SpanData> spanDataList) {
77-
Scope scope =
78-
tracer
79-
.spanBuilder("ExportElasticsearchTraces")
80-
.setSampler(probabilitySampler)
81-
.setRecordEvents(true)
82-
.startScopedSpan();
83-
try {
84-
TimeLimiter timeLimiter = SimpleTimeLimiter.create(Executors.newSingleThreadExecutor());
85-
timeLimiter.callWithTimeout(
86-
new Callable<Void>() {
87-
@Override
88-
public Void call() {
89-
doExport(spanDataList);
90-
return null;
91-
}
92-
},
93-
deadline.toMillis(),
94-
TimeUnit.MILLISECONDS);
95-
} catch (Exception e) {
96-
handleException(e);
97-
} finally {
98-
scope.close();
99-
}
100-
}
101-
102-
private void doExport(Collection<SpanData> spanDataList) {
62+
public void timeLimitedExport(Collection<SpanData> spanDataList) throws Exception {
10363
List<String> jsonList = JsonConversionUtils.convertToJson(appName, spanDataList);
10464
if (jsonList.isEmpty()) {
10565
return;
@@ -130,36 +90,23 @@ private void doExport(Collection<SpanData> spanDataList) {
13090
outputStream.flush();
13191
inputStream = connection.getInputStream();
13292
if (connection.getResponseCode() != 200) {
133-
handleException(new Exception("Response " + connection.getResponseCode()));
93+
throw new Exception("Response " + connection.getResponseCode());
13494
}
135-
} catch (IOException e) {
136-
handleException(e);
137-
// dropping span batch
13895
} finally {
139-
if (inputStream != null) {
140-
try {
141-
inputStream.close();
142-
} catch (IOException e) {
143-
// ignore
144-
}
145-
}
146-
if (outputStream != null) {
147-
try {
148-
outputStream.close();
149-
} catch (IOException e) {
150-
// ignore
151-
}
152-
}
96+
closeStream(inputStream);
97+
closeStream(outputStream);
15398
}
15499
}
155100
}
156101

157-
private static void handleException(Exception e) {
158-
Status status = e instanceof TimeoutException ? Status.DEADLINE_EXCEEDED : Status.UNKNOWN;
159-
tracer
160-
.getCurrentSpan()
161-
.setStatus(
162-
status.withDescription(
163-
e.getMessage() == null ? e.getClass().getSimpleName() : e.getMessage()));
102+
// Closes an input or output stream and ignores potential IOException.
103+
private static void closeStream(@Nullable Closeable stream) {
104+
if (stream != null) {
105+
try {
106+
stream.close();
107+
} catch (IOException e) {
108+
// ignore
109+
}
110+
}
164111
}
165112
}

exporters/trace/instana/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ description = 'OpenCensus Trace Instana Exporter'
77

88
dependencies {
99
compile project(':opencensus-api'),
10+
project(':opencensus-exporter-trace-util'),
1011
libraries.guava
1112

1213
signature "org.codehaus.mojo.signature:java17:1.0@signature"

exporters/trace/jaeger/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ dependencies {
99
compileOnly libraries.auto_value
1010

1111
compile project(':opencensus-api'),
12+
project(':opencensus-exporter-trace-util'),
1213
libraries.guava
1314

1415
compile(libraries.jaeger_reporter) {

0 commit comments

Comments
 (0)