提交 3df884fd 编写于 作者: wu-sheng's avatar wu-sheng

Finish codes for supporting opentracing-java 0.30.0

上级 25858600
......@@ -15,12 +15,12 @@
<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-api</artifactId>
<version>0.20.4</version>
<version>0.30.0</version>
</dependency>
<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-noop</artifactId>
<version>0.20.4</version>
<version>0.30.0</version>
</dependency>
</dependencies>
......
package org.skywalking.apm.toolkit.opentracing;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The <code>NeedSnifferActivation</code> annotation is flag for reader and maintainers,
* which represents this method should be activated/intercepted in sniffer.
*
* @author wusheng
*/
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.SOURCE)
public @interface NeedSnifferActivation {
String value() default "What should interceptor do?";
}
package org.skywalking.apm.toolkit.opentracing;
import io.opentracing.References;
import io.opentracing.Span;
import io.opentracing.SpanContext;
import io.opentracing.Tracer;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* All source code in SkyWalkingSpanBuilder acts like an NoopSpanBuilder.
* Actually, it is NOT.
* The whole logic will be added after toolkit-activation.
* <p>
* Created by wusheng on 2016/12/20.
*/
public class SkyWalkingSpanBuilder implements Tracer.SpanBuilder {
private String operationName;
private long startTime = 0L;
private final Map<String, String> tags;
private SpanContext parentContext;
SkyWalkingSpanBuilder(String operationName) {
this.operationName = operationName;
this.tags = new HashMap<String, String>();
}
/**
* In SkyWalkingTracer, SpanContext will not be used. Tracer will build reference by itself.
*
* @param spanContext
* @return
*/
@Override
public Tracer.SpanBuilder asChildOf(SpanContext spanContext) {
this.parentContext = spanContext;
return this;
}
/**
* In SkyWalkingTracer, Parent Span will not be used. Tracer will build reference by itself.
*
* @param span
* @return
*/
@Override
public Tracer.SpanBuilder asChildOf(Span span) {
asChildOf(span.context());
return this;
}
@Override
public Tracer.SpanBuilder addReference(String referenceType, SpanContext referencedContext) {
if (referenceType.equals(References.CHILD_OF)) {
return asChildOf(referencedContext);
} else {
return this;
}
}
@Override
public Tracer.SpanBuilder withTag(String key, String value) {
if (key != null && value != null) {
tags.put(key, value);
}
return this;
}
@Override
public Tracer.SpanBuilder withTag(String key, boolean value) {
if (key != null) {
tags.put(key, Boolean.toString(value));
}
return this;
}
@Override
public Tracer.SpanBuilder withTag(String key, Number value) {
if (key != null && value != null) {
tags.put(key, value.toString());
}
return this;
}
@Override
public Tracer.SpanBuilder withStartTimestamp(long startTime) {
this.startTime = startTime;
return this;
}
@Override
public Span start() {
if (startTime == 0) {
startTime = System.currentTimeMillis();
}
return new SkyWalkingSpan(this.operationName, this.startTime, this.tags);
}
@Override
public Iterable<Map.Entry<String, String>> baggageItems() {
return parentContext == null
? Collections.<String, String>emptyMap().entrySet()
: parentContext.baggageItems();
}
}
package org.skywalking.apm.toolkit.opentracing;
import io.opentracing.ActiveSpan;
import io.opentracing.SpanContext;
import java.util.Map;
/**
* The <code>SkywalkingActiveSpan</code> is an extension of {@link SkywalkingSpan},
* but because of Java inheritance restrict, only can do with a facade mode.
*
* @author wusheng
*/
public class SkywalkingActiveSpan implements ActiveSpan {
private SkywalkingSpan span;
public SkywalkingActiveSpan(SkywalkingSpan span) {
this.span = span;
}
@Override
public void deactivate() {
span.finish();
}
@Override
public void close() {
this.deactivate();
}
@Override
public Continuation capture() {
return new SkywalkingContinuation();
}
@Override
public SpanContext context() {
return span.context();
}
@Override
public ActiveSpan setTag(String key, String value) {
span.setTag(key, value);
return this;
}
@Override
public ActiveSpan setTag(String key, boolean value) {
span.setTag(key, value);
return this;
}
@Override
public ActiveSpan setTag(String key, Number value) {
span.setTag(key, value);
return this;
}
@Override
public ActiveSpan log(Map<String, ?> fields) {
span.log(fields);
return this;
}
@Override
public ActiveSpan log(long timestampMicroseconds, Map<String, ?> fields) {
span.log(timestampMicroseconds, fields);
return this;
}
@Override
public ActiveSpan log(String event) {
span.log(event);
return this;
}
@Override
public ActiveSpan log(long timestampMicroseconds, String event) {
span.log(timestampMicroseconds, event);
return this;
}
/**
* Don't support baggage item.
*/
@Override
public ActiveSpan setBaggageItem(String key, String value) {
return this;
}
/**
* Don't support baggage item.
*
* @return null, always.
*/
@Override
public String getBaggageItem(String key) {
return null;
}
@Override
public ActiveSpan setOperationName(String operationName) {
span.setOperationName(operationName);
return this;
}
/**
* Don't support logging with payload.
*/
@Deprecated
@Override
public ActiveSpan log(String eventName, Object payload) {
return this;
}
/**
* Don't support logging with payload.
*/
@Deprecated
@Override
public ActiveSpan log(long timestampMicroseconds, String eventName, Object payload) {
return this;
}
}
package org.skywalking.apm.toolkit.opentracing;
import io.opentracing.SpanContext;
import java.util.Map;
/**
* Skywalking tracer context based on {@link ThreadLocal} auto mechanism.
*
* @author wusheng
*/
public class SkywalkingContext implements SpanContext {
public static final SkywalkingContext INSTANCE = new SkywalkingContext();
private SkywalkingContext() {
}
@Override
public Iterable<Map.Entry<String, String>> baggageItems() {
return null;
}
}
package org.skywalking.apm.toolkit.opentracing;
import io.opentracing.ActiveSpan;
/**
* @author wusheng
*/
public class SkywalkingContinuation implements ActiveSpan.Continuation {
@NeedSnifferActivation("1. ContextManager#capture" +
"2. set ContextSnapshot to the dynamic field")
public SkywalkingContinuation() {
}
@NeedSnifferActivation("1. get ContextSnapshot from the dynamic field" +
"2. ContextManager#continued")
@Override
public ActiveSpan activate() {
SkywalkingSpanBuilder builder = new SkywalkingSpanBuilder("Thread/" + Thread.currentThread().getName());
return builder.startActive();
}
}
......@@ -2,112 +2,127 @@ package org.skywalking.apm.toolkit.opentracing;
import io.opentracing.Span;
import io.opentracing.SpanContext;
import java.util.HashMap;
import java.util.Map;
/**
* Created by wusheng on 2016/12/20.
* @author wusheng
*/
public class SkyWalkingSpan implements Span, SpanContext {
private String operationName;
private long startTime;
private Map<String, String> tags;
public class SkywalkingSpan implements Span {
@NeedSnifferActivation(
"1.ContextManager#createSpan (Entry,Exit,Local based on builder)." +
"2.set the span reference to the dynamic field of enhanced SkywalkingSpan")
public SkywalkingSpan(SkywalkingSpanBuilder builder) {
}
private final Map<String, String> baggageItems;
/**
* Create a shell span for {@link SkywalkingTracer#activeSpan()}
* @param tracer
*/
@NeedSnifferActivation(
"1. set the span reference to the dynamic field of enhanced SkywalkingSpan"
)
public SkywalkingSpan(SkywalkingTracer tracer){
SkyWalkingSpan(String operationName, long startTime, Map<String, String> tags) {
this.operationName = operationName;
this.startTime = startTime;
this.tags = tags;
baggageItems = new HashMap<String, String>();
}
@NeedSnifferActivation("Override span's operationName, which has been given at ")
@Override
public SpanContext context() {
public Span setOperationName(String operationName) {
return this;
}
@NeedSnifferActivation("AbstractTracingSpan#log(long timestampMicroseconds, Map<String, ?> fields)")
@Override
public void finish() {
public Span log(long timestampMicroseconds, Map<String, ?> fields) {
return this;
}
/**
* Stop the active span
*
* @param finishMicros
*/
@NeedSnifferActivation(
"1.ContextManager#stopSpan(AbstractSpan span)" +
"2. The parameter of stop methed is from the dynamic field of enhanced SkywalkingSpan")
@Override
public void finish(long finishMicros) {
}
@Override
public void close() {
public Span log(long timestampMicroseconds, String event) {
Map<String, String> eventMap = new HashMap<String, String>(1);
eventMap.put("event", event);
return log(timestampMicroseconds, eventMap);
}
@Override
public Span setTag(String key, String value) {
return this;
public void finish() {
this.finish(System.currentTimeMillis());
}
@Override
public Span setTag(String key, boolean value) {
return this;
public SpanContext context() {
return SkywalkingContext.INSTANCE;
}
@Override
public Span setTag(String key, Number value) {
return this;
@Override public Span setTag(String key, String value) {
return null;
}
@Override
public Span log(Map<String, ?> fields) {
return this;
@Override public Span setTag(String key, boolean value) {
return null;
}
@Override
public Span log(long timestampMicroseconds, Map<String, ?> fields) {
return this;
@Override public Span setTag(String key, Number value) {
return null;
}
@Override
public Span log(String event) {
return this;
public Span log(Map<String, ?> fields) {
return log(System.currentTimeMillis(), fields);
}
@Override
public Span log(long timestampMicroseconds, String event) {
return this;
public Span log(String event) {
return log(System.currentTimeMillis(), event);
}
/**
* Don't support baggage item.
*/
@Override
public Span setBaggageItem(String key, String value) {
baggageItems.put(key, value);
return this;
}
/**
* Don't support baggage item.
*
* @return null, always.
*/
@Override
public String getBaggageItem(String key) {
return baggageItems.get(key);
}
@Override
public Span setOperationName(String operationName) {
return this;
return null;
}
/**
* Don't support logging with payload.
*/
@Deprecated
@Override
public Span log(String eventName, Object payload) {
return this;
}
/**
* Don't support logging with payload.
*/
@Deprecated
@Override
public Span log(long timestampMicroseconds, String eventName, Object payload) {
return this;
}
@Override
public Iterable<Map.Entry<String, String>> baggageItems() {
return baggageItems.entrySet();
}
}
package org.skywalking.apm.toolkit.opentracing;
import io.opentracing.ActiveSpan;
import io.opentracing.BaseSpan;
import io.opentracing.References;
import io.opentracing.Span;
import io.opentracing.SpanContext;
import io.opentracing.Tracer;
import io.opentracing.tag.Tags;
import java.util.LinkedList;
import java.util.List;
/**
* @author wusheng
*/
public class SkywalkingSpanBuilder implements Tracer.SpanBuilder {
private List<Tag> tags = new LinkedList<Tag>();
private String operationName;
private boolean isEntry = false;
private boolean isExit = false;
private int port;
private String peer;
private String componentName;
private boolean isError = false;
private long startTime;
public SkywalkingSpanBuilder(String operationName) {
this.operationName = operationName;
}
@Override
public Tracer.SpanBuilder asChildOf(SpanContext parent) {
if (parent instanceof SkywalkingContext) {
return this;
}
throw new IllegalArgumentException("parent must be type of SpanContext");
}
@Override
public Tracer.SpanBuilder asChildOf(BaseSpan<?> parent) {
if (parent instanceof SkywalkingSpan) {
return this;
}
throw new IllegalArgumentException("parent must be type of SkywalkingSpan");
}
/**
* Ignore the reference type. the span always the entry or has a parent span.
*
* @param referenceType
* @param referencedContext
* @return
*/
@Override
public Tracer.SpanBuilder addReference(String referenceType, SpanContext referencedContext) {
if (References.FOLLOWS_FROM.equals(referenceType)) {
throw new IllegalArgumentException("only support CHILD_OF reference");
}
return asChildOf(referencedContext);
}
@Override
public Tracer.SpanBuilder withTag(String key, String value) {
if (Tags.COMPONENT.equals(key)) {
componentName = value;
} else if (Tags.SPAN_KIND.equals(key)) {
if (Tags.SPAN_KIND_CLIENT.equals(key) || Tags.SPAN_KIND_PRODUCER.equals(key)) {
isEntry = false;
isExit = true;
} else if (Tags.SPAN_KIND_SERVER.equals(key) || Tags.SPAN_KIND_CONSUMER.equals(key)) {
isEntry = true;
isExit = false;
} else {
isEntry = false;
isExit = false;
}
} else if (Tags.PEER_HOST_IPV4.equals(key) || Tags.PEER_HOST_IPV6.equals(key)
|| Tags.PEER_HOSTNAME.equals(key)) {
peer = value;
} else if (Tags.PEER_SERVICE.equals(key)) {
operationName = value;
} else {
tags.add(new Tag(key, value));
}
return this;
}
@Override
public Tracer.SpanBuilder withTag(String key, boolean value) {
if (Tags.ERROR.equals(key)) {
isError = value;
} else {
tags.add(new Tag(key, value ? "true" : "false"));
}
return this;
}
@Override
public Tracer.SpanBuilder withTag(String key, Number value) {
if (Tags.PEER_PORT.equals(key)) {
port = value.intValue();
} else {
tags.add(new Tag(key, value.toString()));
}
return this;
}
@Override
public Tracer.SpanBuilder withStartTimestamp(long microseconds) {
startTime = microseconds;
return this;
}
@Override
public ActiveSpan startActive() {
return new SkywalkingActiveSpan(new SkywalkingSpan(this));
}
@Override
public Span startManual() {
return new SkywalkingSpan(this);
}
@Override
@Deprecated
public Span start() {
return startManual();
}
/**
* All the get methods are for accessing data from activation
*/
public List<Tag> getTags() {
return tags;
}
public String getOperationName() {
return operationName;
}
public boolean isEntry() {
return isEntry;
}
public boolean isExit() {
return isExit;
}
public int getPort() {
return port;
}
public String getPeer() {
return peer;
}
public String getComponentName() {
return componentName;
}
public boolean isError() {
return isError;
}
public long getStartTime() {
return startTime;
}
/**
* All the following methods are needed for activation.
*/
@Override
@NeedSnifferActivation("Stop the active span.")
public Tracer.SpanBuilder ignoreActiveSpan() {
return this;
}
}
package org.skywalking.apm.toolkit.opentracing;
import io.opentracing.ActiveSpan;
import io.opentracing.Span;
import io.opentracing.SpanContext;
import io.opentracing.Tracer;
import io.opentracing.propagation.Format;
import io.opentracing.propagation.TextMap;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Map;
/**
* All source code in SkyWalkingTracer acts like an NoopTracer.
* Actually, it is NOT.
* The whole logic will be added after toolkit-activation.
* <p>
* Created by wusheng on 2016/12/20.
* @author wusheng
*/
public class SkyWalkingTracer implements Tracer {
public class SkywalkingTracer implements Tracer {
private static String TRACE_HEAD_NAME = "sw3";
public static Tracer INSTANCE = new SkyWalkingTracer();
@NeedSnifferActivation("1. ContextManager#inject" +
"2. ContextCarrier#serialize")
private String inject() {
return null;
}
@NeedSnifferActivation("1. ContextCarrier#deserialize" +
"2. ContextManager#extract")
private void extract(String carrier) {
}
@Override
public SpanBuilder buildSpan(String operationName) {
return new SkyWalkingSpanBuilder(operationName);
return new SkywalkingSpanBuilder(operationName);
}
@Override
public <C> void inject(SpanContext spanContext, Format<C> format, C carrier) {
if (Format.Builtin.TEXT_MAP.equals(format) || Format.Builtin.HTTP_HEADERS.equals(format)) {
((TextMap) carrier).put(TRACE_HEAD_NAME, formatInjectCrossProcessPropagationContextData());
((TextMap)carrier).put(TRACE_HEAD_NAME, inject());
} else if (Format.Builtin.BINARY.equals(format)) {
byte[] key = TRACE_HEAD_NAME.getBytes(ByteBufferContext.CHARSET);
byte[] value = formatInjectCrossProcessPropagationContextData().getBytes(ByteBufferContext.CHARSET);
((ByteBuffer) carrier).put(key);
((ByteBuffer) carrier).putInt(value.length);
((ByteBuffer) carrier).put(value);
byte[] value = inject().getBytes(ByteBufferContext.CHARSET);
((ByteBuffer)carrier).put(key);
((ByteBuffer)carrier).putInt(value.length);
((ByteBuffer)carrier).put(value);
} else {
throw new IllegalArgumentException("Unsupported format: " + format);
}
}
@Override
public <C> SpanContext extract(Format<C> format, C carrier) {
if (Format.Builtin.TEXT_MAP.equals(format) || Format.Builtin.HTTP_HEADERS.equals(format)) {
TextMap textMapCarrier = (TextMap) carrier;
formatExtractCrossProcessPropagationContextData(fetchContextData(textMapCarrier));
TextMap textMapCarrier = (TextMap)carrier;
extract(fetchContextData(textMapCarrier));
return new TextMapContext(textMapCarrier);
} else if (Format.Builtin.BINARY.equals(format)) {
ByteBuffer byteBufferCarrier = (ByteBuffer) carrier;
formatExtractCrossProcessPropagationContextData(fetchContextData(byteBufferCarrier));
return new ByteBufferContext((ByteBuffer) carrier);
ByteBuffer byteBufferCarrier = (ByteBuffer)carrier;
extract(fetchContextData(byteBufferCarrier));
return new ByteBufferContext((ByteBuffer)carrier);
} else {
throw new IllegalArgumentException("Unsupported format: " + format);
}
}
/**
* set context data in toolkit-opentracing-activation
*/
private String formatInjectCrossProcessPropagationContextData() {
return "";
@Override
public ActiveSpan activeSpan() {
return new SkywalkingActiveSpan(new SkywalkingSpan(this));
}
/**
* read context data in toolkit-opentracing-activation
*/
private void formatExtractCrossProcessPropagationContextData(String contextData) {
@Override
public ActiveSpan makeActive(Span span) {
if (span instanceof SkywalkingSpan) {
return new SkywalkingActiveSpan((SkywalkingSpan)span);
} else {
throw new IllegalArgumentException("span must be a type of SkywalkingSpan");
}
}
private String fetchContextData(TextMap textMap) {
......@@ -99,4 +107,5 @@ public class SkyWalkingTracer implements Tracer {
return null;
}
}
}
package org.skywalking.apm.toolkit.opentracing;
/**
* @author wusheng
*/
public class Tag {
private String key;
private String value;
public Tag(String key, String value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public String getValue() {
return value;
}
}
......@@ -5,6 +5,7 @@ import org.skywalking.apm.agent.core.boot.ServiceManager;
import org.skywalking.apm.agent.core.conf.Config;
import org.skywalking.apm.agent.core.conf.RemoteDownstreamConfig;
import org.skywalking.apm.agent.core.context.trace.AbstractSpan;
import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
import org.skywalking.apm.agent.core.context.trace.TraceSegment;
import org.skywalking.apm.agent.core.dictionary.DictionaryUtil;
import org.skywalking.apm.agent.core.sampling.SamplingService;
......@@ -106,6 +107,28 @@ public class ContextManager implements TracingContextListener, BootService, Igno
return span;
}
public static void inject(ContextCarrier contextCarrier) {
AbstractSpan span = activeSpan();
if (span instanceof AbstractTracingSpan) {
if (span.isExit()) {
get().inject(contextCarrier);
} else {
throw new IllegalStateException("Can't do inject when the active span isn't an exit span");
}
}
}
public static void extract(ContextCarrier contextCarrier) {
AbstractSpan span = activeSpan();
if (span instanceof AbstractTracingSpan) {
if (span.isEntry()) {
get().extract(contextCarrier);
} else {
throw new IllegalStateException("Can't do extract when the active span isn't an entry span");
}
}
}
public ContextSnapshot capture() {
return get().capture();
}
......@@ -122,7 +145,11 @@ public class ContextManager implements TracingContextListener, BootService, Igno
}
public static void stopSpan() {
get().stopSpan(activeSpan());
stopSpan(activeSpan());
}
public static void stopSpan(AbstractSpan span) {
get().stopSpan(span);
}
@Override
......
......@@ -2,6 +2,7 @@ package org.skywalking.apm.agent.core.context.trace;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.skywalking.apm.agent.core.context.util.KeyValuePair;
import org.skywalking.apm.agent.core.context.util.ThrowableTransformer;
import org.skywalking.apm.agent.core.dictionary.DictionaryUtil;
......@@ -106,7 +107,25 @@ public abstract class AbstractTracingSpan implements AbstractSpan {
.add(new KeyValuePair("error.kind", t.getClass().getName()))
.add(new KeyValuePair("message", t.getMessage()))
.add(new KeyValuePair("stack", ThrowableTransformer.INSTANCE.convert2String(t, 4000)))
.build());
.build(System.currentTimeMillis()));
return this;
}
/**
* Record a common log with multi fields, for supporting opentracing-java
*
* @param fields
* @return the Span, for chaining
*/
public AbstractSpan log(long timestampMicroseconds, Map<String, ?> fields) {
if (logs == null) {
logs = new LinkedList<LogDataEntity>();
}
LogDataEntity.Builder builder = new LogDataEntity.Builder();
for (Map.Entry<String, ?> entry : fields.entrySet()) {
builder.add(new KeyValuePair(entry.getKey(), entry.getValue().toString()));
}
logs.add(builder.build(timestampMicroseconds));
return this;
}
......
......@@ -12,9 +12,11 @@ import org.skywalking.apm.network.proto.LogMessage;
* @author wusheng
*/
public class LogDataEntity {
protected List<KeyValuePair> logs;
private long timestamp = 0;
private List<KeyValuePair> logs;
private LogDataEntity(List<KeyValuePair> logs) {
private LogDataEntity(long timestamp, List<KeyValuePair> logs) {
this.timestamp = timestamp;
this.logs = logs;
}
......@@ -36,8 +38,8 @@ public class LogDataEntity {
return this;
}
public LogDataEntity build() {
return new LogDataEntity(logs);
public LogDataEntity build(long timestamp) {
return new LogDataEntity(timestamp, logs);
}
}
......@@ -46,6 +48,7 @@ public class LogDataEntity {
for (KeyValuePair log : logs) {
logMessageBuilder.addData(log.transform());
}
logMessageBuilder.setTime(timestamp);
return logMessageBuilder.build();
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册