Skip to content

Commit

Permalink
TEIIDTOOLS-437 initial opentracing commit
Browse files Browse the repository at this point in the history
  • Loading branch information
shawkins committed Jun 25, 2018
1 parent 0999875 commit c461fb1
Show file tree
Hide file tree
Showing 24 changed files with 779 additions and 20 deletions.
6 changes: 4 additions & 2 deletions api/src/main/java/org/teiid/logging/LogManager.java
Expand Up @@ -374,14 +374,16 @@ public static void log(int msgLevel, String context, Throwable e, Object... mess
logListener.log(msgLevel, context, e, message);
}

public static void setLogListener(Logger listener) {
logListener.shutdown();
public static Logger setLogListener(Logger listener) {
Logger old = logListener;
logListener.shutdown();
if (listener != null) {
logListener = listener;
}
else {
logListener = new JavaLogger();
}
return old;
}

/**
Expand Down
24 changes: 24 additions & 0 deletions client/pom.xml
Expand Up @@ -67,6 +67,30 @@
<dependency>
<groupId>org.jboss.modules</groupId>
<artifactId>jboss-modules</artifactId>
</dependency>
<dependency>
<groupId>io.opentracing.contrib</groupId>
<artifactId>opentracing-concurrent</artifactId>
</dependency>

<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-api</artifactId>
</dependency>

<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-noop</artifactId>
</dependency>

<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-util</artifactId>
</dependency>
<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-mock</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
26 changes: 26 additions & 0 deletions client/src/main/java/org/teiid/client/RequestMessage.java
Expand Up @@ -27,7 +27,9 @@
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.teiid.core.TeiidProcessingException;
import org.teiid.core.util.ExternalizeUtil;
Expand All @@ -40,6 +42,8 @@
*/
public class RequestMessage implements Externalizable {

private static final String SPAN_CONTEXT = "spanContext"; //$NON-NLS-1$

private static final RequestOptions DEFAULT_REQUEST_OPTIONS = new RequestOptions();

public static final int DEFAULT_FETCH_SIZE = 2048;
Expand Down Expand Up @@ -98,6 +102,8 @@ public enum ShowPlan {
private boolean sync;
private RequestOptions requestOptions;
private Object command;

private Map<String, String> properties;

public RequestMessage() {
}
Expand Down Expand Up @@ -370,6 +376,7 @@ public void readExternal(ObjectInput in) throws IOException,
this.autoGeneratedKeys = (options & 1) == 1;
//8.4 property
this.delaySerialization = (options & 2) == 2;
this.properties = ExternalizeUtil.readMap(in);
} catch (OptionalDataException e) {
} catch (EOFException e) {
}
Expand Down Expand Up @@ -405,6 +412,7 @@ public void writeExternal(ObjectOutput out) throws IOException {
options |= 2;
}
out.writeByte(options);
ExternalizeUtil.writeMap(out, properties);
}

public RequestOptions getRequestOptions() {
Expand Down Expand Up @@ -433,5 +441,23 @@ public boolean isDelaySerialization() {
public void setDelaySerialization(boolean delaySerialization) {
this.delaySerialization = delaySerialization;
}

public void setSpanContext(String string) {
if (this.properties == null) {
this.properties = new HashMap<String, String>();
}
if (string == null) {
this.properties.remove(SPAN_CONTEXT);
} else {
properties.put(SPAN_CONTEXT, string);
}
}

public String getSpanContext() {
if (this.properties == null) {
return null;
}
return this.properties.get(SPAN_CONTEXT);
}

}
7 changes: 7 additions & 0 deletions client/src/main/java/org/teiid/jdbc/StatementImpl.java
Expand Up @@ -55,6 +55,7 @@
import org.teiid.core.util.SqlUtil;
import org.teiid.core.util.StringUtil;
import org.teiid.jdbc.EnhancedTimer.Task;
import org.teiid.jdbc.tracing.TracingHelper;
import org.teiid.net.TeiidURL;


Expand Down Expand Up @@ -548,6 +549,12 @@ public void onCompletion(ResultsFuture future) {
final RequestMessage reqMessage = createRequestMessage(commands, isBatchedCommand, resultsMode);
reqMessage.setReturnAutoGeneratedKeys(autoGenerateKeys);
reqMessage.setRequestOptions(options);
if (this.driverConnection.getServerConnection() != null && !this.driverConnection.getServerConnection().isLocal()) {
String spanContext = TracingHelper.getSpanContext();
if (spanContext != null) {
reqMessage.setSpanContext(spanContext);
}
}
ResultsFuture<ResultsMessage> pendingResult = execute(reqMessage, synch);
final ResultsFuture<Boolean> result = new ResultsFuture<Boolean>();
pendingResult.addCompletionListener(new ResultsFuture.CompletionListener<ResultsMessage>() {
Expand Down
@@ -0,0 +1,83 @@
/*
* Copyright Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags and
* the COPYRIGHT.txt file distributed with this work.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.teiid.jdbc.tracing;

import java.util.HashMap;
import java.util.Map;

import org.teiid.jdbc.tracing.TracingHelper.Injector;

import io.opentracing.Span;
import io.opentracing.Tracer;
import io.opentracing.propagation.Format.Builtin;
import io.opentracing.propagation.TextMapInjectAdapter;
import io.opentracing.util.GlobalTracer;

/**
* Uses the opentracing library to create a json string representation of the span context
* and provides a way to manipulate a static tracer without using the GlobalTracer registration
*/
public class GlobalTracerInjector implements Injector {

private static Tracer TRACER = GlobalTracer.get();

@Override
public String getSpanContext() {
return getSpanContext(TRACER);
}

protected static String getSpanContext(Tracer tracer) {
Span span = tracer.activeSpan();
if (span == null) {
return null;
}
Map<String,String> spanMap = new HashMap<String, String>();
tracer.inject(span.context(), Builtin.TEXT_MAP, new TextMapInjectAdapter(spanMap));

//simple json creation
StringBuilder json = new StringBuilder();
json.append('{');
boolean first = true;
for (Map.Entry<String, String> entry : spanMap.entrySet()) {
if (!first) {
json.append(',');
} else {
first = false;
}
json.append('"').append(entry.getKey().replace("\"", "\\\"")) //$NON-NLS-1$ //$NON-NLS-2$
.append("\":\"") //$NON-NLS-1$
.append(entry.getValue().replace("\"", "\\\"")).append('"'); //$NON-NLS-1$ //$NON-NLS-2$
}
json.append('}');
return json.toString();
}

/*
* Used to workaround that the GlobalTracer can only be registered once.
*/

public static Tracer getTracer() {
return TRACER;
}

public static void setTracer(Tracer tracer) {
TRACER = tracer;
}

}
59 changes: 59 additions & 0 deletions client/src/main/java/org/teiid/jdbc/tracing/TracingHelper.java
@@ -0,0 +1,59 @@
/*
* Copyright Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags and
* the COPYRIGHT.txt file distributed with this work.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.teiid.jdbc.tracing;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.teiid.core.util.ReflectionHelper;

/**
* Used to reflection load logic that is dependent upon the opentracing library, or provide a dummy implementation
*/
public class TracingHelper {

public interface Injector {
String getSpanContext();
}

private static Logger logger = Logger.getLogger("org.teiid.jdbc"); //$NON-NLS-1$

private static Injector INJECTOR;

public static String getSpanContext() {
if (INJECTOR == null) {
try {
INJECTOR = (Injector) ReflectionHelper.create("org.teiid.jdbc.tracing.GlobalTracerInjector", null, TracingHelper.class.getClassLoader()); //$NON-NLS-1$
} catch (Throwable e) { //must catch both Error and Exception
logger.log(Level.FINE, "Unable to load opentracing libraries, propagation will not be used", e); //$NON-NLS-1$
}
if (INJECTOR == null) {
INJECTOR = new Injector() {

@Override
public String getSpanContext() {
return null;
}
};
}
}
return INJECTOR.getSpanContext();
}

}
2 changes: 2 additions & 0 deletions client/src/test/java/org/teiid/client/TestRequestMessage.java
Expand Up @@ -60,6 +60,7 @@ public static RequestMessage example() {
message.setRowLimit(1313);
message.setReturnAutoGeneratedKeys(true);
message.setDelaySerialization(true);
message.setSpanContext("foo");
return message;
}

Expand All @@ -83,6 +84,7 @@ public static RequestMessage example() {
assertEquals(1313, copy.getRowLimit());
assertTrue(copy.isReturnAutoGeneratedKeys());
assertTrue(copy.isDelaySerialization());
assertEquals("foo", copy.getSpanContext());
}

@Test public void testInvalidTxnAutoWrap() {
Expand Down
42 changes: 42 additions & 0 deletions client/src/test/java/org/teiid/jdbc/tracing/TestTracing.java
@@ -0,0 +1,42 @@
/*
* Copyright Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags and
* the COPYRIGHT.txt file distributed with this work.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.teiid.jdbc.tracing;

import static org.junit.Assert.*;

import org.junit.Test;

import io.opentracing.Scope;
import io.opentracing.mock.MockTracer;

@SuppressWarnings("nls")
public class TestTracing {

@Test public void testSpanContextInjection() {
MockTracer tracer = new MockTracer();
assertNull(GlobalTracerInjector.getSpanContext(tracer));
Scope ignored = tracer.buildSpan("x").startActive(true);
try {
assertEquals("{\"spanid\":\"2\",\"traceid\":\"1\"}", GlobalTracerInjector.getSpanContext(tracer));
} finally {
ignored.close();
}
}

}
23 changes: 22 additions & 1 deletion engine/pom.xml
Expand Up @@ -145,7 +145,28 @@
<groupId>com.io7m.xom</groupId>
<artifactId>xom</artifactId>
</dependency>


<dependency>
<groupId>io.opentracing.contrib</groupId>
<artifactId>opentracing-concurrent</artifactId>
</dependency>

<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-api</artifactId>
</dependency>

<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-util</artifactId>
</dependency>

<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-mock</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

</project>

0 comments on commit c461fb1

Please sign in to comment.