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

Commit f68f73b

Browse files
authored
Exporter/Datadog, Elasticsearch: Add deadline option. (#1886)
1 parent ddca5df commit f68f73b

7 files changed

Lines changed: 207 additions & 89 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Monitoring client to make RPCs.
99
with default value 10 seconds.
1010
- Use `ZipkinExporterConfiguration` for creating `ZipkinTraceExporter`. Provide a `Deadline` option
1111
with default value 10 seconds.
12+
- Provide a `Deadline` option to Datadog and Elasticsearch exporter. Default value is 10 seconds.
1213

1314
## 0.21.0 - 2019-04-30
1415
- Add HTTP text format serializer to Tag propagation component.

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

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@
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;
1921
import com.google.gson.FieldNamingPolicy;
2022
import com.google.gson.Gson;
2123
import com.google.gson.GsonBuilder;
24+
import io.opencensus.common.Duration;
2225
import io.opencensus.common.Functions;
2326
import io.opencensus.common.Scope;
2427
import io.opencensus.common.Timestamp;
@@ -44,7 +47,10 @@
4447
import java.util.List;
4548
import java.util.Map;
4649
import java.util.Optional;
50+
import java.util.concurrent.Callable;
51+
import java.util.concurrent.Executors;
4752
import java.util.concurrent.TimeUnit;
53+
import java.util.concurrent.TimeoutException;
4854
import java.util.stream.Collectors;
4955
import javax.annotation.Nullable;
5056

@@ -65,12 +71,14 @@ final class DatadogExporterHandler extends SpanExporter.Handler {
6571
private final URL agentEndpoint;
6672
private final String service;
6773
private final String type;
74+
private final Duration deadline;
6875

69-
DatadogExporterHandler(final String agentEndpoint, final String service, final String type)
76+
DatadogExporterHandler(String agentEndpoint, String service, String type, Duration deadline)
7077
throws MalformedURLException {
7178
this.agentEndpoint = new URL(agentEndpoint);
7279
this.service = service;
7380
this.type = type;
81+
this.deadline = deadline;
7482
}
7583

7684
private static String attributeValueToString(AttributeValue attributeValue) {
@@ -163,7 +171,7 @@ String convertToJson(Collection<SpanData> spanDataList) {
163171
}
164172

165173
@Override
166-
public void export(Collection<SpanData> spanDataList) {
174+
public void export(final Collection<SpanData> spanDataList) {
167175
// Start a new span with explicit 1/10000 sampling probability to avoid the case when user
168176
// sets the default sampler to always sample and we get the gRPC span of the datadog
169177
// export call always sampled and go to an infinite loop.
@@ -172,29 +180,44 @@ public void export(Collection<SpanData> spanDataList) {
172180
.spanBuilder("ExportDatadogTraces")
173181
.setSampler(probabilitySpampler)
174182
.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+
}
175198

176-
final String data = convertToJson(spanDataList);
177-
178-
final HttpURLConnection connection = (HttpURLConnection) agentEndpoint.openConnection();
179-
connection.setRequestMethod("POST");
180-
connection.setRequestProperty("Content-Type", "application/json");
181-
connection.setDoOutput(true);
182-
OutputStream outputStream = connection.getOutputStream();
183-
outputStream.write(data.getBytes(Charset.defaultCharset()));
184-
outputStream.flush();
185-
outputStream.close();
186-
if (connection.getResponseCode() != 200) {
187-
tracer
188-
.getCurrentSpan()
189-
.setStatus(Status.UNKNOWN.withDescription("Response " + connection.getResponseCode()));
190-
}
191-
} catch (IOException e) {
192-
tracer
193-
.getCurrentSpan()
194-
.setStatus(
195-
Status.UNKNOWN.withDescription(
196-
e.getMessage() == null ? e.getClass().getSimpleName() : e.getMessage()));
197-
// drop span batch
199+
private void doExport(Collection<SpanData> spanDataList) throws IOException {
200+
final String data = convertToJson(spanDataList);
201+
202+
final HttpURLConnection connection = (HttpURLConnection) agentEndpoint.openConnection();
203+
connection.setRequestMethod("POST");
204+
connection.setRequestProperty("Content-Type", "application/json");
205+
connection.setDoOutput(true);
206+
OutputStream outputStream = connection.getOutputStream();
207+
outputStream.write(data.getBytes(Charset.defaultCharset()));
208+
outputStream.flush();
209+
outputStream.close();
210+
if (connection.getResponseCode() != 200) {
211+
handleException(new Exception("Response " + connection.getResponseCode()));
198212
}
199213
}
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+
}
200223
}

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

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
package io.opencensus.exporter.trace.datadog;
1818

1919
import com.google.auto.value.AutoValue;
20+
import com.google.common.annotations.VisibleForTesting;
21+
import com.google.common.base.Preconditions;
22+
import io.opencensus.common.Duration;
2023
import javax.annotation.concurrent.Immutable;
2124

2225
/**
@@ -28,6 +31,9 @@
2831
@Immutable
2932
public abstract class DatadogTraceConfiguration {
3033

34+
@VisibleForTesting static final Duration DEFAULT_DEADLINE = Duration.create(10, 0);
35+
@VisibleForTesting static final Duration ZERO = Duration.fromMillis(0);
36+
3137
DatadogTraceConfiguration() {}
3238

3339
/**
@@ -54,14 +60,24 @@ public abstract class DatadogTraceConfiguration {
5460
*/
5561
public abstract String getType();
5662

63+
/**
64+
* Returns the deadline for exporting to Datadog.
65+
*
66+
* <p>Default value is 10 seconds.
67+
*
68+
* @return the export deadline.
69+
* @since 0.22
70+
*/
71+
public abstract Duration getDeadline();
72+
5773
/**
5874
* Return a new {@link Builder}.
5975
*
6076
* @return a {@code Builder}
6177
* @since 0.19
6278
*/
6379
public static Builder builder() {
64-
return new AutoValue_DatadogTraceConfiguration.Builder();
80+
return new AutoValue_DatadogTraceConfiguration.Builder().setDeadline(DEFAULT_DEADLINE);
6581
}
6682

6783
/**
@@ -101,6 +117,28 @@ public abstract static class Builder {
101117
*/
102118
public abstract Builder setType(String type);
103119

104-
public abstract DatadogTraceConfiguration build();
120+
/**
121+
* Sets the deadline for exporting to Datadog.
122+
*
123+
* @param deadline the export deadline.
124+
* @return this
125+
* @since 0.22
126+
*/
127+
public abstract Builder setDeadline(Duration deadline);
128+
129+
abstract Duration getDeadline();
130+
131+
abstract DatadogTraceConfiguration autoBuild();
132+
133+
/**
134+
* Builds a {@link DatadogTraceConfiguration}.
135+
*
136+
* @return a {@code DatadogTraceConfiguration}.
137+
* @since 0.22
138+
*/
139+
public DatadogTraceConfiguration build() {
140+
Preconditions.checkArgument(getDeadline().compareTo(ZERO) > 0, "Deadline must be positive.");
141+
return autoBuild();
142+
}
105143
}
106144
}

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@
3232
* <pre>{@code
3333
* public static void main(String[] args) {
3434
* DatadogTraceConfiguration config = DatadogTraceConfiguration.builder()
35-
* .setAgentEndpoint("http://localhost:8126/v0.3/traces")
36-
* .setService("myService")
37-
* .setType("web")
38-
* .build();
35+
* .setAgentEndpoint("http://localhost:8126/v0.3/traces")
36+
* .setService("myService")
37+
* .setType("web")
38+
* .build();
3939
* DatadogTraceExporter.createAndRegister(config);
4040
* ... // Do work.
4141
* }
@@ -72,7 +72,7 @@ public static void createAndRegister(DatadogTraceConfiguration configuration)
7272
String type = configuration.getType();
7373

7474
final DatadogExporterHandler exporterHandler =
75-
new DatadogExporterHandler(agentEndpoint, service, type);
75+
new DatadogExporterHandler(agentEndpoint, service, type, configuration.getDeadline());
7676
handler = exporterHandler;
7777
Tracing.getExportComponent()
7878
.getSpanExporter()

exporters/trace/datadog/src/test/java/io/opencensus/exporter/trace/datadog/DatadogExporterHandlerTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package io.opencensus.exporter.trace.datadog;
1818

1919
import static com.google.common.truth.Truth.assertThat;
20+
import static io.opencensus.exporter.trace.datadog.DatadogTraceConfiguration.DEFAULT_DEADLINE;
2021

2122
import com.google.common.collect.ImmutableMap;
2223
import io.opencensus.common.Timestamp;
@@ -56,7 +57,8 @@ public class DatadogExporterHandlerTest {
5657

5758
@Before
5859
public void setup() throws Exception {
59-
this.handler = new DatadogExporterHandler("http://localhost", "service", "web");
60+
this.handler =
61+
new DatadogExporterHandler("http://localhost", "service", "web", DEFAULT_DEADLINE);
6062
}
6163

6264
@Test

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

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
package io.opencensus.exporter.trace.elasticsearch;
1818

1919
import com.google.auto.value.AutoValue;
20+
import com.google.common.annotations.VisibleForTesting;
2021
import com.google.common.base.Preconditions;
2122
import com.google.common.base.Strings;
23+
import io.opencensus.common.Duration;
2224
import javax.annotation.Nullable;
2325
import javax.annotation.concurrent.Immutable;
2426

@@ -31,14 +33,17 @@
3133
@Immutable
3234
public abstract class ElasticsearchTraceConfiguration {
3335

36+
@VisibleForTesting static final Duration DEFAULT_DEADLINE = Duration.create(10, 0);
37+
@VisibleForTesting static final Duration ZERO = Duration.fromMillis(0);
38+
3439
/**
3540
* Returns a new {@link Builder}.
3641
*
3742
* @return a {@code Builder}.
3843
* @since 0.20.0
3944
*/
4045
public static Builder builder() {
41-
return new AutoValue_ElasticsearchTraceConfiguration.Builder();
46+
return new AutoValue_ElasticsearchTraceConfiguration.Builder().setDeadline(DEFAULT_DEADLINE);
4247
}
4348

4449
/**
@@ -91,6 +96,16 @@ public static Builder builder() {
9196
*/
9297
public abstract String getElasticsearchType();
9398

99+
/**
100+
* Returns the deadline for exporting to Elasticsearch.
101+
*
102+
* <p>Default value is 10 seconds.
103+
*
104+
* @return the export deadline.
105+
* @since 0.22
106+
*/
107+
public abstract Duration getDeadline();
108+
94109
/**
95110
* Builds a {@link ElasticsearchTraceConfiguration}.
96111
*
@@ -157,6 +172,15 @@ public abstract static class Builder {
157172
*/
158173
public abstract Builder setElasticsearchType(String elasticsearchType);
159174

175+
/**
176+
* Sets the deadline for exporting to Elasticsearch.
177+
*
178+
* @param deadline the export deadline.
179+
* @return this
180+
* @since 0.22
181+
*/
182+
public abstract Builder setDeadline(Duration deadline);
183+
160184
/**
161185
* Builder for {@link ElasticsearchTraceConfiguration}.
162186
*
@@ -174,6 +198,9 @@ public ElasticsearchTraceConfiguration build() {
174198
Preconditions.checkArgument(
175199
!Strings.isNullOrEmpty(elasticsearchTraceConfiguration.getElasticsearchIndex()),
176200
"Invalid Elasticsearch type.");
201+
Preconditions.checkArgument(
202+
elasticsearchTraceConfiguration.getDeadline().compareTo(ZERO) > 0,
203+
"Deadline must be positive.");
177204
return elasticsearchTraceConfiguration;
178205
}
179206
}

0 commit comments

Comments
 (0)