|
23 | 23 | import io.opencensus.common.Duration; |
24 | 24 | import io.opencensus.common.Function; |
25 | 25 | import io.opencensus.common.Functions; |
26 | | -import io.opencensus.common.Scope; |
27 | 26 | import io.opencensus.common.Timestamp; |
| 27 | +import io.opencensus.exporter.trace.util.TimeLimitedHandler; |
28 | 28 | import io.opencensus.trace.AttributeValue; |
29 | | -import io.opencensus.trace.Sampler; |
30 | 29 | import io.opencensus.trace.Span.Kind; |
31 | 30 | import io.opencensus.trace.SpanContext; |
32 | 31 | import io.opencensus.trace.SpanId; |
33 | 32 | import io.opencensus.trace.Status; |
34 | 33 | import io.opencensus.trace.TraceId; |
35 | | -import io.opencensus.trace.Tracer; |
36 | | -import io.opencensus.trace.Tracing; |
37 | 34 | import io.opencensus.trace.export.SpanData; |
38 | | -import io.opencensus.trace.export.SpanExporter; |
39 | | -import io.opencensus.trace.samplers.Samplers; |
| 35 | +import java.io.Closeable; |
40 | 36 | import java.io.IOException; |
41 | 37 | import java.io.InputStream; |
42 | 38 | import java.io.OutputStream; |
|
63 | 59 | * Major TODO is the limitation of Instana to only suport 64bit trace ids, which will be resolved. |
64 | 60 | * Until then it is crossing fingers and treating it as 50% sampler :). |
65 | 61 | */ |
66 | | -final class InstanaExporterHandler extends SpanExporter.Handler { |
| 62 | +final class InstanaExporterHandler extends TimeLimitedHandler { |
67 | 63 |
|
68 | | - private static final Tracer tracer = Tracing.getTracer(); |
69 | | - private static final Sampler probabilitySpampler = Samplers.probabilitySampler(0.0001); |
| 64 | + private static final String EXPORT_SPAN_NAME = "ExportInstanaTraces"; |
70 | 65 | private final URL agentEndpoint; |
71 | 66 |
|
72 | | - InstanaExporterHandler(URL agentEndpoint) { |
| 67 | + InstanaExporterHandler(URL agentEndpoint, Duration deadline) { |
| 68 | + super(deadline, EXPORT_SPAN_NAME); |
73 | 69 | this.agentEndpoint = agentEndpoint; |
74 | 70 | } |
75 | 71 |
|
@@ -180,56 +176,36 @@ static String convertToJson(Collection<SpanData> spanDataList) { |
180 | 176 | } |
181 | 177 |
|
182 | 178 | @Override |
183 | | - public void export(Collection<SpanData> spanDataList) { |
184 | | - // Start a new span with explicit 1/10000 sampling probability to avoid the case when user |
185 | | - // sets the default sampler to always sample and we get the gRPC span of the instana |
186 | | - // export call always sampled and go to an infinite loop. |
187 | | - Scope scope = |
188 | | - tracer.spanBuilder("ExportInstanaTraces").setSampler(probabilitySpampler).startScopedSpan(); |
| 179 | + public void timeLimitedExport(Collection<SpanData> spanDataList) throws Exception { |
| 180 | + String json = convertToJson(spanDataList); |
| 181 | + |
| 182 | + OutputStream outputStream = null; |
| 183 | + InputStream inputStream = null; |
189 | 184 | try { |
190 | | - String json = convertToJson(spanDataList); |
| 185 | + HttpURLConnection connection = (HttpURLConnection) agentEndpoint.openConnection(); |
| 186 | + connection.setRequestMethod("POST"); |
| 187 | + connection.setDoOutput(true); |
| 188 | + outputStream = connection.getOutputStream(); |
| 189 | + outputStream.write(json.getBytes(Charset.defaultCharset())); |
| 190 | + outputStream.flush(); |
| 191 | + inputStream = connection.getInputStream(); |
| 192 | + if (connection.getResponseCode() != 200) { |
| 193 | + throw new Exception("Response " + connection.getResponseCode()); |
| 194 | + } |
| 195 | + } finally { |
| 196 | + closeStream(inputStream); |
| 197 | + closeStream(outputStream); |
| 198 | + } |
| 199 | + } |
191 | 200 |
|
192 | | - OutputStream outputStream = null; |
193 | | - InputStream inputStream = null; |
| 201 | + // Closes an input or output stream and ignores potential IOException. |
| 202 | + private static void closeStream(@javax.annotation.Nullable Closeable stream) { |
| 203 | + if (stream != null) { |
194 | 204 | try { |
195 | | - HttpURLConnection connection = (HttpURLConnection) agentEndpoint.openConnection(); |
196 | | - connection.setRequestMethod("POST"); |
197 | | - connection.setDoOutput(true); |
198 | | - outputStream = connection.getOutputStream(); |
199 | | - outputStream.write(json.getBytes(Charset.defaultCharset())); |
200 | | - outputStream.flush(); |
201 | | - inputStream = connection.getInputStream(); |
202 | | - if (connection.getResponseCode() != 200) { |
203 | | - tracer |
204 | | - .getCurrentSpan() |
205 | | - .setStatus( |
206 | | - Status.UNKNOWN.withDescription("Response " + connection.getResponseCode())); |
207 | | - } |
| 205 | + stream.close(); |
208 | 206 | } catch (IOException e) { |
209 | | - tracer |
210 | | - .getCurrentSpan() |
211 | | - .setStatus( |
212 | | - Status.UNKNOWN.withDescription( |
213 | | - e.getMessage() == null ? e.getClass().getSimpleName() : e.getMessage())); |
214 | | - // dropping span batch |
215 | | - } finally { |
216 | | - if (inputStream != null) { |
217 | | - try { |
218 | | - inputStream.close(); |
219 | | - } catch (IOException e) { |
220 | | - // ignore |
221 | | - } |
222 | | - } |
223 | | - if (outputStream != null) { |
224 | | - try { |
225 | | - outputStream.close(); |
226 | | - } catch (IOException e) { |
227 | | - // ignore |
228 | | - } |
229 | | - } |
| 207 | + // ignore |
230 | 208 | } |
231 | | - } finally { |
232 | | - scope.close(); |
233 | 209 | } |
234 | 210 | } |
235 | 211 | } |
0 commit comments