
com.undefinedlabs.scope.Span Maven / Gradle / Ivy
package com.undefinedlabs.scope;
import com.undefinedlabs.scope.events.log.LogEvent;
import com.undefinedlabs.scope.statistics.Statistics;
import com.undefinedlabs.scope.utils.tag.TagKeys;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Span implements io.opentracing.Span {
private final ScopeTracer tracer;
private final SpanContext context;
private final long startTimeMicroseconds;
private final long startTimeNanoTicks;
private final boolean computeDurationViaNanoTicks;
private long durationMicroseconds;
private long durationNanoTicks;
private final Map tags;
private final List references;
private List logs;
private String operationName;
private boolean finished = false;
private boolean markUnfinished = false;
protected Span(
final ScopeTracer tracer,
final String operationName,
final SpanContext context,
final long startTimeMicroseconds,
final long startTimeNanoTicks,
final boolean computeDurationViaNanoTicks,
final Map tags,
final List references) {
this.tracer = tracer;
this.operationName = operationName;
this.context = context;
this.startTimeMicroseconds = startTimeMicroseconds;
this.startTimeNanoTicks = startTimeNanoTicks;
this.computeDurationViaNanoTicks = computeDurationViaNanoTicks;
this.tags = new HashMap<>();
this.references = references != null ? new ArrayList<>(references) : null;
for (Map.Entry tag : tags.entrySet()) {
setTagAsObject(tag.getKey(), tag.getValue());
}
}
@Override
public io.opentracing.SpanContext context() {
return this.context;
}
@Override
public io.opentracing.Span setTag(String key, String value) {
return setTagAsObject(key, value);
}
@Override
public io.opentracing.Span setTag(String key, boolean value) {
return setTagAsObject(key, value);
}
@Override
public io.opentracing.Span setTag(String key, Number value) {
return setTagAsObject(key, value);
}
public io.opentracing.Span setTag(String key, Object value) {
return setTagAsObject(key, value);
}
@Override
public io.opentracing.Span setTag(io.opentracing.tag.Tag tag, T value) {
return setTagAsObject(tag.getKey(), value);
}
@Override
public io.opentracing.Span log(Map fields) {
return this.log(this.tracer.clock().currentTimeMicros(), fields);
}
@Override
public io.opentracing.Span log(long timestampMicroseconds, Map fields) {
synchronized (this) {
if (fields == null) {
return this;
}
if (logs == null) {
this.logs = new ArrayList<>();
}
this.logs.add(new SpanEventData(timestampMicroseconds, (Map) fields));
}
return this;
}
@Override
public io.opentracing.Span log(String event) {
return this.log(this.tracer.clock().currentTimeMicros(), event);
}
@Override
public io.opentracing.Span log(long timestampMicroseconds, String event) {
return this.log(
timestampMicroseconds,
this.tracer
.eventFieldsFactory()
.createFields(LogEvent.newBuilder().withMessage(event).build()));
}
@Override
public io.opentracing.Span setBaggageItem(String key, String value) {
synchronized (this) {
this.context.getBaggage().put(key, value);
}
return this;
}
@Override
public String getBaggageItem(String key) {
synchronized (this) {
return this.context.getBaggage().get(key);
}
}
@Override
public io.opentracing.Span setOperationName(String operationName) {
synchronized (this) {
this.operationName = operationName;
}
return this;
}
@Override
public void finish() {
if (this.computeDurationViaNanoTicks) {
final long durationNanos = this.tracer.clock().currentNanoTicks() - this.startTimeNanoTicks;
final long durationMicros = durationNanos / 1000;
finishWithDuration(durationMicros, durationNanos);
} else {
finish(this.tracer.clock().currentTimeMicros());
}
}
@Override
public void finish(long finishMicros) {
final long durationMicros = finishMicros - this.startTimeMicroseconds;
final long durationNanos = durationMicros * 1000;
finishWithDuration(durationMicros, durationNanos);
}
private void finishWithDuration(final long durationMicros, final long durationNanos) {
synchronized (this) {
if (this.finished) {
return;
}
this.finished = true;
this.durationMicroseconds = durationMicros;
this.durationNanoTicks = durationNanos;
}
this.tracer.registerFinishedSpan(this);
this.tracer.reportSpan(this);
Statistics.INSTANCE.registerFinishedSpan(this);
}
public long getStartMicros() {
synchronized (this) {
return this.startTimeMicroseconds;
}
}
public long getStartNanos() {
synchronized (this) {
return this.startTimeNanoTicks;
}
}
public ScopeTracer getTracer() {
return tracer;
}
public long getDurationMicros() {
synchronized (this) {
return this.durationMicroseconds;
}
}
public long getDurationNanos() {
synchronized (this) {
return this.durationNanoTicks;
}
}
public String getOperationName() {
synchronized (this) {
return this.operationName;
}
}
public Map getTags() {
synchronized (this) {
return Collections.unmodifiableMap(new HashMap<>(tags));
}
}
public List getReferences() {
synchronized (this) {
if (references == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(references);
}
}
public List getLogs() {
synchronized (this) {
return this.logs != null ? Collections.unmodifiableList(new ArrayList<>(logs)) : null;
}
}
private io.opentracing.Span setTagAsObject(String key, Object value) {
synchronized (this) {
this.tags.put(key, value);
}
return this;
}
public io.opentracing.Span markUnfinished() {
synchronized (this) {
if (markUnfinished) {
return this;
}
this.markUnfinished = true;
this.tags.put(TagKeys.UNFINISHED, true);
}
return this;
}
public boolean isUnfinished() {
synchronized (this) {
return this.markUnfinished;
}
}
@Override
public String toString() {
synchronized (this) {
return this.context.toString() + " - " + this.operationName;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy