diff --git a/skywalking-commons/skywalking-trace/src/main/java/com/a/eye/skywalking/trace/LogData.java b/skywalking-commons/skywalking-trace/src/main/java/com/a/eye/skywalking/trace/LogData.java new file mode 100644 index 0000000000000000000000000000000000000000..47c4b7d182bf3719848cd33a78ed9b1b8578d111 --- /dev/null +++ b/skywalking-commons/skywalking-trace/src/main/java/com/a/eye/skywalking/trace/LogData.java @@ -0,0 +1,18 @@ +package com.a.eye.skywalking.trace; + +import java.util.Map; + +/** + * It is a holder of one log record. + * + * Created by wusheng on 2017/2/17. + */ +public class LogData { + private final long time; + private final Map fields; + + LogData(long time, Map fields) { + this.time = time; + this.fields = fields; + } +} diff --git a/skywalking-commons/skywalking-trace/src/main/java/com/a/eye/skywalking/trace/Span.java b/skywalking-commons/skywalking-trace/src/main/java/com/a/eye/skywalking/trace/Span.java index 4b7fcac2e01f6012c9b9389556a154ba2ddba220..2c81181c30a6ecea6b5b937e297fcd2c872b1eaa 100644 --- a/skywalking-commons/skywalking-trace/src/main/java/com/a/eye/skywalking/trace/Span.java +++ b/skywalking-commons/skywalking-trace/src/main/java/com/a/eye/skywalking/trace/Span.java @@ -1,5 +1,11 @@ package com.a.eye.skywalking.trace; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + /** * Span is a concept from OpenTracing Spec, also from Google Dapper Paper. * Traces in OpenTracing are defined implicitly by their Spans. @@ -21,4 +27,151 @@ package com.a.eye.skywalking.trace; * Created by wusheng on 2017/2/17. */ public class Span { + private int spanId; + + private int parentSpanId; + + /** + * The start time of this Span. + */ + private long startTime; + + /** + * The end time of this Span. + */ + private long endTime; + + /** + * The operation name ot this Span. + * If you want to know, how to set an operation name, + * {@see https://github.com/opentracing/specification/blob/master/specification.md#start-a-new-span} + */ + private String operationName; + + /** + * Tag is a concept from OpenTracing spec. + * + * {@see https://github.com/opentracing/specification/blob/master/specification.md#set-a-span-tag} + */ + private final Map tags = new HashMap(); + + /** + * Log is a concept from OpenTracing spec. + * + * {@see https://github.com/opentracing/specification/blob/master/specification.md#log-structured-data} + */ + private final List logs = new ArrayList(); + + /** + * Create a new span, by given span id and parent span id. + * This span must belong a {@link TraceSegment}, also is a part of Distributed Trace. + * + * @param spanId given by the creator, and must be unique id in the {@link TraceSegment} + * @param parentSpanId given by the creator, and must be an existed span id in the {@link TraceSegment}. + * Value -1 means no parent span if this {@link TraceSegment}. + * @param operationName {@link #operationName} + */ + public Span(int spanId, int parentSpanId, String operationName){ + this.spanId = spanId; + this.parentSpanId = parentSpanId; + this.startTime = System.currentTimeMillis(); + } + + /** + * Create a new span, by given span id and no parent span id. + * No parent span id means that, this Span is the first span of the {@link TraceSegment} + * + * @param spanId given by the creator, and must be unique id in the {@link TraceSegment} + * @param operationName {@link #operationName} + */ + public Span(int spanId, String operationName){ + this(spanId, -1, operationName); + } + + /** + * Finish the active Span. + * When it is finished, it will be archived by the given {@link TraceSegment}, which owners it. + * + * @param owner of the Span. + */ + public void finish(TraceSegment owner){ + this.endTime = System.currentTimeMillis(); + owner.archive(this); + } + + /** + * Set a key:value tag on the Span. + */ + public final Span setTag(String key, String value) { + tags.put(key, value); + return this; + } + + public final Span setTag(String key, boolean value) { + tags.put(key, value); + return this; + } + + public final Span setTag(String key, Number value) { + tags.put(key, value); + return this; + } + + /** + * Get all tags from this span, but readonly. + * + * @return + */ + public final Map getTags() { + return Collections.unmodifiableMap(tags); + } + + /** + * This method is from opentracing-java. + * {@see https://github.com/opentracing/opentracing-java/blob/release-0.20.9/opentracing-api/src/main/java/io/opentracing/Span.java#L91} + * + * Log key:value pairs to the Span with the current walltime timestamp. + * + *

CAUTIONARY NOTE: not all Tracer implementations support key:value log fields end-to-end. + * Caveat emptor. + * + *

A contrived example (using Guava, which is not required): + *

{@code
+        span.log(
+            ImmutableMap.Builder()
+            .put("event", "soft error")
+            .put("type", "cache timeout")
+            .put("waited.millis", 1500)
+            .build());
+        }
+ * + * @param fields key:value log fields. Tracer implementations should support String, numeric, and boolean values; + * some may also support arbitrary Objects. + * @return the Span, for chaining + * @see Span#log(String) + */ + Span log(Map fields){ + logs.add(new LogData(System.currentTimeMillis(), fields)); + return this; + } + + /** + * This method is from opentracing-java. + * {@see https://github.com/opentracing/opentracing-java/blob/release-0.20.9/opentracing-api/src/main/java/io/opentracing/Span.java#L120} + * + * Record an event at the current walltime timestamp. + * + * Shorthand for + * + *
{@code
+        span.log(Collections.singletonMap("event", event));
+        }
+ * + * @param event the event value; often a stable identifier for a moment in the Span lifecycle + * @return the Span, for chaining + */ + Span log(String event){ + log(Collections.singletonMap("event", event)); + return this; + } } diff --git a/skywalking-commons/skywalking-trace/src/main/java/com/a/eye/skywalking/trace/TraceSegment.java b/skywalking-commons/skywalking-trace/src/main/java/com/a/eye/skywalking/trace/TraceSegment.java index bb671bfb16f7e06a362ad65cc9b95b90489ad921..7d164f2a904b83e93a8a45b2eebfb61c6432fd55 100644 --- a/skywalking-commons/skywalking-trace/src/main/java/com/a/eye/skywalking/trace/TraceSegment.java +++ b/skywalking-commons/skywalking-trace/src/main/java/com/a/eye/skywalking/trace/TraceSegment.java @@ -52,17 +52,18 @@ public class TraceSegment { /** * Create a trace segment, by given segmentId. - * This segmentId is generated by TraceSegmentRef, AKA tracer/agent module. + * This segmentId is generated by TraceSegmentRef, AKA, from tracer/agent module. * * @param segmentId {@link #traceSegmentId} */ public TraceSegment(String segmentId) { this.traceSegmentId = segmentId; this.startTime = System.currentTimeMillis(); + this.spans = new LinkedList(); } /** - * Establish the link between this segment to his parents. + * Establish the link between this segment and its parents. * The first time, you {@link #ref(TraceSegmentRef)} to parent, it is affirmed as {@link #primaryRef}. * And others are affirmed as {@link #refs}. * @@ -78,4 +79,21 @@ public class TraceSegment { refs.add(refSegment); } } + + /** + * After {@link Span} is finished, as be controller by "skywalking-api" module, + * notify the {@link TraceSegment} to archive it. + * + * @param finishedSpan + */ + void archive(Span finishedSpan){ + spans.add(finishedSpan); + } + + /** + * Finish this {@link TraceSegment}. + */ + public void finish(){ + this.endTime = System.currentTimeMillis(); + } }