* This would trace 50% of all gets, 75% of all puts and would not trace any other requests.
*/
public interface Sampler {
public static final Sampler> ALWAYS = AlwaysSampler.INSTANCE;
public static final Sampler> NEVER = NeverSampler.INSTANCE;
public boolean next(T info);
}
incubator-htrace-3.1.0/htrace-core/src/main/java/org/apache/htrace/SamplerBuilder.java 0000664 0000000 0000000 00000006240 12456011105 0030625 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.htrace;
import java.lang.reflect.Constructor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.htrace.impl.AlwaysSampler;
import org.apache.htrace.impl.NeverSampler;
/**
* A {@link Sampler} builder. It reads a {@link Sampler} class name from the provided
* configuration using the {@link #SAMPLER_CONF_KEY} key. Unqualified class names
* are interpreted as members of the {@code org.apache.htrace.impl} package. The {@link #build()}
* method constructs an instance of that class, initialized with the same configuration.
*/
public class SamplerBuilder {
// TODO: should follow the same API as SpanReceiverBuilder
public final static String SAMPLER_CONF_KEY = "sampler";
private final static String DEFAULT_PACKAGE = "org.apache.htrace.impl";
private final static ClassLoader classLoader =
SamplerBuilder.class.getClassLoader();
private final HTraceConfiguration conf;
private static final Log LOG = LogFactory.getLog(SamplerBuilder.class);
public SamplerBuilder(HTraceConfiguration conf) {
this.conf = conf;
}
public Sampler build() {
String str = conf.get(SAMPLER_CONF_KEY);
if (str.isEmpty()) {
return NeverSampler.INSTANCE;
}
if (!str.contains(".")) {
str = DEFAULT_PACKAGE + "." + str;
}
Class cls = null;
try {
cls = classLoader.loadClass(str);
} catch (ClassNotFoundException e) {
LOG.error("SamplerBuilder cannot find sampler class " + str +
": falling back on NeverSampler.");
return NeverSampler.INSTANCE;
}
Constructor ctor = null;
try {
ctor = cls.getConstructor(HTraceConfiguration.class);
} catch (NoSuchMethodException e) {
LOG.error("SamplerBuilder cannot find a constructor for class " + str +
"which takes an HTraceConfiguration. Falling back on " +
"NeverSampler.");
return NeverSampler.INSTANCE;
}
try {
return ctor.newInstance(conf);
} catch (ReflectiveOperationException e) {
LOG.error("SamplerBuilder reflection error when constructing " + str +
". Falling back on NeverSampler.", e);
return NeverSampler.INSTANCE;
} catch (Throwable e) {
LOG.error("SamplerBuilder constructor error when constructing " + str +
". Falling back on NeverSampler.", e);
return NeverSampler.INSTANCE;
}
}
}
incubator-htrace-3.1.0/htrace-core/src/main/java/org/apache/htrace/Span.java 0000664 0000000 0000000 00000011520 12456011105 0026611 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.htrace;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* Base interface for gathering and reporting statistics about a block of
* execution.
*
* Spans form a tree structure with the parent relationship. The first span in a
* trace has no parent span.
*/
@JsonSerialize(using = Span.SpanSerializer.class)
public interface Span {
public static final long ROOT_SPAN_ID = 0x74ace;
/**
* The block has completed, stop the clock
*/
void stop();
/**
* Get the start time, in milliseconds
*/
long getStartTimeMillis();
/**
* Get the stop time, in milliseconds
*/
long getStopTimeMillis();
/**
* Return the total amount of time elapsed since start was called, if running,
* or difference between stop and start
*/
long getAccumulatedMillis();
/**
* Has the span been started and not yet stopped?
*/
boolean isRunning();
/**
* Return a textual description of this span
*/
String getDescription();
/**
* A pseudo-unique (random) number assigned to this span instance
*/
long getSpanId();
/**
* A pseudo-unique (random) number assigned to the trace associated with this
* span
*/
long getTraceId();
/**
* Create a child span of this span with the given description
*/
Span child(String description);
@Override
String toString();
/**
* Return the pseudo-unique (random) number of the first parent span, returns
* ROOT_SPAN_ID if there are no parents.
*/
long getParentId();
/**
* Add a data annotation associated with this span
*/
void addKVAnnotation(byte[] key, byte[] value);
/**
* Add a timeline annotation associated with this span
*/
void addTimelineAnnotation(String msg);
/**
* Get data associated with this span (read only)
*/
Map getKVAnnotations();
/**
* Get any timeline annotations (read only)
*/
List getTimelineAnnotations();
/**
* Return a unique id for the node or process from which this Span originated.
* IP address is a reasonable choice.
*
* @return
*/
String getProcessId();
/**
* Serialize to Json
*/
String toJson();
public static class SpanSerializer extends JsonSerializer {
@Override
public void serialize(Span span, JsonGenerator jgen, SerializerProvider provider)
throws IOException {
jgen.writeStartObject();
jgen.writeStringField("i", String.format("%016x", span.getTraceId()));
jgen.writeStringField("s", String.format("%016x", span.getSpanId()));
jgen.writeNumberField("b", span.getStartTimeMillis());
jgen.writeNumberField("e", span.getStopTimeMillis());
jgen.writeStringField("d", span.getDescription());
jgen.writeStringField("r", span.getProcessId());
jgen.writeArrayFieldStart("p");
if (span.getParentId() != ROOT_SPAN_ID) {
jgen.writeString(String.format("%016x", span.getParentId()));
}
jgen.writeEndArray();
Map traceInfoMap = span.getKVAnnotations();
if (!traceInfoMap.isEmpty()) {
jgen.writeObjectFieldStart("n");
for (Map.Entry e : traceInfoMap.entrySet()) {
jgen.writeStringField(new String(e.getKey(), "UTF-8"),
new String(e.getValue(), "UTF-8"));
}
jgen.writeEndObject();
}
List timelineAnnotations =
span.getTimelineAnnotations();
if (!timelineAnnotations.isEmpty()) {
jgen.writeArrayFieldStart("t");
for (TimelineAnnotation tl : timelineAnnotations) {
jgen.writeStartObject();
jgen.writeNumberField("t", tl.getTime());
jgen.writeStringField("m", tl.getMessage());
jgen.writeEndObject();
}
jgen.writeEndArray();
}
jgen.writeEndObject();
}
}
}
incubator-htrace-3.1.0/htrace-core/src/main/java/org/apache/htrace/SpanReceiver.java 0000664 0000000 0000000 00000002756 12456011105 0030311 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.htrace;
import java.io.Closeable;
/**
* The collector within a process that is the destination of Spans when a trace is running.
* {@code SpanReceiver} implementations are expected to provide a constructor with the signature
*
*
* public SpanReceiverImpl(HTraceConfiguration)
*
* The helper class {@link org.apache.htrace.SpanReceiverBuilder} provides convenient factory
* methods for creating {@code SpanReceiver} instances from configuration.
* @see org.apache.htrace.SpanReceiverBuilder
*/
public interface SpanReceiver extends Closeable {
/**
* Called when a Span is stopped and can now be stored.
*/
public void receiveSpan(Span span);
}
incubator-htrace-3.1.0/htrace-core/src/main/java/org/apache/htrace/SpanReceiverBuilder.java 0000664 0000000 0000000 00000010261 12456011105 0031606 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.htrace;
import java.lang.reflect.Constructor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* A {@link SpanReceiver} builder. It reads a {@link SpanReceiver} class name from the provided
* configuration using the {@link #SPAN_RECEIVER_CONF_KEY} key. Unqualified class names
* are interpreted as members of the {@code org.apache.htrace.impl} package. The {@link #build()}
* method constructs an instance of that class, initialized with the same configuration.
*/
public class SpanReceiverBuilder {
static final Log LOG = LogFactory.getLog(SpanReceiverBuilder.class);
public final static String SPAN_RECEIVER_CONF_KEY = "span.receiver";
private final static String DEFAULT_PACKAGE = "org.apache.htrace.impl";
private final static ClassLoader classLoader =
SpanReceiverBuilder.class.getClassLoader();
private final HTraceConfiguration conf;
private boolean logErrors;
private String spanReceiverClass;
public SpanReceiverBuilder(HTraceConfiguration conf) {
this.conf = conf;
reset();
}
/**
* Set this builder back to defaults. Any previous calls to {@link #spanReceiverClass(String)}
* are overridden by the value provided by configuration.
* @return This instance
*/
public SpanReceiverBuilder reset() {
this.logErrors = true;
this.spanReceiverClass = this.conf.get(SPAN_RECEIVER_CONF_KEY);
return this;
}
/**
* Override the {@code SpanReceiver} class name provided in configuration with a new value.
* @return This instance
*/
public SpanReceiverBuilder spanReceiverClass(final String spanReceiverClass) {
this.spanReceiverClass = spanReceiverClass;
return this;
}
/**
* Configure whether we should log errors during build().
* @return This instance
*/
public SpanReceiverBuilder logErrors(boolean logErrors) {
this.logErrors = logErrors;
return this;
}
private void logError(String errorStr) {
if (!logErrors) {
return;
}
LOG.error(errorStr);
}
private void logError(String errorStr, Throwable e) {
if (!logErrors) {
return;
}
LOG.error(errorStr, e);
}
public SpanReceiver build() {
if ((this.spanReceiverClass == null) ||
this.spanReceiverClass.isEmpty()) {
return null;
}
String str = spanReceiverClass;
if (!str.contains(".")) {
str = DEFAULT_PACKAGE + "." + str;
}
Class cls = null;
try {
cls = classLoader.loadClass(str);
} catch (ClassNotFoundException e) {
logError("SpanReceiverBuilder cannot find SpanReceiver class " + str +
": disabling span receiver.");
return null;
}
Constructor ctor = null;
try {
ctor = cls.getConstructor(HTraceConfiguration.class);
} catch (NoSuchMethodException e) {
logError("SpanReceiverBuilder cannot find a constructor for class " +
str + "which takes an HTraceConfiguration. Disabling span " +
"receiver.");
return null;
}
try {
return ctor.newInstance(conf);
} catch (ReflectiveOperationException e) {
logError("SpanReceiverBuilder reflection error when constructing " + str +
". Disabling span receiver.", e);
return null;
} catch (Throwable e) {
logError("SpanReceiverBuilder constructor error when constructing " + str +
". Disabling span receiver.", e);
return null;
}
}
} incubator-htrace-3.1.0/htrace-core/src/main/java/org/apache/htrace/TimelineAnnotation.java 0000664 0000000 0000000 00000002263 12456011105 0031515 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.htrace;
public class TimelineAnnotation {
private final long time;
private final String msg;
public TimelineAnnotation(long time, String msg) {
this.time = time;
this.msg = msg;
}
public long getTime() {
return time;
}
public String getMessage() {
return msg;
}
@Override
public String toString() {
return "@" + time + ": " + msg;
}
}
incubator-htrace-3.1.0/htrace-core/src/main/java/org/apache/htrace/Trace.java 0000664 0000000 0000000 00000014245 12456011105 0026755 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.htrace;
import org.apache.htrace.impl.MilliSpan;
import org.apache.htrace.impl.TrueIfTracingSampler;
import org.apache.htrace.wrappers.TraceCallable;
import org.apache.htrace.wrappers.TraceRunnable;
import java.security.SecureRandom;
import java.util.Random;
import java.util.concurrent.Callable;
/**
* The primary way to interact with the library. Provides methods to start
* spans, as well as set necessary tracing information.
*/
public class Trace {
private final static Random random = new SecureRandom();
/**
* Starts and returns a new span as the child of the current span if the
* default sampler (TrueIfTracingSampler) returns true, otherwise returns the
* NullSpan.
*
* @param description Description of the span to be created.
* @return
*/
public static TraceScope startSpan(String description) {
return startSpan(description, TrueIfTracingSampler.INSTANCE);
}
/**
* Starts and returns a new span as the child of the parameter 'parent'. This
* will always return a new span, even if tracing wasn't previously enabled for
* this thread.
*
* @param description Description of the span to be created.
* @param parent The parent that should be used to create the child span that is to
* be returned.
* @return
*/
public static TraceScope startSpan(String description, Span parent) {
if (parent == null) return startSpan(description);
return continueSpan(parent.child(description));
}
public static TraceScope startSpan(String description, TraceInfo tinfo) {
if (tinfo == null) return continueSpan(null);
Span newSpan = new MilliSpan(description, tinfo.traceId, tinfo.spanId,
random.nextLong(), Tracer.getProcessId());
return continueSpan(newSpan);
}
public static TraceScope startSpan(String description, Sampler s) {
return startSpan(description, s, null);
}
public static TraceScope startSpan(String description, Sampler s, TraceInfo tinfo) {
Span span = null;
if (isTracing() || s.next(tinfo)) {
span = new MilliSpan(description, tinfo.traceId, tinfo.spanId,
random.nextLong(), Tracer.getProcessId());
}
return continueSpan(span);
}
public static TraceScope startSpan(String description, Sampler s, T info) {
Span span = null;
if (isTracing() || s.next(info)) {
span = Tracer.getInstance().createNew(description);
}
return continueSpan(span);
}
/**
* Pick up an existing span from another thread.
*/
public static TraceScope continueSpan(Span s) {
// Return an empty TraceScope that does nothing on close
if (s == null) return NullScope.INSTANCE;
return Tracer.getInstance().continueSpan(s);
}
/**
* Set the processId to be used for all Spans created by this Tracer.
*
* @param processId
* @see Span.java
*/
public static void setProcessId(String processId) {
Tracer.processId = processId;
}
/**
* Removes the given SpanReceiver from the list of SpanReceivers.
*
* @param rcvr
*/
public static void removeReceiver(SpanReceiver rcvr) {
Tracer.getInstance().removeReceiver(rcvr);
}
/**
* Adds the given SpanReceiver to the current Tracer instance's list of
* SpanReceivers.
*
* @param rcvr
*/
public static void addReceiver(SpanReceiver rcvr) {
Tracer.getInstance().addReceiver(rcvr);
}
/**
* Adds a data annotation to the current span if tracing is currently on.
*/
public static void addKVAnnotation(byte[] key, byte[] value) {
Span s = currentSpan();
if (s != null) {
s.addKVAnnotation(key, value);
}
}
/**
* Annotate the current span with the given message.
*/
public static void addTimelineAnnotation(String msg) {
Span s = currentSpan();
if (s != null) {
s.addTimelineAnnotation(msg);
}
}
/**
* Returns true if the current thread is a part of a trace, false otherwise.
*
* @return
*/
public static boolean isTracing() {
return Tracer.getInstance().isTracing();
}
/**
* If we are tracing, return the current span, else null
*
* @return Span representing the current trace, or null if not tracing.
*/
public static Span currentSpan() {
return Tracer.getInstance().currentSpan();
}
/**
* Wrap the callable in a TraceCallable, if tracing.
*
* @param callable
* @return The callable provided, wrapped if tracing, 'callable' if not.
*/
public static Callable wrap(Callable callable) {
if (isTracing()) {
return new TraceCallable(Trace.currentSpan(), callable);
} else {
return callable;
}
}
/**
* Wrap the runnable in a TraceRunnable, if tracing
*
* @param runnable
* @return The runnable provided, wrapped if tracing, 'runnable' if not.
*/
public static Runnable wrap(Runnable runnable) {
if (isTracing()) {
return new TraceRunnable(Trace.currentSpan(), runnable);
} else {
return runnable;
}
}
/**
* Wrap the runnable in a TraceRunnable, if tracing
*
* @param description name of the span to be created.
* @param runnable
* @return The runnable provided, wrapped if tracing, 'runnable' if not.
*/
public static Runnable wrap(String description, Runnable runnable) {
if (isTracing()) {
return new TraceRunnable(Trace.currentSpan(), runnable, description);
} else {
return runnable;
}
}
}
incubator-htrace-3.1.0/htrace-core/src/main/java/org/apache/htrace/TraceInfo.java 0000664 0000000 0000000 00000002377 12456011105 0027574 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.htrace;
public class TraceInfo {
public final long traceId;
public final long spanId;
public TraceInfo(long traceId, long spanId) {
this.traceId = traceId;
this.spanId = spanId;
}
@Override
public String toString() {
return "TraceInfo(traceId=" + traceId + ", spanId=" + spanId + ")";
}
public static TraceInfo fromSpan(Span s) {
if (s == null) return null;
return new TraceInfo(s.getTraceId(), s.getSpanId());
}
}
incubator-htrace-3.1.0/htrace-core/src/main/java/org/apache/htrace/TraceScope.java 0000664 0000000 0000000 00000004223 12456011105 0027742 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.htrace;
import java.io.Closeable;
public class TraceScope implements Closeable {
/**
* the span for this scope
*/
private final Span span;
/**
* the span that was "current" before this scope was entered
*/
private final Span savedSpan;
private boolean detached = false;
TraceScope(Span span, Span saved) {
this.span = span;
this.savedSpan = saved;
}
public Span getSpan() {
return span;
}
/**
* Remove this span as the current thread, but don't stop it yet or
* send it for collection. This is useful if the span object is then
* passed to another thread for use with Trace.continueTrace().
*
* @return the same Span object
*/
public Span detach() {
detached = true;
Span cur = Tracer.getInstance().currentSpan();
if (cur != span) {
Tracer.LOG.debug("Closing trace span " + span + " but " +
cur + " was top-of-stack");
} else {
Tracer.getInstance().setCurrentSpan(savedSpan);
}
return span;
}
/**
* Return true when {@link #detach()} has been called. Helpful when debugging
* multiple threads working on a single span.
*/
public boolean isDetached() {
return detached;
}
@Override
public void close() {
if (span == null) return;
if (!detached) {
// The span is done
span.stop();
detach();
}
}
}
incubator-htrace-3.1.0/htrace-core/src/main/java/org/apache/htrace/TraceTree.java 0000664 0000000 0000000 00000011154 12456011105 0027571 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.htrace;
import org.apache.htrace.impl.MilliSpan;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.TreeSet;
/**
* Used to create the graph formed by spans.
*/
public class TraceTree {
public static final Log LOG = LogFactory.getLog(Tracer.class);
public static class SpansByParent {
private static Comparator COMPARATOR =
new Comparator() {
@Override
public int compare(Span a, Span b) {
if (a.getParentId() < b.getParentId()) {
return -1;
} else if (a.getParentId() > b.getParentId()) {
return 1;
} else if (a.getSpanId() < b.getSpanId()) {
return -1;
} else if (a.getSpanId() > b.getSpanId()) {
return 1;
} else {
return 0;
}
}
};
private final TreeSet treeSet;
SpansByParent(Collection spans) {
TreeSet treeSet = new TreeSet(COMPARATOR);
for (Span span : spans) {
treeSet.add(span);
}
this.treeSet = treeSet;
}
public List find(long parentId) {
List spans = new ArrayList();
Span span = new MilliSpan("", Long.MIN_VALUE,
parentId, Long.MIN_VALUE, "");
while (true) {
span = treeSet.higher(span);
if (span == null) {
break;
}
if (span.getParentId() != parentId) {
break;
}
spans.add(span);
}
return spans;
}
public Iterator iterator() {
return Collections.unmodifiableSortedSet(treeSet).iterator();
}
}
public static class SpansByProcessId {
private static Comparator COMPARATOR =
new Comparator() {
@Override
public int compare(Span a, Span b) {
int cmp = a.getProcessId().compareTo(b.getProcessId());
if (cmp != 0) {
return cmp;
} else if (a.getSpanId() < b.getSpanId()) {
return -1;
} else if (a.getSpanId() > b.getSpanId()) {
return 1;
} else {
return 0;
}
}
};
private final TreeSet treeSet;
SpansByProcessId(Collection spans) {
TreeSet treeSet = new TreeSet(COMPARATOR);
for (Span span : spans) {
treeSet.add(span);
}
this.treeSet = treeSet;
}
public List find(String processId) {
List spans = new ArrayList();
Span span = new MilliSpan("", Long.MIN_VALUE,
Long.MIN_VALUE, Long.MIN_VALUE, processId);
while (true) {
span = treeSet.higher(span);
if (span == null) {
break;
}
if (span.getProcessId().equals(processId)) {
break;
}
spans.add(span);
}
return spans;
}
public Iterator iterator() {
return Collections.unmodifiableSortedSet(treeSet).iterator();
}
}
private final SpansByParent spansByParent;
private final SpansByProcessId spansByProcessId;
/**
* Create a new TraceTree
*
* @param spans The collection of spans to use to create this TraceTree. Should
* have at least one root span (span with parentId =
* Span.ROOT_SPAN_ID
*/
public TraceTree(Collection spans) {
this.spansByParent = new SpansByParent(spans);
this.spansByProcessId = new SpansByProcessId(spans);
}
public SpansByParent getSpansByParent() {
return spansByParent;
}
public SpansByProcessId getSpansByProcessId() {
return spansByProcessId;
}
}
incubator-htrace-3.1.0/htrace-core/src/main/java/org/apache/htrace/Tracer.java 0000664 0000000 0000000 00000007222 12456011105 0027134 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.htrace;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.htrace.impl.MilliSpan;
import java.security.SecureRandom;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* A Tracer provides the implementation for collecting and distributing Spans
* within a process.
*/
public class Tracer {
public static final Log LOG = LogFactory.getLog(Tracer.class);
private final static Random random = new SecureRandom();
private final List receivers = new CopyOnWriteArrayList();
private static final ThreadLocal currentSpan = new ThreadLocal() {
@Override
protected Span initialValue() {
return null;
}
};
public static final TraceInfo DONT_TRACE = new TraceInfo(-1, -1);
protected static String processId = null;
/**
* Internal class for defered singleton idiom.
*
* https://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom
*/
private static class TracerHolder {
private static final Tracer INSTANCE = new Tracer();
}
public static Tracer getInstance() {
return TracerHolder.INSTANCE;
}
protected Span createNew(String description) {
Span parent = currentSpan.get();
if (parent == null) {
return new MilliSpan(description,
/* traceId = */ random.nextLong(),
/* parentSpanId = */ Span.ROOT_SPAN_ID,
/* spanId = */ random.nextLong(),
getProcessId());
} else {
return parent.child(description);
}
}
protected boolean isTracing() {
return currentSpan.get() != null;
}
protected Span currentSpan() {
return currentSpan.get();
}
public void deliver(Span span) {
for (SpanReceiver receiver : receivers) {
receiver.receiveSpan(span);
}
}
protected void addReceiver(SpanReceiver receiver) {
receivers.add(receiver);
}
protected void removeReceiver(SpanReceiver receiver) {
receivers.remove(receiver);
}
protected Span setCurrentSpan(Span span) {
if (LOG.isTraceEnabled()) {
LOG.trace("setting current span " + span);
}
currentSpan.set(span);
return span;
}
public TraceScope continueSpan(Span s) {
Span oldCurrent = currentSpan();
setCurrentSpan(s);
return new TraceScope(s, oldCurrent);
}
protected int numReceivers() {
return receivers.size();
}
static String getProcessId() {
if (processId == null) {
String cmdLine = System.getProperty("sun.java.command");
if (cmdLine != null && !cmdLine.isEmpty()) {
String fullClassName = cmdLine.split("\\s+")[0];
String[] classParts = fullClassName.split("\\.");
cmdLine = classParts[classParts.length - 1];
}
processId = (cmdLine == null || cmdLine.isEmpty()) ? "Unknown" : cmdLine;
}
return processId;
}
}
incubator-htrace-3.1.0/htrace-core/src/main/java/org/apache/htrace/impl/ 0000775 0000000 0000000 00000000000 12456011105 0026007 5 ustar 00root root 0000000 0000000 incubator-htrace-3.1.0/htrace-core/src/main/java/org/apache/htrace/impl/AlwaysSampler.java 0000664 0000000 0000000 00000002313 12456011105 0031435 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.htrace.impl;
import org.apache.htrace.HTraceConfiguration;
import org.apache.htrace.Sampler;
/**
* A Sampler that always returns true.
*/
public final class AlwaysSampler implements Sampler