HTRACE-211. Move htrace-core classes to the org.apache.htrace.core namespace (cmccabe)
Project: http://git-wip-us.apache.org/repos/asf/incubator-htrace/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-htrace/commit/fd889b65 Tree: http://git-wip-us.apache.org/repos/asf/incubator-htrace/tree/fd889b65 Diff: http://git-wip-us.apache.org/repos/asf/incubator-htrace/diff/fd889b65 Branch: refs/heads/master Commit: fd889b659604c227045200fce4fd8eadf85e7166 Parents: afa0b71 Author: Colin P. Mccabe <[email protected]> Authored: Tue Aug 18 11:03:37 2015 -0700 Committer: Colin P. Mccabe <[email protected]> Committed: Tue Aug 18 11:13:10 2015 -0700 ---------------------------------------------------------------------- .../org/apache/htrace/HTraceConfiguration.java | 109 ------ .../main/java/org/apache/htrace/NullScope.java | 44 --- .../main/java/org/apache/htrace/Sampler.java | 42 --- .../java/org/apache/htrace/SamplerBuilder.java | 92 ----- .../src/main/java/org/apache/htrace/Span.java | 192 ---------- .../src/main/java/org/apache/htrace/SpanId.java | 149 -------- .../java/org/apache/htrace/SpanReceiver.java | 39 -- .../org/apache/htrace/SpanReceiverBuilder.java | 138 -------- .../org/apache/htrace/TimelineAnnotation.java | 40 --- .../src/main/java/org/apache/htrace/Trace.java | 223 ------------ .../main/java/org/apache/htrace/TraceScope.java | 99 ------ .../src/main/java/org/apache/htrace/Tracer.java | 130 ------- .../org/apache/htrace/core/AlwaysSampler.java | 33 ++ .../org/apache/htrace/core/CountSampler.java | 39 ++ .../apache/htrace/core/HTraceConfiguration.java | 109 ++++++ .../htrace/core/LocalFileSpanReceiver.java | 261 ++++++++++++++ .../java/org/apache/htrace/core/MilliSpan.java | 348 ++++++++++++++++++ .../org/apache/htrace/core/NeverSampler.java | 34 ++ .../java/org/apache/htrace/core/NullScope.java | 44 +++ .../apache/htrace/core/POJOSpanReceiver.java | 49 +++ .../apache/htrace/core/ProbabilitySampler.java | 46 +++ .../java/org/apache/htrace/core/Sampler.java | 39 ++ .../org/apache/htrace/core/SamplerBuilder.java | 91 +++++ .../main/java/org/apache/htrace/core/Span.java | 192 ++++++++++ .../java/org/apache/htrace/core/SpanId.java | 149 ++++++++ .../org/apache/htrace/core/SpanReceiver.java | 39 ++ .../apache/htrace/core/SpanReceiverBuilder.java | 138 ++++++++ .../htrace/core/StandardOutSpanReceiver.java | 42 +++ .../apache/htrace/core/TimelineAnnotation.java | 40 +++ .../main/java/org/apache/htrace/core/Trace.java | 219 ++++++++++++ .../org/apache/htrace/core/TraceCallable.java | 65 ++++ .../htrace/core/TraceExecutorService.java | 118 +++++++ .../java/org/apache/htrace/core/TraceProxy.java | 58 +++ .../org/apache/htrace/core/TraceRunnable.java | 64 ++++ .../java/org/apache/htrace/core/TraceScope.java | 99 ++++++ .../java/org/apache/htrace/core/Tracer.java | 129 +++++++ .../java/org/apache/htrace/core/TracerId.java | 290 +++++++++++++++ .../org/apache/htrace/impl/AlwaysSampler.java | 36 -- .../org/apache/htrace/impl/CountSampler.java | 43 --- .../htrace/impl/LocalFileSpanReceiver.java | 264 -------------- .../java/org/apache/htrace/impl/MilliSpan.java | 352 ------------------- .../org/apache/htrace/impl/NeverSampler.java | 37 -- .../apache/htrace/impl/POJOSpanReceiver.java | 53 --- .../apache/htrace/impl/ProbabilitySampler.java | 48 --- .../htrace/impl/StandardOutSpanReceiver.java | 45 --- .../java/org/apache/htrace/impl/TracerId.java | 291 --------------- .../apache/htrace/wrappers/TraceCallable.java | 69 ---- .../htrace/wrappers/TraceExecutorService.java | 118 ------- .../org/apache/htrace/wrappers/TraceProxy.java | 62 ---- .../apache/htrace/wrappers/TraceRunnable.java | 68 ---- .../java/org/apache/htrace/TestBadClient.java | 154 -------- .../org/apache/htrace/TestCountSampler.java | 43 --- .../test/java/org/apache/htrace/TestHTrace.java | 118 ------- .../apache/htrace/TestHTraceConfiguration.java | 63 ---- .../java/org/apache/htrace/TestNullScope.java | 37 -- .../java/org/apache/htrace/TestSampler.java | 59 ---- .../test/java/org/apache/htrace/TestSpanId.java | 72 ---- .../apache/htrace/TestSpanReceiverBuilder.java | 140 -------- .../java/org/apache/htrace/TraceCreator.java | 169 --------- .../test/java/org/apache/htrace/TraceGraph.java | 179 ---------- .../org/apache/htrace/core/TestBadClient.java | 146 ++++++++ .../apache/htrace/core/TestCountSampler.java | 41 +++ .../java/org/apache/htrace/core/TestHTrace.java | 116 ++++++ .../htrace/core/TestHTraceConfiguration.java | 62 ++++ .../htrace/core/TestLocalFileSpanReceiver.java | 70 ++++ .../org/apache/htrace/core/TestMilliSpan.java | 145 ++++++++ .../org/apache/htrace/core/TestNullScope.java | 34 ++ .../org/apache/htrace/core/TestSampler.java | 55 +++ .../java/org/apache/htrace/core/TestSpanId.java | 72 ++++ .../htrace/core/TestSpanReceiverBuilder.java | 139 ++++++++ .../org/apache/htrace/core/TestTracerId.java | 47 +++ .../org/apache/htrace/core/TraceCreator.java | 169 +++++++++ .../java/org/apache/htrace/core/TraceGraph.java | 176 ++++++++++ .../htrace/impl/TestLocalFileSpanReceiver.java | 75 ---- .../org/apache/htrace/impl/TestMilliSpan.java | 148 -------- .../org/apache/htrace/impl/TestTracerId.java | 47 --- 76 files changed, 4007 insertions(+), 4087 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/main/java/org/apache/htrace/HTraceConfiguration.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/HTraceConfiguration.java b/htrace-core/src/main/java/org/apache/htrace/HTraceConfiguration.java deleted file mode 100644 index 4580dff..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/HTraceConfiguration.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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 java.util.HashMap; -import java.util.Map; - -/** - * Wrapper which integrating applications should implement in order - * to provide tracing configuration. - */ -public abstract class HTraceConfiguration { - - private static final Log LOG = LogFactory.getLog(HTraceConfiguration.class); - - private static final Map<String, String> EMPTY_MAP = new HashMap<String, String>(1); - - /** - * An empty HTrace configuration. - */ - public static final HTraceConfiguration EMPTY = fromMap(EMPTY_MAP); - - /** - * Create an HTrace configuration from a map. - * - * @param conf The map to create the configuration from. - * @return The new configuration. - */ - public static HTraceConfiguration fromMap(Map<String, String> conf) { - return new MapConf(conf); - } - - public static HTraceConfiguration fromKeyValuePairs(String... pairs) { - if ((pairs.length % 2) != 0) { - throw new RuntimeException("You must specify an equal number of keys " + - "and values."); - } - Map<String, String> conf = new HashMap<String, String>(); - for (int i = 0; i < pairs.length; i+=2) { - conf.put(pairs[i], pairs[i + 1]); - } - return new MapConf(conf); - } - - public abstract String get(String key); - - public abstract String get(String key, String defaultValue); - - public boolean getBoolean(String key, boolean defaultValue) { - String value = get(key, String.valueOf(defaultValue)).trim().toLowerCase(); - - if ("true".equals(value)) { - return true; - } else if ("false".equals(value)) { - return false; - } - - LOG.warn("Expected boolean for key [" + key + "] instead got [" + value + "]."); - return defaultValue; - } - - public int getInt(String key, int defaultVal) { - String val = get(key); - if (val == null || val.trim().isEmpty()) { - return defaultVal; - } - try { - return Integer.parseInt(val); - } catch (NumberFormatException nfe) { - throw new IllegalArgumentException("Bad value for '" + key + "': should be int"); - } - } - - private static class MapConf extends HTraceConfiguration { - private final Map<String, String> conf; - - public MapConf(Map<String, String> conf) { - this.conf = new HashMap<String, String>(conf); - } - - @Override - public String get(String key) { - return conf.get(key); - } - - @Override - public String get(String key, String defaultValue) { - String value = get(key); - return value == null ? defaultValue : value; - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/main/java/org/apache/htrace/NullScope.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/NullScope.java b/htrace-core/src/main/java/org/apache/htrace/NullScope.java deleted file mode 100644 index ff9a42c..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/NullScope.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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; - -/** - * Singleton instance representing an empty {@link TraceScope}. - */ -public final class NullScope extends TraceScope { - - public static final TraceScope INSTANCE = new NullScope(); - - private NullScope() { - super(null, null); - } - - @Override - public Span detach() { - return null; - } - - @Override - public void close() { - return; - } - - @Override - public String toString() { - return "NullScope"; - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/main/java/org/apache/htrace/Sampler.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/Sampler.java b/htrace-core/src/main/java/org/apache/htrace/Sampler.java deleted file mode 100644 index 3bf62aa..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/Sampler.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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.AlwaysSampler; -import org.apache.htrace.impl.NeverSampler; - -/** - * Extremely simple callback to determine the frequency that an action should be - * performed. - * <p/> - * For example, the next() function may look like this: - * <p/> - * <pre> - * <code> - * public boolean next() { - * return Math.random() > 0.5; - * } - * </code> - * </pre> - * 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(); -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/main/java/org/apache/htrace/SamplerBuilder.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/SamplerBuilder.java b/htrace-core/src/main/java/org/apache/htrace/SamplerBuilder.java deleted file mode 100644 index 4364671..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/SamplerBuilder.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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() { - Sampler sampler = newSampler(); - if (LOG.isTraceEnabled()) { - LOG.trace("Created new sampler of type " + - sampler.getClass().getName(), new Exception()); - } - return sampler; - } - - private Sampler newSampler() { - String str = conf.get(SAMPLER_CONF_KEY); - if (str == null || 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<Sampler> 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; - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/main/java/org/apache/htrace/Span.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/Span.java b/htrace-core/src/main/java/org/apache/htrace/Span.java deleted file mode 100644 index 0897ee9..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/Span.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * 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. - * <p/> - * Spans should form a directed acyclic graph structure. It should be possible - * to keep following the parents of a span until you arrive at a span with no - * parents.<p/> - */ -@JsonSerialize(using = Span.SpanSerializer.class) -public interface Span { - /** - * 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.<p/> - * - * Will never be null. - */ - String getDescription(); - - /** - * A pseudo-unique (random) number assigned to this span instance.<p/> - * - * The spanId is immutable and cannot be changed. It is safe to access this - * from multiple threads. - */ - SpanId getSpanId(); - - /** - * Create a child span of this span with the given description - */ - Span child(String description); - - @Override - String toString(); - - /** - * Returns the parent IDs of the span.<p/> - * - * The array will be empty if there are no parents. - */ - SpanId[] getParents(); - - /** - * Set the parents of this span.<p/> - * - * Any existing parents will be cleared by this call. - */ - void setParents(SpanId[] parents); - - /** - * Add a data annotation associated with this span - */ - void addKVAnnotation(String key, String value); - - /** - * Add a timeline annotation associated with this span - */ - void addTimelineAnnotation(String msg); - - /** - * Get data associated with this span (read only)<p/> - * - * Will never be null. - */ - Map<String, String> getKVAnnotations(); - - /** - * Get any timeline annotations (read only)<p/> - * - * Will never be null. - */ - List<TimelineAnnotation> getTimelineAnnotations(); - - /** - * Return a unique id for the process from which this Span originated.<p/> - * - * Will never be null. - */ - String getTracerId(); - - /** - * Set the process id of a span. - */ - void setTracerId(String s); - - /** - * Serialize to Json - */ - String toJson(); - - public static class SpanSerializer extends JsonSerializer<Span> { - @Override - public void serialize(Span span, JsonGenerator jgen, SerializerProvider provider) - throws IOException { - jgen.writeStartObject(); - if (span.getSpanId().isValid()) { - jgen.writeStringField("a", span.getSpanId().toString()); - } - if (span.getStartTimeMillis() != 0) { - jgen.writeNumberField("b", span.getStartTimeMillis()); - } - if (span.getStopTimeMillis() != 0) { - jgen.writeNumberField("e", span.getStopTimeMillis()); - } - if (!span.getDescription().isEmpty()) { - jgen.writeStringField("d", span.getDescription()); - } - String tracerId = span.getTracerId(); - if (!tracerId.isEmpty()) { - jgen.writeStringField("r", tracerId); - } - jgen.writeArrayFieldStart("p"); - for (SpanId parent : span.getParents()) { - jgen.writeString(parent.toString()); - } - jgen.writeEndArray(); - Map<String, String> traceInfoMap = span.getKVAnnotations(); - if (!traceInfoMap.isEmpty()) { - jgen.writeObjectFieldStart("n"); - for (Map.Entry<String, String> e : traceInfoMap.entrySet()) { - jgen.writeStringField(e.getKey(), e.getValue()); - } - jgen.writeEndObject(); - } - List<TimelineAnnotation> 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(); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/main/java/org/apache/htrace/SpanId.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/SpanId.java b/htrace-core/src/main/java/org/apache/htrace/SpanId.java deleted file mode 100644 index 25dc108..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/SpanId.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * 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.math.BigInteger; -import java.lang.Void; -import java.util.concurrent.ThreadLocalRandom; -import java.util.Random; - -/** - * Uniquely identifies an HTrace span. - * - * Span IDs are 128 bits in total. The upper 64 bits of a span ID is the same - * as the upper 64 bits of the parent span, if there is one. The lower 64 bits - * are always random. - */ -public final class SpanId implements Comparable<SpanId> { - private static final int SPAN_ID_STRING_LENGTH = 32; - private final long high; - private final long low; - - /** - * The invalid span ID, which is all zeroes. - * - * It is also the "least" span ID in the sense that it is considered - * smaller than any other span ID. - */ - public static SpanId INVALID = new SpanId(0, 0); - - private static long nonZeroRand64() { - while (true) { - long r = ThreadLocalRandom.current().nextLong(); - if (r != 0) { - return r; - } - } - } - - public static SpanId fromRandom() { - return new SpanId(nonZeroRand64(), nonZeroRand64()); - } - - public static SpanId fromString(String str) { - if (str.length() != SPAN_ID_STRING_LENGTH) { - throw new RuntimeException("Invalid SpanID string: length was not " + - SPAN_ID_STRING_LENGTH); - } - long high = - ((Long.parseLong(str.substring(0, 8), 16)) << 32) | - (Long.parseLong(str.substring(8, 16), 16)); - long low = - ((Long.parseLong(str.substring(16, 24), 16)) << 32) | - (Long.parseLong(str.substring(24, 32), 16)); - return new SpanId(high, low); - } - - public SpanId(long high, long low) { - this.high = high; - this.low = low; - } - - public long getHigh() { - return high; - } - - public long getLow() { - return low; - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof SpanId)) { - return false; - } - SpanId other = (SpanId)o; - return ((other.high == high) && (other.low == low)); - } - - @Override - public int compareTo(SpanId other) { - int cmp = compareAsUnsigned(high, other.high); - if (cmp != 0) { - return cmp; - } - return compareAsUnsigned(low, other.low); - } - - private static int compareAsUnsigned(long a, long b) { - boolean aSign = a < 0; - boolean bSign = b < 0; - if (aSign != bSign) { - if (aSign) { - return 1; - } else { - return -1; - } - } - if (aSign) { - a = -a; - b = -b; - } - if (a < b) { - return -1; - } else if (a > b) { - return 1; - } else { - return 0; - } - } - - @Override - public int hashCode() { - return (int)((0xffffffff & (high >> 32))) ^ - (int)((0xffffffff & (high >> 0))) ^ - (int)((0xffffffff & (low >> 32))) ^ - (int)((0xffffffff & (low >> 0))); - } - - @Override - public String toString() { - return String.format("%08x%08x%08x%08x", - (0x00000000ffffffffL & (high >> 32)), - (0x00000000ffffffffL & high), - (0x00000000ffffffffL & (low >> 32)), - (0x00000000ffffffffL & low)); - } - - public boolean isValid() { - return (high != 0) || (low != 0); - } - - public SpanId newChildId() { - return new SpanId(high, nonZeroRand64()); - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/main/java/org/apache/htrace/SpanReceiver.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/SpanReceiver.java b/htrace-core/src/main/java/org/apache/htrace/SpanReceiver.java deleted file mode 100644 index 7ae157b..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/SpanReceiver.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 - * <p> - * <pre> - * <code>public SpanReceiverImpl(HTraceConfiguration)</code> - * </pre> - * 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); -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/main/java/org/apache/htrace/SpanReceiverBuilder.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/SpanReceiverBuilder.java b/htrace-core/src/main/java/org/apache/htrace/SpanReceiverBuilder.java deleted file mode 100644 index 15b3af0..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/SpanReceiverBuilder.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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 { - private 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() { - SpanReceiver spanReceiver = newSpanReceiver(); - if (LOG.isTraceEnabled()) { - LOG.trace("Created new span receiver of type " + - ((spanReceiver == null) ? "(none)" : - spanReceiver.getClass().getName())); - } - return spanReceiver; - } - - private SpanReceiver newSpanReceiver() { - if ((this.spanReceiverClass == null) || - this.spanReceiverClass.isEmpty()) { - LOG.debug("No span receiver class specified."); - 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<SpanReceiver> 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 { - LOG.debug("Creating new instance of " + str + "..."); - 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; - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/main/java/org/apache/htrace/TimelineAnnotation.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/TimelineAnnotation.java b/htrace-core/src/main/java/org/apache/htrace/TimelineAnnotation.java deleted file mode 100644 index d0ae675..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/TimelineAnnotation.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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; - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/main/java/org/apache/htrace/Trace.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/Trace.java b/htrace-core/src/main/java/org/apache/htrace/Trace.java deleted file mode 100644 index e782309..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/Trace.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * 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 org.apache.htrace.impl.NeverSampler; -import org.apache.htrace.wrappers.TraceCallable; -import org.apache.htrace.wrappers.TraceRunnable; - -import java.util.concurrent.Callable; - -/** - * The Trace class is the primary way to interact with the library. It provides - * methods to create and manipulate spans. - * - * A 'Span' represents a length of time. It has many other attributes such as a - * description, ID, and even potentially a set of key/value strings attached to - * it. - * - * Each thread in your application has a single currently active currentSpan - * associated with it. When this is non-null, it represents the current - * operation that the thread is doing. Spans are NOT thread-safe, and must - * never be used by multiple threads at once. With care, it is possible to - * safely pass a Span object between threads, but in most cases this is not - * necessary. - * - * A 'TraceScope' can either be empty, or contain a Span. TraceScope objects - * implement the Java's Closeable interface. Similar to file descriptors, they - * must be closed after they are created. When a TraceScope contains a Span, - * this span is closed when the scope is closed. - * - * The 'startSpan' methods in this class do a few things: - * <ul> - * <li>Create a new Span which has this thread's currentSpan as one of its parents.</li> - * <li>Set currentSpan to the new Span.</li> - * <li>Create a TraceSpan object to manage the new Span.</li> - * </ul> - * - * Closing a TraceScope does a few things: - * <ul> - * <li>It closes the span which the scope was managing.</li> - * <li>Set currentSpan to the previous currentSpan (which may be null).</li> - * </ul> - */ -public class Trace { - private static final Log LOG = LogFactory.getLog(Trace.class); - - /** - * Creates a new trace scope. - * - * If this thread has a currently active trace span, the trace scope we create - * here will contain a new span descending from the currently active span. - * If there is no currently active trace span, the trace scope we create will - * be empty. - * - * @param description The description field for the new span to create. - */ - public static TraceScope startSpan(String description) { - return startSpan(description, NeverSampler.INSTANCE); - } - - public static TraceScope startSpan(String description, SpanId parentId) { - if (parentId == null) { - return continueSpan(null); - } - Span newSpan = new MilliSpan.Builder(). - begin(System.currentTimeMillis()). - end(0). - description(description). - spanId(parentId.newChildId()). - parents(new SpanId[] { parentId }). - build(); - return continueSpan(newSpan); - } - - /** - * Creates a new trace scope. - * - * If this thread has a currently active trace span, it must be the 'parent' - * span that you pass in here as a parameter. The trace scope we create here - * will contain a new span which is a child of 'parent'. - * - * @param description The description field for the new span to create. - */ - public static TraceScope startSpan(String description, Span parent) { - if (parent == null) { - return startSpan(description); - } - Span currentSpan = currentSpan(); - if ((currentSpan != null) && (currentSpan != parent)) { - Tracer.clientError("HTrace client error: thread " + - Thread.currentThread().getName() + " tried to start a new Span " + - "with parent " + parent.toString() + ", but there is already a " + - "currentSpan " + currentSpan); - } - return continueSpan(parent.child(description)); - } - - public static <T> TraceScope startSpan(String description, Sampler s) { - Span span = null; - if (isTracing() || s.next()) { - 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); - } - - /** - * Removes the given SpanReceiver from the list of SpanReceivers. - */ - public static void removeReceiver(SpanReceiver rcvr) { - Tracer.getInstance().removeReceiver(rcvr); - } - - /** - * Adds the given SpanReceiver to the current Tracer instance's list of - * SpanReceivers. - */ - 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(String key, String 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. - */ - 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. - * - * @return The callable provided, wrapped if tracing, 'callable' if not. - */ - public static <V> Callable<V> wrap(Callable<V> callable) { - if (isTracing()) { - return new TraceCallable<V>(Trace.currentSpan(), callable); - } else { - return callable; - } - } - - /** - * Wrap the runnable in a TraceRunnable, if tracing - * - * @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 The runnable that will have tracing info associated with it if tracing. - * @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; - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/main/java/org/apache/htrace/TraceScope.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/TraceScope.java b/htrace-core/src/main/java/org/apache/htrace/TraceScope.java deleted file mode 100644 index ab36feb..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/TraceScope.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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; -import java.lang.Thread; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -public class TraceScope implements Closeable { - private static final Log LOG = LogFactory.getLog(TraceScope.class); - - /** - * 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() { - if (detached) { - Tracer.clientError("Tried to detach trace span " + span + " but " + - "it has already been detached."); - } - detached = true; - - Span cur = Tracer.getInstance().currentSpan(); - if (cur != span) { - Tracer.clientError("Tried to detach trace span " + span + " but " + - "it is not the current span for the " + - Thread.currentThread().getName() + " thread. You have " + - "probably forgotten to close or detach " + cur); - } 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 (detached) { - return; - } - detached = true; - Span cur = Tracer.getInstance().currentSpan(); - if (cur != span) { - Tracer.clientError("Tried to close trace span " + span + " but " + - "it is not the current span for the " + - Thread.currentThread().getName() + " thread. You have " + - "probably forgotten to close or detach " + cur); - } else { - span.stop(); - Tracer.getInstance().setCurrentSpan(savedSpan); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/main/java/org/apache/htrace/Tracer.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/Tracer.java b/htrace-core/src/main/java/org/apache/htrace/Tracer.java deleted file mode 100644 index d07e1a8..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/Tracer.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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.util.List; -import java.util.Random; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.ThreadLocalRandom; - -/** - * A Tracer provides the implementation for collecting and distributing Spans - * within a process. - */ -public class Tracer { - private static final Log LOG = LogFactory.getLog(Tracer.class); - - static long nonZeroRandom64() { - long id; - Random random = ThreadLocalRandom.current(); - do { - id = random.nextLong(); - } while (id == 0); - return id; - } - - private final List<SpanReceiver> receivers = new CopyOnWriteArrayList<SpanReceiver>(); - private static final ThreadLocal<Span> currentSpan = new ThreadLocal<Span>() { - @Override - protected Span initialValue() { - return null; - } - }; - private static final SpanId EMPTY_PARENT_ARRAY[] = new SpanId[0]; - - /** - * Log a client error, and throw an exception. - * - * @param str The message to use in the log and the exception. - */ - static void clientError(String str) { - LOG.error(str); - throw new RuntimeException(str); - } - - /** - * Internal class for defered singleton idiom. - * <p/> - * 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.Builder(). - begin(System.currentTimeMillis()). - end(0). - description(description). - parents(EMPTY_PARENT_ARRAY). - spanId(SpanId.fromRandom()). - build(); - } 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(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/main/java/org/apache/htrace/core/AlwaysSampler.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/core/AlwaysSampler.java b/htrace-core/src/main/java/org/apache/htrace/core/AlwaysSampler.java new file mode 100644 index 0000000..a9259bd --- /dev/null +++ b/htrace-core/src/main/java/org/apache/htrace/core/AlwaysSampler.java @@ -0,0 +1,33 @@ +/* + * 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.core; + +/** + * A Sampler that always returns true. + */ +public final class AlwaysSampler implements Sampler { + + public static final AlwaysSampler INSTANCE = new AlwaysSampler(null); + + public AlwaysSampler(HTraceConfiguration conf) { + } + + @Override + public boolean next() { + return true; + } +} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/main/java/org/apache/htrace/core/CountSampler.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/core/CountSampler.java b/htrace-core/src/main/java/org/apache/htrace/core/CountSampler.java new file mode 100644 index 0000000..10d5c98 --- /dev/null +++ b/htrace-core/src/main/java/org/apache/htrace/core/CountSampler.java @@ -0,0 +1,39 @@ +/* + * 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.core; + +import java.util.concurrent.ThreadLocalRandom; + +/** + * Sampler that returns true every N calls. Specify the frequency interval by configuring a + * {@code long} value for {@link #SAMPLER_FREQUENCY_CONF_KEY}. + */ +public class CountSampler implements Sampler { + public final static String SAMPLER_FREQUENCY_CONF_KEY = "sampler.frequency"; + + final long frequency; + long count = ThreadLocalRandom.current().nextLong(); + + public CountSampler(HTraceConfiguration conf) { + this.frequency = Long.parseLong(conf.get(SAMPLER_FREQUENCY_CONF_KEY), 10); + } + + @Override + public boolean next() { + return (count++ % frequency) == 0; + } +} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/main/java/org/apache/htrace/core/HTraceConfiguration.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/core/HTraceConfiguration.java b/htrace-core/src/main/java/org/apache/htrace/core/HTraceConfiguration.java new file mode 100644 index 0000000..c6e445b --- /dev/null +++ b/htrace-core/src/main/java/org/apache/htrace/core/HTraceConfiguration.java @@ -0,0 +1,109 @@ +/* + * 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.core; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.HashMap; +import java.util.Map; + +/** + * Wrapper which integrating applications should implement in order + * to provide tracing configuration. + */ +public abstract class HTraceConfiguration { + + private static final Log LOG = LogFactory.getLog(HTraceConfiguration.class); + + private static final Map<String, String> EMPTY_MAP = new HashMap<String, String>(1); + + /** + * An empty HTrace configuration. + */ + public static final HTraceConfiguration EMPTY = fromMap(EMPTY_MAP); + + /** + * Create an HTrace configuration from a map. + * + * @param conf The map to create the configuration from. + * @return The new configuration. + */ + public static HTraceConfiguration fromMap(Map<String, String> conf) { + return new MapConf(conf); + } + + public static HTraceConfiguration fromKeyValuePairs(String... pairs) { + if ((pairs.length % 2) != 0) { + throw new RuntimeException("You must specify an equal number of keys " + + "and values."); + } + Map<String, String> conf = new HashMap<String, String>(); + for (int i = 0; i < pairs.length; i+=2) { + conf.put(pairs[i], pairs[i + 1]); + } + return new MapConf(conf); + } + + public abstract String get(String key); + + public abstract String get(String key, String defaultValue); + + public boolean getBoolean(String key, boolean defaultValue) { + String value = get(key, String.valueOf(defaultValue)).trim().toLowerCase(); + + if ("true".equals(value)) { + return true; + } else if ("false".equals(value)) { + return false; + } + + LOG.warn("Expected boolean for key [" + key + "] instead got [" + value + "]."); + return defaultValue; + } + + public int getInt(String key, int defaultVal) { + String val = get(key); + if (val == null || val.trim().isEmpty()) { + return defaultVal; + } + try { + return Integer.parseInt(val); + } catch (NumberFormatException nfe) { + throw new IllegalArgumentException("Bad value for '" + key + "': should be int"); + } + } + + private static class MapConf extends HTraceConfiguration { + private final Map<String, String> conf; + + public MapConf(Map<String, String> conf) { + this.conf = new HashMap<String, String>(conf); + } + + @Override + public String get(String key) { + return conf.get(key); + } + + @Override + public String get(String key, String defaultValue) { + String value = get(key); + return value == null ? defaultValue : value; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/main/java/org/apache/htrace/core/LocalFileSpanReceiver.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/core/LocalFileSpanReceiver.java b/htrace-core/src/main/java/org/apache/htrace/core/LocalFileSpanReceiver.java new file mode 100644 index 0000000..0aed846 --- /dev/null +++ b/htrace-core/src/main/java/org/apache/htrace/core/LocalFileSpanReceiver.java @@ -0,0 +1,261 @@ +/* + * 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.core; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.EOFException; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.file.FileSystems; +import java.nio.file.StandardOpenOption; +import java.util.UUID; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Writes the spans it receives to a local file. + */ +public class LocalFileSpanReceiver implements SpanReceiver { + private static final Log LOG = LogFactory.getLog(LocalFileSpanReceiver.class); + public static final String PATH_KEY = "local-file-span-receiver.path"; + public static final String CAPACITY_KEY = "local-file-span-receiver.capacity"; + public static final int CAPACITY_DEFAULT = 5000; + private static ObjectWriter JSON_WRITER = new ObjectMapper().writer(); + private final String path; + + private byte[][] bufferedSpans; + private int bufferedSpansIndex; + private final ReentrantLock bufferLock = new ReentrantLock(); + + private final FileOutputStream stream; + private final FileChannel channel; + private final ReentrantLock channelLock = new ReentrantLock(); + private final TracerId tracerId; + + public LocalFileSpanReceiver(HTraceConfiguration conf) { + int capacity = conf.getInt(CAPACITY_KEY, CAPACITY_DEFAULT); + if (capacity < 1) { + throw new IllegalArgumentException(CAPACITY_KEY + " must not be " + + "less than 1."); + } + this.path = conf.get(PATH_KEY); + if (path == null || path.isEmpty()) { + throw new IllegalArgumentException("must configure " + PATH_KEY); + } + boolean success = false; + try { + this.stream = new FileOutputStream(path, true); + } catch (IOException ioe) { + LOG.error("Error opening " + path + ": " + ioe.getMessage()); + throw new RuntimeException(ioe); + } + this.channel = stream.getChannel(); + if (this.channel == null) { + try { + this.stream.close(); + } catch (IOException e) { + LOG.error("Error closing " + path, e); + } + LOG.error("Failed to get channel for " + path); + throw new RuntimeException("Failed to get channel for " + path); + } + this.bufferedSpans = new byte[capacity][]; + this.bufferedSpansIndex = 0; + if (LOG.isDebugEnabled()) { + LOG.debug("Created new LocalFileSpanReceiver with path = " + path + + ", capacity = " + capacity); + } + this.tracerId = new TracerId(conf); + } + + /** + * Number of buffers to use in FileChannel#write. + * + * On UNIX, FileChannel#write uses writev-- a kernel interface that allows + * us to send multiple buffers at once. This is more efficient than making a + * separate write call for each buffer, since it minimizes the number of + * transitions from userspace to kernel space. + */ + private final int WRITEV_SIZE = 20; + + private final static ByteBuffer newlineBuf = + ByteBuffer.wrap(new byte[] { (byte)0xa }); + + /** + * Flushes a bufferedSpans array. + */ + private void doFlush(byte[][] toFlush, int len) throws IOException { + int bidx = 0, widx = 0; + ByteBuffer writevBufs[] = new ByteBuffer[2 * WRITEV_SIZE]; + + while (true) { + if (widx == writevBufs.length) { + channel.write(writevBufs); + widx = 0; + } + if (bidx == len) { + break; + } + writevBufs[widx] = ByteBuffer.wrap(toFlush[bidx]); + writevBufs[widx + 1] = newlineBuf; + bidx++; + widx+=2; + } + if (widx > 0) { + channel.write(writevBufs, 0, widx); + } + } + + @Override + public void receiveSpan(Span span) { + if (span.getTracerId().isEmpty()) { + span.setTracerId(tracerId.get()); + } + + // Serialize the span data into a byte[]. Note that we're not holding the + // lock here, to improve concurrency. + byte jsonBuf[] = null; + try { + jsonBuf = JSON_WRITER.writeValueAsBytes(span); + } catch (JsonProcessingException e) { + LOG.error("receiveSpan(path=" + path + ", span=" + span + "): " + + "Json processing error: " + e.getMessage()); + return; + } + + // Grab the bufferLock and put our jsonBuf into the list of buffers to + // flush. + byte toFlush[][] = null; + bufferLock.lock(); + try { + if (bufferedSpans == null) { + LOG.debug("receiveSpan(path=" + path + ", span=" + span + "): " + + "LocalFileSpanReceiver for " + path + " is closed."); + return; + } + bufferedSpans[bufferedSpansIndex] = jsonBuf; + bufferedSpansIndex++; + if (bufferedSpansIndex == bufferedSpans.length) { + // If we've hit the limit for the number of buffers to flush, + // swap out the existing bufferedSpans array for a new array, and + // prepare to flush those spans to disk. + toFlush = bufferedSpans; + bufferedSpansIndex = 0; + bufferedSpans = new byte[bufferedSpans.length][]; + } + } finally { + bufferLock.unlock(); + } + if (toFlush != null) { + // We released the bufferLock above, to avoid blocking concurrent + // receiveSpan calls. But now, we must take the channelLock, to make + // sure that we have sole access to the output channel. If we did not do + // this, we might get interleaved output. + // + // There is a small chance that another thread doing a flush of more + // recent spans could get ahead of us here, and take the lock before we + // do. This is ok, since spans don't have to be written out in order. + channelLock.lock(); + try { + doFlush(toFlush, toFlush.length); + } catch (IOException ioe) { + LOG.error("Error flushing buffers to " + path + ": " + + ioe.getMessage()); + } finally { + channelLock.unlock(); + } + } + } + + @Override + public void close() throws IOException { + byte toFlush[][] = null; + int numToFlush = 0; + bufferLock.lock(); + try { + if (bufferedSpans == null) { + LOG.info("LocalFileSpanReceiver for " + path + " was already closed."); + return; + } + numToFlush = bufferedSpansIndex; + bufferedSpansIndex = 0; + toFlush = bufferedSpans; + bufferedSpans = null; + } finally { + bufferLock.unlock(); + } + channelLock.lock(); + try { + doFlush(toFlush, numToFlush); + } catch (IOException ioe) { + LOG.error("Error flushing buffers to " + path + ": " + + ioe.getMessage()); + } finally { + try { + stream.close(); + } catch (IOException e) { + LOG.error("Error closing stream for " + path, e); + } + channelLock.unlock(); + } + } + + public static String getUniqueLocalTraceFileName() { + String tmp = System.getProperty("java.io.tmpdir", "/tmp"); + String nonce = null; + BufferedReader reader = null; + try { + // On Linux we can get a unique local file name by reading the process id + // out of /proc/self/stat. (There isn't any portable way to get the + // process ID from Java.) + reader = new BufferedReader( + new InputStreamReader(new FileInputStream("/proc/self/stat"), + "UTF-8")); + String line = reader.readLine(); + if (line == null) { + throw new EOFException(); + } + nonce = line.split(" ")[0]; + } catch (IOException e) { + } finally { + if (reader != null) { + try { + reader.close(); + } catch(IOException e) { + LOG.warn("Exception in closing " + reader, e); + } + } + } + if (nonce == null) { + // If we can't use the process ID, use a random nonce. + nonce = UUID.randomUUID().toString(); + } + return new File(tmp, nonce).getAbsolutePath(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/main/java/org/apache/htrace/core/MilliSpan.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/core/MilliSpan.java b/htrace-core/src/main/java/org/apache/htrace/core/MilliSpan.java new file mode 100644 index 0000000..49b5fbe --- /dev/null +++ b/htrace-core/src/main/java/org/apache/htrace/core/MilliSpan.java @@ -0,0 +1,348 @@ +/* + * 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.core; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * A Span implementation that stores its information in milliseconds since the + * epoch. + */ +@JsonDeserialize(using = MilliSpan.MilliSpanDeserializer.class) +public class MilliSpan implements Span { + private static ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static ObjectReader JSON_READER = OBJECT_MAPPER.reader(MilliSpan.class); + private static ObjectWriter JSON_WRITER = OBJECT_MAPPER.writer(); + private static final SpanId EMPTY_PARENT_ARRAY[] = new SpanId[0]; + private static final String EMPTY_STRING = ""; + + private long begin; + private long end; + private final String description; + private SpanId parents[]; + private final SpanId spanId; + private Map<String, String> traceInfo = null; + private String tracerId; + private List<TimelineAnnotation> timeline = null; + + @Override + public Span child(String childDescription) { + return new MilliSpan.Builder(). + begin(System.currentTimeMillis()). + end(0). + description(childDescription). + parents(new SpanId[] {spanId}). + spanId(spanId.newChildId()). + tracerId(tracerId). + build(); + } + + /** + * The public interface for constructing a MilliSpan. + */ + public static class Builder { + private long begin; + private long end; + private String description = EMPTY_STRING; + private SpanId parents[] = EMPTY_PARENT_ARRAY; + private SpanId spanId = SpanId.INVALID; + private Map<String, String> traceInfo = null; + private String tracerId = EMPTY_STRING; + private List<TimelineAnnotation> timeline = null; + + public Builder() { + } + + public Builder begin(long begin) { + this.begin = begin; + return this; + } + + public Builder end(long end) { + this.end = end; + return this; + } + + public Builder description(String description) { + this.description = description; + return this; + } + + public Builder parents(SpanId parents[]) { + this.parents = parents; + return this; + } + + public Builder parents(List<SpanId> parentList) { + SpanId[] parents = new SpanId[parentList.size()]; + for (int i = 0; i < parentList.size(); i++) { + parents[i] = parentList.get(i); + } + this.parents = parents; + return this; + } + + public Builder spanId(SpanId spanId) { + this.spanId = spanId; + return this; + } + + public Builder traceInfo(Map<String, String> traceInfo) { + this.traceInfo = traceInfo.isEmpty() ? null : traceInfo; + return this; + } + + public Builder tracerId(String tracerId) { + this.tracerId = tracerId; + return this; + } + + public Builder timeline(List<TimelineAnnotation> timeline) { + this.timeline = timeline.isEmpty() ? null : timeline; + return this; + } + + public MilliSpan build() { + return new MilliSpan(this); + } + } + + public MilliSpan() { + this.begin = 0; + this.end = 0; + this.description = EMPTY_STRING; + this.parents = EMPTY_PARENT_ARRAY; + this.spanId = SpanId.INVALID; + this.traceInfo = null; + this.tracerId = EMPTY_STRING; + this.timeline = null; + } + + private MilliSpan(Builder builder) { + this.begin = builder.begin; + this.end = builder.end; + this.description = builder.description; + this.parents = builder.parents; + this.spanId = builder.spanId; + this.traceInfo = builder.traceInfo; + this.tracerId = builder.tracerId; + this.timeline = builder.timeline; + } + + @Override + public synchronized void stop() { + if (end == 0) { + if (begin == 0) + throw new IllegalStateException("Span for " + description + + " has not been started"); + end = System.currentTimeMillis(); + Tracer.getInstance().deliver(this); + } + } + + protected long currentTimeMillis() { + return System.currentTimeMillis(); + } + + @Override + public synchronized boolean isRunning() { + return begin != 0 && end == 0; + } + + @Override + public synchronized long getAccumulatedMillis() { + if (begin == 0) + return 0; + if (end > 0) + return end - begin; + return currentTimeMillis() - begin; + } + + @Override + public String toString() { + return toJson(); + } + + @Override + public String getDescription() { + return description; + } + + @Override + public SpanId getSpanId() { + return spanId; + } + + @Override + public SpanId[] getParents() { + return parents; + } + + @Override + public void setParents(SpanId[] parents) { + this.parents = parents; + } + + @Override + public long getStartTimeMillis() { + return begin; + } + + @Override + public long getStopTimeMillis() { + return end; + } + + @Override + public void addKVAnnotation(String key, String value) { + if (traceInfo == null) + traceInfo = new HashMap<String, String>(); + traceInfo.put(key, value); + } + + @Override + public void addTimelineAnnotation(String msg) { + if (timeline == null) { + timeline = new ArrayList<TimelineAnnotation>(); + } + timeline.add(new TimelineAnnotation(System.currentTimeMillis(), msg)); + } + + @Override + public Map<String, String> getKVAnnotations() { + if (traceInfo == null) + return Collections.emptyMap(); + return Collections.unmodifiableMap(traceInfo); + } + + @Override + public List<TimelineAnnotation> getTimelineAnnotations() { + if (timeline == null) { + return Collections.emptyList(); + } + return Collections.unmodifiableList(timeline); + } + + @Override + public String getTracerId() { + return tracerId; + } + + @Override + public void setTracerId(String tracerId) { + this.tracerId = tracerId; + } + + @Override + public String toJson() { + StringWriter writer = new StringWriter(); + try { + JSON_WRITER.writeValue(writer, this); + } catch (IOException e) { + // An IOException should not be possible when writing to a string. + throw new RuntimeException(e); + } + return writer.toString(); + } + + public static class MilliSpanDeserializer + extends JsonDeserializer<MilliSpan> { + @Override + public MilliSpan deserialize(JsonParser jp, DeserializationContext ctxt) + throws IOException, JsonProcessingException { + JsonNode root = jp.getCodec().readTree(jp); + Builder builder = new Builder(); + JsonNode bNode = root.get("b"); + if (bNode != null) { + builder.begin(bNode.asLong()); + } + JsonNode eNode = root.get("e"); + if (eNode != null) { + builder.end(eNode.asLong()); + } + JsonNode dNode = root.get("d"); + if (dNode != null) { + builder.description(dNode.asText()); + } + JsonNode sNode = root.get("a"); + if (sNode != null) { + builder.spanId(SpanId.fromString(sNode.asText())); + } + JsonNode rNode = root.get("r"); + if (rNode != null) { + builder.tracerId(rNode.asText()); + } + JsonNode parentsNode = root.get("p"); + LinkedList<SpanId> parents = new LinkedList<SpanId>(); + if (parentsNode != null) { + for (Iterator<JsonNode> iter = parentsNode.elements(); + iter.hasNext(); ) { + JsonNode parentIdNode = iter.next(); + parents.add(SpanId.fromString(parentIdNode.asText())); + } + } + builder.parents(parents); + JsonNode traceInfoNode = root.get("n"); + if (traceInfoNode != null) { + HashMap<String, String> traceInfo = new HashMap<String, String>(); + for (Iterator<String> iter = traceInfoNode.fieldNames(); + iter.hasNext(); ) { + String field = iter.next(); + traceInfo.put(field, traceInfoNode.get(field).asText()); + } + builder.traceInfo(traceInfo); + } + JsonNode timelineNode = root.get("t"); + if (timelineNode != null) { + LinkedList<TimelineAnnotation> timeline = + new LinkedList<TimelineAnnotation>(); + for (Iterator<JsonNode> iter = timelineNode.elements(); + iter.hasNext(); ) { + JsonNode ann = iter.next(); + timeline.add(new TimelineAnnotation(ann.get("t").asLong(), + ann.get("m").asText())); + } + builder.timeline(timeline); + } + return builder.build(); + } + } + + static MilliSpan fromJson(String json) throws IOException { + return JSON_READER.readValue(json); + } +} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/main/java/org/apache/htrace/core/NeverSampler.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/core/NeverSampler.java b/htrace-core/src/main/java/org/apache/htrace/core/NeverSampler.java new file mode 100644 index 0000000..65f6087 --- /dev/null +++ b/htrace-core/src/main/java/org/apache/htrace/core/NeverSampler.java @@ -0,0 +1,34 @@ +/* + * 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.core; + +/** + * A Sampler that never returns true. + */ +public final class NeverSampler implements Sampler { + + public static final NeverSampler INSTANCE = new NeverSampler(null); + + public NeverSampler(HTraceConfiguration conf) { + } + + @Override + public boolean next() { + return false; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/main/java/org/apache/htrace/core/NullScope.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/core/NullScope.java b/htrace-core/src/main/java/org/apache/htrace/core/NullScope.java new file mode 100644 index 0000000..e7964cf --- /dev/null +++ b/htrace-core/src/main/java/org/apache/htrace/core/NullScope.java @@ -0,0 +1,44 @@ +/* + * 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.core; + +/** + * Singleton instance representing an empty {@link TraceScope}. + */ +public final class NullScope extends TraceScope { + + public static final TraceScope INSTANCE = new NullScope(); + + private NullScope() { + super(null, null); + } + + @Override + public Span detach() { + return null; + } + + @Override + public void close() { + return; + } + + @Override + public String toString() { + return "NullScope"; + } +} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/main/java/org/apache/htrace/core/POJOSpanReceiver.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/core/POJOSpanReceiver.java b/htrace-core/src/main/java/org/apache/htrace/core/POJOSpanReceiver.java new file mode 100644 index 0000000..be782ba --- /dev/null +++ b/htrace-core/src/main/java/org/apache/htrace/core/POJOSpanReceiver.java @@ -0,0 +1,49 @@ +/* + * 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.core; + +import java.io.IOException; +import java.util.Collection; +import java.util.HashSet; + +/** + * SpanReceiver for testing only that just collects the Span objects it + * receives. The spans it receives can be accessed with getSpans(); + */ +public class POJOSpanReceiver implements SpanReceiver { + private final Collection<Span> spans; + + public POJOSpanReceiver(HTraceConfiguration conf) { + this.spans = new HashSet<Span>(); + } + + /** + * @return The spans this POJOSpanReceiver has received. + */ + public Collection<Span> getSpans() { + return spans; + } + + @Override + public void close() throws IOException { + } + + @Override + public void receiveSpan(Span span) { + spans.add(span); + } +} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/main/java/org/apache/htrace/core/ProbabilitySampler.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/core/ProbabilitySampler.java b/htrace-core/src/main/java/org/apache/htrace/core/ProbabilitySampler.java new file mode 100644 index 0000000..5bb0042 --- /dev/null +++ b/htrace-core/src/main/java/org/apache/htrace/core/ProbabilitySampler.java @@ -0,0 +1,46 @@ +/* + * 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.core; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; + +/** + * Sampler that returns true a certain percentage of the time. Specify the frequency interval by + * configuring a {@code double} value for {@link #SAMPLER_FRACTION_CONF_KEY}. + */ +public class ProbabilitySampler implements Sampler { + private static final Log LOG = LogFactory.getLog(ProbabilitySampler.class); + public final double threshold; + public final static String SAMPLER_FRACTION_CONF_KEY = "sampler.fraction"; + + public ProbabilitySampler(HTraceConfiguration conf) { + this.threshold = Double.parseDouble(conf.get(SAMPLER_FRACTION_CONF_KEY)); + if (LOG.isTraceEnabled()) { + LOG.trace("Created new ProbabilitySampler with threshold = " + + threshold + "."); + } + } + + @Override + public boolean next() { + return ThreadLocalRandom.current().nextDouble() < threshold; + } +}
