Skip to content

Commit 8e70687

Browse files
authored
Merge pull request #122 from DataDog/tyler/remove-ot-agent-dep
Remove dependency on OpenTracing Agent
2 parents c238b9d + c652aa2 commit 8e70687

7 files changed

Lines changed: 598 additions & 10 deletions

File tree

dd-java-agent/dd-java-agent.gradle

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ dependencies {
2222
transitive = false
2323
}
2424

25-
compile group: 'io.opentracing.contrib', name: 'opentracing-agent', version: '0.1.0'
25+
compile group: 'org.jboss.byteman', name: 'byteman', version: '4.0.0-BETA5'
26+
2627
compile group: 'org.reflections', name: 'reflections', version: '0.9.11'
2728
compile group: 'com.google.auto.service', name: 'auto-service', version: '1.0-rc3'
2829
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25'
@@ -53,9 +54,6 @@ jar {
5354
"Premain-Class": "com.datadoghq.trace.agent.TracingAgent",
5455
"Can-Redefine-Classes": true,
5556
"Can-Retransform-Classes": true,
56-
// It is dangerous putting everything on the bootstrap classpath,
57-
// but kept for consistency with previous versions.
58-
"Boot-Class-Path": "./${jar.archiveName}.jar"
5957
)
6058
}
6159
}

dd-java-agent/integrations/helpers/helpers.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ dependencies {
1111
compileOnly project(':dd-trace-annotations')
1212
compileOnly group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25'
1313

14-
compileOnly group: 'io.opentracing.contrib', name: 'opentracing-agent', version: '0.1.0'
14+
compileOnly group: 'org.jboss.byteman', name: 'byteman', version: '4.0.0-BETA5'
1515

1616
compile group: 'io.opentracing.contrib', name: 'opentracing-web-servlet-filter', version: '0.0.9'
1717
compile group: 'io.opentracing.contrib', name: 'opentracing-mongo-driver', version: '0.0.3'

dd-java-agent/integrations/helpers/src/main/java/com/datadoghq/trace/agent/integration/DDAgentTracingHelper.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import io.opentracing.NoopTracerFactory;
44
import io.opentracing.Tracer;
5-
import io.opentracing.contrib.agent.OpenTracingHelper;
65
import lombok.extern.slf4j.Slf4j;
76
import org.jboss.byteman.rule.Rule;
87

Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
/*
2+
* Copyright 2017 Red Hat, Inc. and/or its affiliates
3+
* and other contributors as indicated by the @author tags.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package com.datadoghq.trace.agent.integration;
18+
19+
import io.opentracing.ActiveSpan;
20+
import io.opentracing.BaseSpan;
21+
import io.opentracing.Span;
22+
import io.opentracing.SpanContext;
23+
import io.opentracing.Tracer;
24+
import io.opentracing.Tracer.SpanBuilder;
25+
import io.opentracing.contrib.tracerresolver.TracerResolver;
26+
import io.opentracing.propagation.Format;
27+
import io.opentracing.util.GlobalTracer;
28+
import java.net.HttpURLConnection;
29+
import java.util.Collections;
30+
import java.util.Map;
31+
import java.util.WeakHashMap;
32+
import java.util.logging.Level;
33+
import java.util.logging.Logger;
34+
import org.jboss.byteman.rule.Rule;
35+
import org.jboss.byteman.rule.helper.Helper;
36+
37+
/** This class provides helper capabilities to the byteman rules. */
38+
public class OpenTracingHelper extends Helper {
39+
40+
private static final Logger log = Logger.getLogger(OpenTracingHelper.class.getName());
41+
42+
private static Tracer tracer;
43+
44+
private static final Map<Object, Span> spanAssociations =
45+
Collections.synchronizedMap(new WeakHashMap<Object, Span>());
46+
private static final Map<Object, Span> finished =
47+
Collections.synchronizedMap(new WeakHashMap<Object, Span>());
48+
49+
private static final Map<Object, Integer> state =
50+
Collections.synchronizedMap(new WeakHashMap<Object, Integer>());
51+
52+
private static final Object SYNC = new Object();
53+
54+
public OpenTracingHelper(Rule rule) {
55+
super(rule);
56+
}
57+
58+
/**
59+
* This method returns the OpenTracing tracer.
60+
*
61+
* @return The tracer
62+
*/
63+
public Tracer getTracer() {
64+
if (tracer == null) {
65+
// Initialize on first use
66+
initTracer();
67+
}
68+
return tracer;
69+
}
70+
71+
protected void initTracer() {
72+
synchronized (SYNC) {
73+
if (tracer == null) {
74+
if (!GlobalTracer.isRegistered()) {
75+
// Try to obtain a tracer using the TracerResolver
76+
Tracer resolved = TracerResolver.resolveTracer();
77+
if (resolved != null) {
78+
try {
79+
GlobalTracer.register(resolved);
80+
} catch (RuntimeException re) {
81+
log.log(Level.WARNING, "Failed to register tracer '" + resolved + "'", re);
82+
}
83+
}
84+
}
85+
// Initialize the tracer even if one has not been registered
86+
// (i.e. it will use a NoopTracer under the covers)
87+
tracer = new AgentTracer(GlobalTracer.get());
88+
}
89+
}
90+
}
91+
92+
/**
93+
* This method establishes an association between an application object (i.e. the subject of the
94+
* instrumentation) and a span. Once the application object is no longer being used, the
95+
* association with the span will automatically be discarded.
96+
*
97+
* @param obj The application object to be associated with the span
98+
* @param span The span
99+
*/
100+
public void associateSpan(Object obj, Span span) {
101+
spanAssociations.put(obj, span);
102+
}
103+
104+
/**
105+
* This method retrieves the span associated with the supplied application object.
106+
*
107+
* @param obj The application object
108+
* @return The span, or null if no associated span exists
109+
*/
110+
public Span retrieveSpan(Object obj) {
111+
return spanAssociations.get(obj);
112+
}
113+
114+
/** ******************************************* */
115+
/** Needs to be replaced by span.isFinished() */
116+
public void finishedSpan(Object key, Span span) {
117+
finished.put(key, span);
118+
}
119+
120+
public boolean isFinished(Object key) {
121+
return finished.containsKey(key);
122+
}
123+
/** ******************************************* */
124+
125+
/**
126+
* This method enables an instrumentation rule to record a 'state' number against an application
127+
* object. This can be used in situations where rules are only applicable in certain states. For
128+
* example, the simple case for rules responsible for installing filters would be states
129+
* representing NOT_INSTALLED and INSTALLED. This means that the filter would only be installed if
130+
* the application object (target of the instrumentation rule) was in the NOT_INSTALLED state.
131+
* However other more complex scenarios may be encountered where more than two states are
132+
* required.
133+
*
134+
* @param obj The application object
135+
* @param value The state value
136+
*/
137+
public void setState(Object obj, int value) {
138+
state.put(obj, new Integer(value));
139+
}
140+
141+
/**
142+
* This method retrieves the current 'state' number associated with the supplied application
143+
* object.
144+
*
145+
* @param obj The application object
146+
* @return The state, or 0 if no state currently exists
147+
*/
148+
public int getState(Object obj) {
149+
Integer value = state.get(obj);
150+
return value == null ? 0 : value.intValue();
151+
}
152+
153+
/**
154+
* This method determines whether the instrumentation point, associated with the supplied object,
155+
* should be ignored.
156+
*
157+
* @param obj The instrumentation target
158+
* @return Whether the instrumentation point should be ignored
159+
*/
160+
public boolean ignore(Object obj) {
161+
boolean ignore = false;
162+
163+
if (obj instanceof HttpURLConnection) {
164+
String value = ((HttpURLConnection) obj).getRequestProperty("opentracing.ignore");
165+
ignore = value != null && value.equalsIgnoreCase("true");
166+
}
167+
168+
// TODO: If other technologies need to use this feature,
169+
// then create an Adapter to wrap the specifics of each
170+
// technology and provide access to their properties
171+
172+
if (ignore && log.isLoggable(Level.FINEST)) {
173+
log.finest("Ignoring request because the property [opentracing.ignore] is present.");
174+
}
175+
176+
return ignore;
177+
}
178+
179+
/**
180+
* Proxy tracer used for one purpose - to enable the rules to define a ChildOf relationship
181+
* without being concerned whether the supplied Span is null. If the spec (and Tracer
182+
* implementations) are updated to indicate a null should be ignored, then this proxy can be
183+
* removed.
184+
*/
185+
public static class AgentTracer implements Tracer {
186+
187+
private Tracer tracer;
188+
189+
public AgentTracer(Tracer tracer) {
190+
this.tracer = tracer;
191+
}
192+
193+
@Override
194+
public SpanBuilder buildSpan(String operation) {
195+
return new AgentSpanBuilder(tracer.buildSpan(operation));
196+
}
197+
198+
@Override
199+
public <C> SpanContext extract(Format<C> format, C carrier) {
200+
return tracer.extract(format, carrier);
201+
}
202+
203+
@Override
204+
public <C> void inject(SpanContext ctx, Format<C> format, C carrier) {
205+
tracer.inject(ctx, format, carrier);
206+
}
207+
208+
@Override
209+
public ActiveSpan activeSpan() {
210+
return tracer.activeSpan();
211+
}
212+
213+
@Override
214+
public ActiveSpan makeActive(Span span) {
215+
return tracer.makeActive(span);
216+
}
217+
}
218+
219+
public static class AgentSpanBuilder implements SpanBuilder {
220+
221+
private SpanBuilder spanBuilder;
222+
223+
public AgentSpanBuilder(SpanBuilder spanBuilder) {
224+
this.spanBuilder = spanBuilder;
225+
}
226+
227+
@Override
228+
public SpanBuilder addReference(String type, SpanContext ctx) {
229+
if (ctx != null) {
230+
spanBuilder.addReference(type, ctx);
231+
}
232+
return this;
233+
}
234+
235+
@Override
236+
public SpanBuilder asChildOf(SpanContext ctx) {
237+
if (ctx != null) {
238+
spanBuilder.asChildOf(ctx);
239+
}
240+
return this;
241+
}
242+
243+
@Override
244+
public SpanBuilder asChildOf(BaseSpan<?> span) {
245+
if (span != null) {
246+
spanBuilder.asChildOf(span);
247+
}
248+
return this;
249+
}
250+
251+
@Override
252+
public Span start() {
253+
return spanBuilder.start();
254+
}
255+
256+
@Override
257+
public SpanBuilder withStartTimestamp(long ts) {
258+
spanBuilder.withStartTimestamp(ts);
259+
return this;
260+
}
261+
262+
@Override
263+
public SpanBuilder withTag(String name, String value) {
264+
spanBuilder.withTag(name, value);
265+
return this;
266+
}
267+
268+
@Override
269+
public SpanBuilder withTag(String name, boolean value) {
270+
spanBuilder.withTag(name, value);
271+
return this;
272+
}
273+
274+
@Override
275+
public SpanBuilder withTag(String name, Number value) {
276+
spanBuilder.withTag(name, value);
277+
return this;
278+
}
279+
280+
@Override
281+
public SpanBuilder ignoreActiveSpan() {
282+
spanBuilder.ignoreActiveSpan();
283+
return this;
284+
}
285+
286+
@Override
287+
public ActiveSpan startActive() {
288+
return spanBuilder.startActive();
289+
}
290+
291+
@Override
292+
public Span startManual() {
293+
return spanBuilder.startManual();
294+
}
295+
}
296+
}

0 commit comments

Comments
 (0)