Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make LightStep's Tracer fall in line with OpenTracing changes #18

Merged
merged 3 commits into from
Jul 16, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/.idea/
.idea/
.gradle/
**/.idea/workspace.xml
**/.idea/tasks.xml
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import com.lightstep.tracer.shared.Span;

import io.opentracing.Tracer;
import io.opentracing.References;

public abstract class AbstractTracer implements Tracer {
// Delay before sending the initial report
Expand Down Expand Up @@ -71,12 +72,12 @@ protected enum InternalLogLevel {
/**
* The tag key used to define traces which are joined based on a GUID.
*/
public static final String TRACE_GUID_KEY = "join:trace_guid";
public static final String TRACE_GUID_KEY = "join:trace_guid";
/**
* The tag key used to record the relationship between child and parent
* spans.
*/
public static final String PARENT_SPAN_GUID_KEY = "parent_span_guid";
public static final String PARENT_SPAN_GUID_KEY = "parent_span_guid";

// copied from options
private final int maxBufferedSpans;
Expand Down Expand Up @@ -295,12 +296,12 @@ public Tracer.SpanBuilder buildSpan(String operationName) {
return this.new SpanBuilder(operationName);
}

public <T> void inject(io.opentracing.Span span, T carrier) {
public void inject(io.opentracing.SpanContext spanContext, Object carrier) {
// TODO implement
throw new RuntimeException("inject: unimplemented");
}

public <T> Tracer.SpanBuilder join(T carrier) {
public io.opentracing.SpanContext extract(Object carrier) {
// TODO implement
throw new RuntimeException("join: unimplemented");
}
Expand Down Expand Up @@ -460,7 +461,7 @@ void addSpan(SpanRecord span) {
}
}

private static final String generateGUID() {
static final String generateGUID() {
// Note that ThreadLocalRandom is a singleton, thread safe Random Generator
long guid = ThreadLocalRandom.current().nextLong(Long.MAX_VALUE);
return Long.toHexString(guid);
Expand All @@ -473,7 +474,7 @@ protected void addTracerTag(String key, String value) {

class SpanBuilder implements Tracer.SpanBuilder{
private String operationName;
private io.opentracing.Span parent;
private SpanContext parent;
private Map<String, String> tags;
private long startTimestampMicros;

Expand All @@ -482,13 +483,18 @@ class SpanBuilder implements Tracer.SpanBuilder{
this.tags = new HashMap<String, String>();
}

public Tracer.SpanBuilder withOperationName(String operationName) {
this.operationName = operationName;
return this;
public Tracer.SpanBuilder asChildOf(Span parent) {
return this.asChildOf(parent.context());
}

public Tracer.SpanBuilder asChildOf(io.opentracing.SpanContext parent) {
return this.addReference(References.CHILD_OF, parent);
}

public Tracer.SpanBuilder withParent(io.opentracing.Span parent) {
this.parent = parent;
public Tracer.SpanBuilder addReference(String type, io.opentracing.SpanContext referredTo) {
if (type == References.CHILD_OF || type == References.FOLLOWS_FROM) {
this.parent = (SpanContext)referredTo;
}
return this;
}

Expand Down Expand Up @@ -528,17 +534,18 @@ public io.opentracing.Span start() {
record.setOldest_micros(this.startTimestampMicros);
record.setSpan_guid(generateGUID());

String traceID;
if (this.parent instanceof io.opentracing.Span) {
Span parentSpan = (Span)parent;
traceID = parentSpan.getTraceID();
record.addToAttributes(new KeyValue(PARENT_SPAN_GUID_KEY, parentSpan.getGUID()));
} else {
traceID = generateGUID();
String traceId = null;
if (this.parent != null && this.parent instanceof SpanContext) {
traceId = this.parent.getTraceId();
record.addToAttributes(new KeyValue(
PARENT_SPAN_GUID_KEY,
this.parent.getSpanId()));
}
record.addToJoin_ids(new TraceJoinId(TRACE_GUID_KEY, traceID));
SpanContext newSpanContext = new SpanContext(traceId); // traceId may be null
// Record the eventual TraceId in the SpanRecord.
record.setTrace_guid(newSpanContext.getTraceId());
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we set this rather than the no-longer-needed and deprecated TRACE_GUID_KEY.


Span span = new Span(AbstractTracer.this, record, traceID);
Span span = new Span(AbstractTracer.this, newSpanContext, record);
for (Map.Entry<String, String> pair : this.tags.entrySet()) {
span.setTag(pair.getKey(), pair.getValue());
}
Expand Down
23 changes: 13 additions & 10 deletions common/src/main/java/com/lightstep/tracer/shared/NoopSpan.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package com.lightstep.tracer.shared;

import io.opentracing.Span;
import io.opentracing.SpanContext;

// A span which is returned when the tracer is disabled.
class NoopSpan implements Span {

static final Span INSTANCE = new NoopSpan();
static final SpanContext CONTEXT = new NoopSpanContext();

private NoopSpan(){}

@Override
public SpanContext context() { return CONTEXT; }

@Override
public void finish() {}

Expand All @@ -30,16 +35,6 @@ public Span setTag(String key, Number value) {
return this;
}

@Override
public Span setBaggageItem(String key, String value) {
return this;
}

@Override
public String getBaggageItem(String key) {
return null;
}

@Override
public Span log(String message, /* @Nullable */ Object payload) {
return this;
Expand All @@ -49,4 +44,12 @@ public Span log(String message, /* @Nullable */ Object payload) {
public Span log(long instantMicroseconds, String message, /* @Nullable */ Object payload) {
return this;
}

private static class NoopSpanContext implements SpanContext {
@Override
public String getBaggageItem(String key) { return null; }

@Override
public SpanContext setBaggageItem(String key, String value) { return this; }
}
}
54 changes: 21 additions & 33 deletions common/src/main/java/com/lightstep/tracer/shared/Span.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,51 +16,34 @@ public class Span implements io.opentracing.Span {

private final Object mutex = new Object();
private final AbstractTracer tracer;
private final SpanContext context;
private final SpanRecord record;
private final String traceID;
private final ObjectMapper objectToJsonMapper;

Span (AbstractTracer tracer, SpanRecord record, String traceID) {
Span (AbstractTracer tracer, SpanContext context, SpanRecord record) {
this.context = context;
this.tracer = tracer;
this.record = record;
this.traceID = traceID;

this.objectToJsonMapper = new ObjectMapper();
this.objectToJsonMapper.setSerializationInclusion(
com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY);
}

public String getTraceID() {
synchronized (this.mutex) {
return this.traceID;
}
}

public String getGUID() {
synchronized (this.mutex) {
return this.record.getSpan_guid();
}
}

public AbstractTracer getTracer() {
return this.tracer;
@Override
public io.opentracing.SpanContext context() {
return this.context;
}

@Override
public void finish() {
synchronized (this.mutex) {
this.record.setYoungest_micros(System.currentTimeMillis() * 1000);
this.tracer.addSpan(record);
}
}

public void close() {
this.finish();
}

private static final boolean isJoinKey(String key) {
return key.startsWith("join:");
}

@Override
public Span setTag(String key, String value) {
synchronized (this.mutex) {
if (isJoinKey(key)) {
Expand All @@ -72,6 +55,7 @@ public Span setTag(String key, String value) {
return this;
}

@Override
public Span setTag(String key, boolean value){
synchronized (this.mutex) {
if (isJoinKey(key)) {
Expand All @@ -83,6 +67,7 @@ public Span setTag(String key, boolean value){
return this;
}

@Override
public Span setTag(String key, Number value) {
synchronized (this.mutex) {
if (isJoinKey(key)) {
Expand All @@ -94,14 +79,16 @@ public Span setTag(String key, Number value) {
return this;
}

public Span setBaggageItem(String key, String value) {
// TODO implement baggage
return this;
public void close() {
this.finish();
}

public String getBaggageItem(String key) {
// TODO implement baggage
return "";
private static final boolean isJoinKey(String key) {
return key.startsWith("join:");
}

public AbstractTracer getTracer() {
return this.tracer;
}

public Span log(String message, /* @Nullable */ Object payload) {
Expand All @@ -124,7 +111,8 @@ public Span log(long timestampMicroseconds, String message, /* @Nullable */ Obje
log.setPayload_json(payloadString);
} catch (JsonProcessingException e) {
// Just use a string.
this.tracer.debug("Payload not serializable to JSON. Setting as String. (Span GUID=" + this.getGUID() + ")");
this.tracer.debug("Payload not serializable to JSON. Setting as String. (SpanId=" +
((SpanContext)this.context()).getSpanId() + ")");
log.setPayload_json(payload.toString());
}
}
Expand All @@ -139,7 +127,7 @@ public Span log(long timestampMicroseconds, String message, /* @Nullable */ Obje
public String generateTraceURL() {
synchronized (this.mutex) {
return "https://app.lightstep.com/" + tracer.getAccessToken() +
"/trace?span_guid=" + this.getGUID() +
"/trace?span_guid=" + this.context.getSpanId() +
"&at_micros=" + (System.currentTimeMillis() * 1000);
}
}
Expand Down
43 changes: 43 additions & 0 deletions common/src/main/java/com/lightstep/tracer/shared/SpanContext.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.lightstep.tracer.shared;

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

public class SpanContext implements io.opentracing.SpanContext {
private final String traceId;
private final String spanId;
private Map<String, String> baggage;

public SpanContext(String traceId) {
if (traceId == null) {
this.traceId = AbstractTracer.generateGUID();
} else {
this.traceId = traceId;
}
this.spanId = AbstractTracer.generateGUID();
}

public String getSpanId() {
return this.spanId;
}
public String getTraceId() {
return this.traceId;
}

@Override
public synchronized String getBaggageItem(String key) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm using synchronized here rather than creating a Mutex. Seemed fine / equivalent.

if (this.baggage == null) {
return null;
}
return this.baggage.get(key);
}

@Override
public synchronized SpanContext setBaggageItem(String key, String value) {
if (this.baggage == null) {
this.baggage = new HashMap<String, String>();
}
this.baggage.put(key, value);
return this;
}
}
2 changes: 1 addition & 1 deletion lightstep-tracer-jre/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ repositories {

// Dependencies to build this JAR archive
dependencies {
compile 'io.opentracing:opentracing-api:0.1.0-SNAPSHOT'
compile 'io.opentracing:opentracing-api:0.9.0'
compile 'org.apache.thrift:libthrift:0.9.2'
compile 'com.fasterxml.jackson.core:jackson-databind:2.7.3'
compile 'org.json:json:20160212'
Expand Down
16 changes: 16 additions & 0 deletions lightstep-tracer-jre/lightstep-tracer.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:3.8.1" level="project" />
<orderEntry type="library" name="Maven: org.json:json:20090211" level="project" />
</component>
</module>