You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@htrace.apache.org by cm...@apache.org on 2014/12/06 05:07:44 UTC
[8/8] incubator-htrace git commit: HTRACE-8. Change our base package
from org.htrace to org.apache.htrace (cmccabe / stack)
HTRACE-8. Change our base package from org.htrace to org.apache.htrace (cmccabe / stack)
Project: http://git-wip-us.apache.org/repos/asf/incubator-htrace/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-htrace/commit/a27cd4da
Tree: http://git-wip-us.apache.org/repos/asf/incubator-htrace/tree/a27cd4da
Diff: http://git-wip-us.apache.org/repos/asf/incubator-htrace/diff/a27cd4da
Branch: refs/heads/master
Commit: a27cd4dabd9a018e23f2fb14d8d916979040dc18
Parents: c4a0d5d
Author: Colin P. Mccabe <cm...@apache.org>
Authored: Fri Dec 5 20:01:21 2014 -0800
Committer: Colin P. Mccabe <cm...@apache.org>
Committed: Fri Dec 5 20:01:21 2014 -0800
----------------------------------------------------------------------
README.md | 7 +-
htrace-core/pom.xml | 2 +-
.../org/apache/htrace/HTraceConfiguration.java | 84 +
.../main/java/org/apache/htrace/NullScope.java | 34 +
.../main/java/org/apache/htrace/Sampler.java | 54 +
.../src/main/java/org/apache/htrace/Span.java | 116 +
.../java/org/apache/htrace/SpanReceiver.java | 42 +
.../org/apache/htrace/TimelineAnnotation.java | 40 +
.../src/main/java/org/apache/htrace/Trace.java | 208 ++
.../main/java/org/apache/htrace/TraceInfo.java | 38 +
.../main/java/org/apache/htrace/TraceScope.java | 82 +
.../main/java/org/apache/htrace/TraceTree.java | 95 +
.../src/main/java/org/apache/htrace/Tracer.java | 125 +
.../org/apache/htrace/impl/AlwaysSampler.java | 32 +
.../org/apache/htrace/impl/CountSampler.java | 41 +
.../htrace/impl/LocalFileSpanReceiver.java | 137 ++
.../java/org/apache/htrace/impl/MilliSpan.java | 161 ++
.../org/apache/htrace/impl/NeverSampler.java | 33 +
.../apache/htrace/impl/POJOSpanReceiver.java | 58 +
.../apache/htrace/impl/ProbabilitySampler.java | 36 +
.../htrace/impl/StandardOutSpanReceiver.java | 42 +
.../htrace/impl/TrueIfTracingSampler.java | 37 +
.../apache/htrace/wrappers/TraceCallable.java | 69 +
.../htrace/wrappers/TraceExecutorService.java | 118 +
.../org/apache/htrace/wrappers/TraceProxy.java | 70 +
.../apache/htrace/wrappers/TraceRunnable.java | 64 +
.../java/org/htrace/HTraceConfiguration.java | 84 -
.../src/main/java/org/htrace/NullScope.java | 34 -
.../src/main/java/org/htrace/Sampler.java | 54 -
htrace-core/src/main/java/org/htrace/Span.java | 116 -
.../src/main/java/org/htrace/SpanReceiver.java | 42 -
.../java/org/htrace/TimelineAnnotation.java | 40 -
htrace-core/src/main/java/org/htrace/Trace.java | 208 --
.../src/main/java/org/htrace/TraceInfo.java | 38 -
.../src/main/java/org/htrace/TraceScope.java | 82 -
.../src/main/java/org/htrace/TraceTree.java | 95 -
.../src/main/java/org/htrace/Tracer.java | 125 -
.../java/org/htrace/impl/AlwaysSampler.java | 32 -
.../main/java/org/htrace/impl/CountSampler.java | 41 -
.../org/htrace/impl/LocalFileSpanReceiver.java | 137 --
.../main/java/org/htrace/impl/MilliSpan.java | 161 --
.../main/java/org/htrace/impl/NeverSampler.java | 33 -
.../java/org/htrace/impl/POJOSpanReceiver.java | 58 -
.../org/htrace/impl/ProbabilitySampler.java | 36 -
.../htrace/impl/StandardOutSpanReceiver.java | 42 -
.../org/htrace/impl/TrueIfTracingSampler.java | 37 -
.../java/org/htrace/wrappers/TraceCallable.java | 69 -
.../htrace/wrappers/TraceExecutorService.java | 118 -
.../java/org/htrace/wrappers/TraceProxy.java | 70 -
.../java/org/htrace/wrappers/TraceRunnable.java | 64 -
.../org/apache/htrace/TestCountSampler.java | 40 +
.../test/java/org/apache/htrace/TestHTrace.java | 118 +
.../apache/htrace/TestHTraceConfiguration.java | 63 +
.../java/org/apache/htrace/TestSampler.java | 53 +
.../java/org/apache/htrace/TraceCreator.java | 163 ++
.../test/java/org/htrace/TestCountSampler.java | 40 -
.../src/test/java/org/htrace/TestHTrace.java | 113 -
.../org/htrace/TestHTraceConfiguration.java | 62 -
.../src/test/java/org/htrace/TestSampler.java | 49 -
.../src/test/java/org/htrace/TraceCreator.java | 157 --
htrace-hbase/README.md | 12 +-
htrace-hbase/pom.xml | 8 +-
.../apache/htrace/impl/HBaseSpanReceiver.java | 373 +++
.../htrace/protobuf/generated/SpanProtos.java | 2241 ++++++++++++++++++
.../apache/htrace/viewer/HBaseSpanViewer.java | 226 ++
.../htrace/viewer/HBaseSpanViewerServer.java | 115 +
.../viewer/HBaseSpanViewerSpansServlet.java | 97 +
.../viewer/HBaseSpanViewerTracesServlet.java | 84 +
.../java/org/htrace/impl/HBaseSpanReceiver.java | 367 ---
.../htrace/protobuf/generated/SpanProtos.java | 2241 ------------------
.../java/org/htrace/viewer/HBaseSpanViewer.java | 224 --
.../htrace/viewer/HBaseSpanViewerServer.java | 115 -
.../viewer/HBaseSpanViewerSpansServlet.java | 95 -
.../viewer/HBaseSpanViewerTracesServlet.java | 82 -
htrace-hbase/src/main/protobuf/Span.proto | 2 +-
htrace-hbase/src/main/webapps/htrace/spans.js | 2 +-
.../org/apache/htrace/impl/HBaseTestUtil.java | 89 +
.../htrace/impl/TestHBaseSpanReceiver.java | 226 ++
.../htrace/viewer/TestHBaseSpanViewer.java | 97 +
.../java/org/htrace/impl/HBaseTestUtil.java | 84 -
.../org/htrace/impl/TestHBaseSpanReceiver.java | 219 --
.../org/htrace/viewer/TestHBaseSpanViewer.java | 95 -
htrace-zipkin/pom.xml | 4 +-
.../apache/htrace/impl/ZipkinSpanReceiver.java | 363 +++
.../htrace/zipkin/HTraceToZipkinConverter.java | 195 ++
.../org/htrace/impl/ZipkinSpanReceiver.java | 362 ---
.../htrace/zipkin/HTraceToZipkinConverter.java | 194 --
.../htrace/TestHTraceSpanToZipkinSpan.java | 135 ++
.../org/htrace/TestHTraceSpanToZipkinSpan.java | 132 --
pom.xml | 2 +-
90 files changed, 6514 insertions(+), 6466 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index 442609a..2e01807 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,10 @@ HTrace
======
HTrace is a tracing framework intended for use with distributed systems written in java.
-The project is hosted at http://github.com/cloudera/htrace.
-The project is available in Maven Central with groupId: org.htrace, and name: htrace.
-(It was formally at groupId: org.cloudera.htrace, and name: htrace).
+The project is hosted at http://htrace.incubator.apache.org
+The project is available in Maven Central with groupId: org.apache.htrace,
+and name: htrace (It was formally groupId: org.cloudera.htrace, and
+groundId: org.htrace).
API
---
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/htrace-core/pom.xml
----------------------------------------------------------------------
diff --git a/htrace-core/pom.xml b/htrace-core/pom.xml
index 47677d8..42f624c 100644
--- a/htrace-core/pom.xml
+++ b/htrace-core/pom.xml
@@ -17,7 +17,7 @@ language governing permissions and limitations under the License. -->
<parent>
<artifactId>htrace</artifactId>
- <groupId>org.htrace</groupId>
+ <groupId>org.apache.htrace</groupId>
<version>3.0.4</version>
</parent>
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/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
new file mode 100644
index 0000000..ecef911
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/HTraceConfiguration.java
@@ -0,0 +1,84 @@
+/*
+ * 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);
+
+ public static HTraceConfiguration fromMap(Map<String, String> conf) {
+ 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/a27cd4da/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
new file mode 100644
index 0000000..32963a8
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/NullScope.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;
+
+/**
+ * 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 String toString() {
+ return "NullScope";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/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
new file mode 100644
index 0000000..9f81e14
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/Sampler.java
@@ -0,0 +1,54 @@
+/*
+ * 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/>
+ * 'T' is the object type you require to create a more advanced sampling
+ * function. For example if there is some RPC information in a 'Call' object,
+ * you might implement Sampler<Call>. Then when the RPC is received you can call
+ * one of the Trace.java functions that takes the extra 'info' parameter, which
+ * will be passed into the next function you implemented.
+ * <p/>
+ * For the example above, the next(T info) function may look like this
+ * <p/>
+ * public boolean next(T info){
+ * if (info == null) {
+ * return false;
+ * } else if (info.getName().equals("get")) {
+ * return Math.random() > 0.5;
+ * } else if (info.getName().equals("put")) {
+ * return Math.random() > 0.25;
+ * } else {
+ * return false;
+ * }
+ * }
+ * This would trace 50% of all gets, 75% of all puts and would not trace any other requests.
+ */
+public interface Sampler<T> {
+
+ public static final Sampler<?> ALWAYS = AlwaysSampler.INSTANCE;
+ public static final Sampler<?> NEVER = NeverSampler.INSTANCE;
+
+ public boolean next(T info);
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/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
new file mode 100644
index 0000000..633bcba
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/Span.java
@@ -0,0 +1,116 @@
+/*
+ * 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.util.List;
+import java.util.Map;
+
+
+/**
+ * Base interface for gathering and reporting statistics about a block of
+ * execution.
+ * <p/>
+ * Spans form a tree structure with the parent relationship. The first span in a
+ * trace has no parent span.
+ */
+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 parent span, returns
+ * ROOT_SPAN_ID if this is the root span
+ */
+ 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<byte[], byte[]> getKVAnnotations();
+
+ /**
+ * Get any timeline annotations (read only)
+ */
+ List<TimelineAnnotation> getTimelineAnnotations();
+
+ /**
+ * Return a unique id for the node or process from which this Span originated.
+ * IP address is a reasonable choice.
+ *
+ * @return
+ */
+ String getProcessId();
+}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/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
new file mode 100644
index 0000000..aad549a
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/SpanReceiver.java
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+public interface SpanReceiver extends Closeable {
+
+ /**
+ * Hosts of SpanReceivers should call this method to provide
+ * configuration to SpanReceivers after creating them.
+ */
+ public void configure(HTraceConfiguration conf);
+
+ /**
+ * Called when a Span is stopped and can now be stored.
+ *
+ * @param span
+ */
+ public void receiveSpan(Span span);
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/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
new file mode 100644
index 0000000..d0ae675
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/TimelineAnnotation.java
@@ -0,0 +1,40 @@
+/*
+ * 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/a27cd4da/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
new file mode 100644
index 0000000..61dfdfa
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/Trace.java
@@ -0,0 +1,208 @@
+/*
+ * 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 <T> TraceScope startSpan(String description, Sampler<T> s) {
+ return startSpan(description, s, null);
+ }
+
+ public static TraceScope startSpan(String description, Sampler<TraceInfo> 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 <T> TraceScope startSpan(String description, Sampler<T> 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 <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
+ *
+ * @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;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/htrace-core/src/main/java/org/apache/htrace/TraceInfo.java
----------------------------------------------------------------------
diff --git a/htrace-core/src/main/java/org/apache/htrace/TraceInfo.java b/htrace-core/src/main/java/org/apache/htrace/TraceInfo.java
new file mode 100644
index 0000000..9e7d74a
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/TraceInfo.java
@@ -0,0 +1,38 @@
+/*
+ * 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());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/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
new file mode 100644
index 0000000..7773aad
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/TraceScope.java
@@ -0,0 +1,82 @@
+/*
+ * 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();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/htrace-core/src/main/java/org/apache/htrace/TraceTree.java
----------------------------------------------------------------------
diff --git a/htrace-core/src/main/java/org/apache/htrace/TraceTree.java b/htrace-core/src/main/java/org/apache/htrace/TraceTree.java
new file mode 100644
index 0000000..8dc6a30
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/TraceTree.java
@@ -0,0 +1,95 @@
+/*
+ * 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.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Multimap;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.Collection;
+
+/**
+ * Used to create the graph formed by spans.
+ */
+public class TraceTree {
+ public static final Log LOG = LogFactory.getLog(Tracer.class);
+ private Multimap<Long, Span> spansByParentID;
+ private Collection<Span> spans;
+ private Multimap<String, Span> spansByPid;
+
+ /**
+ * 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<Span> spans) {
+ this.spans = ImmutableList.copyOf(spans);
+ this.spansByParentID = HashMultimap.<Long, Span>create();
+ this.spansByPid = HashMultimap.<String, Span>create();
+
+ for (Span s : this.spans) {
+ if (s.getProcessId() != null) {
+ spansByPid.put(s.getProcessId(), s);
+ } else {
+ LOG.warn("Encountered span with null processId. This should not happen. Span: "
+ + s);
+ }
+ spansByParentID.put(s.getParentId(), s);
+ }
+ }
+
+ /**
+ * @return The collection of spans given to this TraceTree at construction.
+ */
+ public Collection<Span> getSpans() {
+ return spans;
+ }
+
+ /**
+ * @return A copy of the MultiMap from parent span ID -> children of span with
+ * that ID.
+ */
+ public Multimap<Long, Span> getSpansByParentIdMap() {
+ return HashMultimap.<Long, Span>create(spansByParentID);
+ }
+
+ /**
+ * @return A collection of the root spans (spans with parent ID =
+ * Span.ROOT_SPAN_ID) in this tree.
+ */
+ public Collection<Span> getRoots() {
+ Collection<Span> roots = spansByParentID.get(Span.ROOT_SPAN_ID);
+ if (roots != null) {
+ return roots;
+ }
+ throw new IllegalStateException(
+ "TraceTree is not correctly formed - there are no root spans in the collection provided at construction.");
+ }
+
+ /**
+ * @return A copy of the Multimap from String process ID -> spans with that
+ * process ID. If process ID was not set in Trace.java, all spans will
+ * have empty string process IDs.
+ */
+ public Multimap<String, Span> getSpansByPidMap() {
+ return HashMultimap.<String, Span>create(spansByPid);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/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
new file mode 100644
index 0000000..614521c
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/Tracer.java
@@ -0,0 +1,125 @@
+/*
+ * 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<SpanReceiver> receivers = new CopyOnWriteArrayList<SpanReceiver>();
+ private static final ThreadLocal<Span> currentSpan = new ThreadLocal<Span>() {
+ @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.
+ * <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(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;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/htrace-core/src/main/java/org/apache/htrace/impl/AlwaysSampler.java
----------------------------------------------------------------------
diff --git a/htrace-core/src/main/java/org/apache/htrace/impl/AlwaysSampler.java b/htrace-core/src/main/java/org/apache/htrace/impl/AlwaysSampler.java
new file mode 100644
index 0000000..8c90eff
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/impl/AlwaysSampler.java
@@ -0,0 +1,32 @@
+/*
+ * 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.Sampler;
+
+public final class AlwaysSampler implements Sampler<Object> {
+
+ public static final AlwaysSampler INSTANCE = new AlwaysSampler();
+
+ private AlwaysSampler() {
+ }
+
+ @Override
+ public boolean next(Object info) {
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/htrace-core/src/main/java/org/apache/htrace/impl/CountSampler.java
----------------------------------------------------------------------
diff --git a/htrace-core/src/main/java/org/apache/htrace/impl/CountSampler.java b/htrace-core/src/main/java/org/apache/htrace/impl/CountSampler.java
new file mode 100644
index 0000000..78e155c
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/impl/CountSampler.java
@@ -0,0 +1,41 @@
+/*
+ * 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.Sampler;
+
+import java.util.Random;
+
+/**
+ * Sampler that returns true every N calls.
+ */
+public class CountSampler implements Sampler<Object> {
+
+ final static Random random = new Random();
+
+ final long frequency;
+ long count = random.nextLong();
+
+ public CountSampler(long frequency) {
+ this.frequency = frequency;
+ }
+
+ @Override
+ public boolean next(Object info) {
+ return (count++ % frequency) == 0;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/htrace-core/src/main/java/org/apache/htrace/impl/LocalFileSpanReceiver.java
----------------------------------------------------------------------
diff --git a/htrace-core/src/main/java/org/apache/htrace/impl/LocalFileSpanReceiver.java b/htrace-core/src/main/java/org/apache/htrace/impl/LocalFileSpanReceiver.java
new file mode 100644
index 0000000..6b4be80
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/impl/LocalFileSpanReceiver.java
@@ -0,0 +1,137 @@
+/*
+ * 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.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.htrace.HTraceConfiguration;
+import org.apache.htrace.Span;
+import org.apache.htrace.SpanReceiver;
+import org.mortbay.util.ajax.JSON;
+
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Writes the spans it receives to a local file.
+ * A production LocalFileSpanReceiver should use a real CSV format.
+ */
+public class LocalFileSpanReceiver implements SpanReceiver {
+ public 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";
+ // default capacity for the executors blocking queue
+ public static final int CAPACITY_DEFAULT = 5000;
+ // default timeout duration when calling executor.awaitTermination()
+ public static final long EXECUTOR_TERMINATION_TIMEOUT_DURATION_DEFAULT = 60;
+ private String file;
+ private FileWriter fwriter;
+ private BufferedWriter bwriter;
+ private Map<String, Object> values;
+ private ExecutorService executor;
+ private long executorTerminationTimeoutDuration;
+
+ public LocalFileSpanReceiver() {
+ }
+
+
+ @Override
+ public void configure(HTraceConfiguration conf) {
+ this.executorTerminationTimeoutDuration = EXECUTOR_TERMINATION_TIMEOUT_DURATION_DEFAULT;
+ int capacity = conf.getInt(CAPACITY_KEY, CAPACITY_DEFAULT);
+ this.file = conf.get(PATH_KEY);
+ if (file == null || file.isEmpty()) {
+ throw new IllegalArgumentException("must configure " + PATH_KEY);
+ }
+ this.executor = new ThreadPoolExecutor(1, 1, 0, TimeUnit.SECONDS,
+ new LinkedBlockingQueue<Runnable>(capacity));
+ try {
+ this.fwriter = new FileWriter(this.file, true);
+ } catch (IOException ioe) {
+ throw new RuntimeException(ioe);
+ }
+ this.bwriter = new BufferedWriter(fwriter);
+ this.values = new LinkedHashMap<String, Object>();
+ }
+
+
+ private class WriteSpanRunnable implements Runnable {
+ public final Span span;
+
+ public WriteSpanRunnable(Span span) {
+ this.span = span;
+ }
+
+ @Override
+ public void run() {
+ try {
+ values.put("TraceID", span.getTraceId());
+ values.put("SpanID", span.getSpanId());
+ values.put("ParentID", span.getParentId());
+ values.put("ProcessID", span.getProcessId());
+ values.put("Start", span.getStartTimeMillis());
+ values.put("Stop", span.getStopTimeMillis());
+ values.put("Description", span.getDescription());
+ values.put("KVAnnotations", span.getKVAnnotations());
+ values.put("TLAnnotations", span.getTimelineAnnotations());
+ bwriter.write(JSON.toString(values));
+ bwriter.newLine();
+ bwriter.flush();
+ values.clear();
+ } catch (IOException e) {
+ LOG.error("Error when writing to file: " + file, e);
+ }
+ }
+ }
+
+ @Override
+ public void receiveSpan(Span span) {
+ executor.submit(new WriteSpanRunnable(span));
+ }
+
+ @Override
+ public void close() throws IOException {
+ executor.shutdown();
+ try {
+ if (!executor.awaitTermination(this.executorTerminationTimeoutDuration,
+ TimeUnit.SECONDS)) {
+ LOG.warn("Was not able to process all remaining spans to write upon closing in: "
+ + this.executorTerminationTimeoutDuration + "s");
+ }
+ } catch (InterruptedException e1) {
+ LOG.warn("Thread interrupted when terminating executor.", e1);
+ }
+
+ try {
+ fwriter.close();
+ } catch (IOException e) {
+ LOG.error("Error closing filewriter for file: " + file, e);
+ }
+ try {
+ bwriter.close();
+ } catch (IOException e) {
+ LOG.error("Error closing bufferedwriter for file: " + file, e);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/htrace-core/src/main/java/org/apache/htrace/impl/MilliSpan.java
----------------------------------------------------------------------
diff --git a/htrace-core/src/main/java/org/apache/htrace/impl/MilliSpan.java b/htrace-core/src/main/java/org/apache/htrace/impl/MilliSpan.java
new file mode 100644
index 0000000..9d24f68
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/impl/MilliSpan.java
@@ -0,0 +1,161 @@
+/*
+ * 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.Span;
+import org.apache.htrace.TimelineAnnotation;
+import org.apache.htrace.Tracer;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+/**
+ * A Span implementation that stores its information in milliseconds since the
+ * epoch.
+ */
+public class MilliSpan implements Span {
+
+ private static Random rand = new Random();
+
+ private long start;
+ private long stop;
+ private final String description;
+ private final long traceId;
+ private final long parentSpanId;
+ private final long spanId;
+ private Map<byte[], byte[]> traceInfo = null;
+ private final String processId;
+ private List<TimelineAnnotation> timeline = null;
+
+ @Override
+ public Span child(String description) {
+ return new MilliSpan(description, traceId, spanId, rand.nextLong(), processId);
+ }
+
+ public MilliSpan(String description, long traceId, long parentSpanId, long spanId, String processId) {
+ this.description = description;
+ this.traceId = traceId;
+ this.parentSpanId = parentSpanId;
+ this.spanId = spanId;
+ this.start = System.currentTimeMillis();
+ this.stop = 0;
+ this.processId = processId;
+ }
+
+ @Override
+ public synchronized void stop() {
+ if (stop == 0) {
+ if (start == 0)
+ throw new IllegalStateException("Span for " + description
+ + " has not been started");
+ stop = System.currentTimeMillis();
+ Tracer.getInstance().deliver(this);
+ }
+ }
+
+ protected long currentTimeMillis() {
+ return System.currentTimeMillis();
+ }
+
+ @Override
+ public synchronized boolean isRunning() {
+ return start != 0 && stop == 0;
+ }
+
+ @Override
+ public synchronized long getAccumulatedMillis() {
+ if (start == 0)
+ return 0;
+ if (stop > 0)
+ return stop - start;
+ return currentTimeMillis() - start;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("Span{Id:0x%16x,parentId:0x%16x,desc:%s}", spanId, parentSpanId, description);
+ }
+
+ @Override
+ public String getDescription() {
+ return description;
+ }
+
+ @Override
+ public long getSpanId() {
+ return spanId;
+ }
+
+ @Override
+ public long getParentId() {
+ return parentSpanId;
+ }
+
+ @Override
+ public long getTraceId() {
+ return traceId;
+ }
+
+ @Override
+ public long getStartTimeMillis() {
+ return start;
+ }
+
+ @Override
+ public long getStopTimeMillis() {
+ return stop;
+ }
+
+ @Override
+ public void addKVAnnotation(byte[] key, byte[] value) {
+ if (traceInfo == null)
+ traceInfo = new HashMap<byte[], byte[]>();
+ 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<byte[], byte[]> 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 getProcessId() {
+ return processId;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/htrace-core/src/main/java/org/apache/htrace/impl/NeverSampler.java
----------------------------------------------------------------------
diff --git a/htrace-core/src/main/java/org/apache/htrace/impl/NeverSampler.java b/htrace-core/src/main/java/org/apache/htrace/impl/NeverSampler.java
new file mode 100644
index 0000000..20233d9
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/impl/NeverSampler.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.impl;
+
+import org.apache.htrace.Sampler;
+
+public final class NeverSampler implements Sampler<Object> {
+
+ public static final NeverSampler INSTANCE = new NeverSampler();
+
+ private NeverSampler() {
+ }
+
+ @Override
+ public boolean next(Object info) {
+ return false;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/htrace-core/src/main/java/org/apache/htrace/impl/POJOSpanReceiver.java
----------------------------------------------------------------------
diff --git a/htrace-core/src/main/java/org/apache/htrace/impl/POJOSpanReceiver.java b/htrace-core/src/main/java/org/apache/htrace/impl/POJOSpanReceiver.java
new file mode 100644
index 0000000..a77fd39
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/impl/POJOSpanReceiver.java
@@ -0,0 +1,58 @@
+/*
+ * 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.Span;
+import org.apache.htrace.SpanReceiver;
+
+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;
+
+ @Override
+ public void configure(HTraceConfiguration conf) {
+ }
+
+ /**
+ * @return The spans this POJOSpanReceiver has received.
+ */
+ public Collection<Span> getSpans() {
+ return spans;
+ }
+
+ public POJOSpanReceiver() {
+ this.spans = new HashSet<Span>();
+ }
+
+ @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/a27cd4da/htrace-core/src/main/java/org/apache/htrace/impl/ProbabilitySampler.java
----------------------------------------------------------------------
diff --git a/htrace-core/src/main/java/org/apache/htrace/impl/ProbabilitySampler.java b/htrace-core/src/main/java/org/apache/htrace/impl/ProbabilitySampler.java
new file mode 100644
index 0000000..a34c5ec
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/impl/ProbabilitySampler.java
@@ -0,0 +1,36 @@
+/*
+ * 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.Sampler;
+
+import java.util.Random;
+
+public class ProbabilitySampler implements Sampler<Object> {
+ public final double threshold;
+ private Random random;
+
+ public ProbabilitySampler(double threshold) {
+ this.threshold = threshold;
+ random = new Random();
+ }
+
+ @Override
+ public boolean next(Object info) {
+ return random.nextDouble() < threshold;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/htrace-core/src/main/java/org/apache/htrace/impl/StandardOutSpanReceiver.java
----------------------------------------------------------------------
diff --git a/htrace-core/src/main/java/org/apache/htrace/impl/StandardOutSpanReceiver.java b/htrace-core/src/main/java/org/apache/htrace/impl/StandardOutSpanReceiver.java
new file mode 100644
index 0000000..2253f86
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/impl/StandardOutSpanReceiver.java
@@ -0,0 +1,42 @@
+/*
+ * 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.Span;
+import org.apache.htrace.SpanReceiver;
+
+import java.io.IOException;
+
+/**
+ * Used for testing. Simply prints to standard out any spans it receives.
+ */
+public class StandardOutSpanReceiver implements SpanReceiver {
+
+ @Override
+ public void configure(HTraceConfiguration conf) {
+ }
+
+ @Override
+ public void receiveSpan(Span span) {
+ System.out.println(span);
+ }
+
+ @Override
+ public void close() throws IOException {
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/htrace-core/src/main/java/org/apache/htrace/impl/TrueIfTracingSampler.java
----------------------------------------------------------------------
diff --git a/htrace-core/src/main/java/org/apache/htrace/impl/TrueIfTracingSampler.java b/htrace-core/src/main/java/org/apache/htrace/impl/TrueIfTracingSampler.java
new file mode 100644
index 0000000..69598ba
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/impl/TrueIfTracingSampler.java
@@ -0,0 +1,37 @@
+/*
+ * 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.Sampler;
+import org.apache.htrace.Trace;
+
+/**
+ * A Sampler that returns true if and only if tracing is on the current thread.
+ */
+public class TrueIfTracingSampler implements Sampler<Object> {
+
+ public static final TrueIfTracingSampler INSTANCE = new TrueIfTracingSampler();
+
+ private TrueIfTracingSampler() {
+ }
+
+ @Override
+ public boolean next(Object info) {
+ return Trace.isTracing();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/htrace-core/src/main/java/org/apache/htrace/wrappers/TraceCallable.java
----------------------------------------------------------------------
diff --git a/htrace-core/src/main/java/org/apache/htrace/wrappers/TraceCallable.java b/htrace-core/src/main/java/org/apache/htrace/wrappers/TraceCallable.java
new file mode 100644
index 0000000..e761fbf
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/wrappers/TraceCallable.java
@@ -0,0 +1,69 @@
+/*
+ * 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.wrappers;
+
+import org.apache.htrace.Span;
+import org.apache.htrace.Trace;
+import org.apache.htrace.TraceScope;
+
+import java.util.concurrent.Callable;
+
+/**
+ * Wrap a Callable with a Span that survives a change in threads.
+ */
+public class TraceCallable<V> implements Callable<V> {
+ private final Callable<V> impl;
+ private final Span parent;
+ private final String description;
+
+ public TraceCallable(Callable<V> impl) {
+ this(Trace.currentSpan(), impl);
+ }
+
+ public TraceCallable(Span parent, Callable<V> impl) {
+ this(parent, impl, null);
+ }
+
+ public TraceCallable(Span parent, Callable<V> impl, String description) {
+ this.impl = impl;
+ this.parent = parent;
+ this.description = description;
+ }
+
+ @Override
+ public V call() throws Exception {
+ if (parent != null) {
+ TraceScope chunk = Trace.startSpan(getDescription(), parent);
+
+ try {
+ return impl.call();
+ } finally {
+ chunk.close();
+ }
+ } else {
+ return impl.call();
+ }
+ }
+
+ public Callable<V> getImpl() {
+ return impl;
+ }
+
+ private String getDescription() {
+ return this.description == null ? Thread.currentThread().getName() : description;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/htrace-core/src/main/java/org/apache/htrace/wrappers/TraceExecutorService.java
----------------------------------------------------------------------
diff --git a/htrace-core/src/main/java/org/apache/htrace/wrappers/TraceExecutorService.java b/htrace-core/src/main/java/org/apache/htrace/wrappers/TraceExecutorService.java
new file mode 100644
index 0000000..03e891f
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/wrappers/TraceExecutorService.java
@@ -0,0 +1,118 @@
+/*
+ * 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.wrappers;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+
+public class TraceExecutorService implements ExecutorService {
+
+ private final ExecutorService impl;
+
+ public TraceExecutorService(ExecutorService impl) {
+ this.impl = impl;
+ }
+
+ @Override
+ public void execute(Runnable command) {
+ impl.execute(new TraceRunnable(command));
+ }
+
+ @Override
+ public void shutdown() {
+ impl.shutdown();
+ }
+
+ @Override
+ public List<Runnable> shutdownNow() {
+ return impl.shutdownNow();
+ }
+
+ @Override
+ public boolean isShutdown() {
+ return impl.isShutdown();
+ }
+
+ @Override
+ public boolean isTerminated() {
+ return impl.isTerminated();
+ }
+
+ @Override
+ public boolean awaitTermination(long timeout, TimeUnit unit)
+ throws InterruptedException {
+ return impl.awaitTermination(timeout, unit);
+ }
+
+ @Override
+ public <T> Future<T> submit(Callable<T> task) {
+ return impl.submit(new TraceCallable<T>(task));
+ }
+
+ @Override
+ public <T> Future<T> submit(Runnable task, T result) {
+ return impl.submit(new TraceRunnable(task), result);
+ }
+
+ @Override
+ public Future<?> submit(Runnable task) {
+ return impl.submit(new TraceRunnable(task));
+ }
+
+ private <T> Collection<? extends Callable<T>> wrapCollection(
+ Collection<? extends Callable<T>> tasks) {
+ List<Callable<T>> result = new ArrayList<Callable<T>>();
+ for (Callable<T> task : tasks) {
+ result.add(new TraceCallable<T>(task));
+ }
+ return result;
+ }
+
+ @Override
+ public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
+ throws InterruptedException {
+ return impl.invokeAll(wrapCollection(tasks));
+ }
+
+ @Override
+ public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
+ long timeout, TimeUnit unit) throws InterruptedException {
+ return impl.invokeAll(wrapCollection(tasks), timeout, unit);
+ }
+
+ @Override
+ public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
+ throws InterruptedException, ExecutionException {
+ return impl.invokeAny(wrapCollection(tasks));
+ }
+
+ @Override
+ public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout,
+ TimeUnit unit) throws InterruptedException, ExecutionException,
+ TimeoutException {
+ return impl.invokeAny(wrapCollection(tasks), timeout, unit);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/htrace-core/src/main/java/org/apache/htrace/wrappers/TraceProxy.java
----------------------------------------------------------------------
diff --git a/htrace-core/src/main/java/org/apache/htrace/wrappers/TraceProxy.java b/htrace-core/src/main/java/org/apache/htrace/wrappers/TraceProxy.java
new file mode 100644
index 0000000..c06befd
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/wrappers/TraceProxy.java
@@ -0,0 +1,70 @@
+/*
+ * 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.wrappers;
+
+import org.apache.htrace.Sampler;
+import org.apache.htrace.Trace;
+import org.apache.htrace.TraceScope;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+public class TraceProxy {
+ /**
+ * Returns an object that will trace all calls to itself.
+ *
+ * @param instance
+ * @return
+ */
+ public static <T> T trace(T instance) {
+ return trace(instance, Sampler.ALWAYS);
+ }
+
+ /**
+ * Returns an object that will trace all calls to itself.
+ *
+ * @param <V>
+ * @param instance
+ * @param sampler
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public static <T, V> T trace(final T instance, final Sampler<V> sampler) {
+ InvocationHandler handler = new InvocationHandler() {
+ @Override
+ public Object invoke(Object obj, Method method, Object[] args)
+ throws Throwable {
+ if (!sampler.next(null)) {
+ return method.invoke(instance, args);
+ }
+
+ TraceScope scope = Trace.startSpan(method.getName(), Sampler.ALWAYS);
+ try {
+ return method.invoke(instance, args);
+ } catch (Throwable ex) {
+ ex.printStackTrace();
+ throw ex;
+ } finally {
+ scope.close();
+ }
+ }
+ };
+ return (T) Proxy.newProxyInstance(instance.getClass().getClassLoader(),
+ instance.getClass().getInterfaces(), handler);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/htrace-core/src/main/java/org/apache/htrace/wrappers/TraceRunnable.java
----------------------------------------------------------------------
diff --git a/htrace-core/src/main/java/org/apache/htrace/wrappers/TraceRunnable.java b/htrace-core/src/main/java/org/apache/htrace/wrappers/TraceRunnable.java
new file mode 100644
index 0000000..64fada7
--- /dev/null
+++ b/htrace-core/src/main/java/org/apache/htrace/wrappers/TraceRunnable.java
@@ -0,0 +1,64 @@
+/*
+ * 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.wrappers;
+
+import org.apache.htrace.Span;
+import org.apache.htrace.Trace;
+import org.apache.htrace.TraceScope;
+
+/**
+ * Wrap a Runnable with a Span that survives a change in threads.
+ */
+public class TraceRunnable implements Runnable {
+
+ private final Span parent;
+ private final Runnable runnable;
+ private final String description;
+
+ public TraceRunnable(Runnable runnable) {
+ this(Trace.currentSpan(), runnable);
+ }
+
+ public TraceRunnable(Span parent, Runnable runnable) {
+ this(parent, runnable, null);
+ }
+
+ public TraceRunnable(Span parent, Runnable runnable, String description) {
+ this.parent = parent;
+ this.runnable = runnable;
+ this.description = description;
+ }
+
+ @Override
+ public void run() {
+ if (parent != null) {
+ TraceScope chunk = Trace.startSpan(getDescription(), parent);
+
+ try {
+ runnable.run();
+ } finally {
+ chunk.close();
+ }
+ } else {
+ runnable.run();
+ }
+ }
+
+ private String getDescription() {
+ return this.description == null ? Thread.currentThread().getName() : description;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/htrace-core/src/main/java/org/htrace/HTraceConfiguration.java
----------------------------------------------------------------------
diff --git a/htrace-core/src/main/java/org/htrace/HTraceConfiguration.java b/htrace-core/src/main/java/org/htrace/HTraceConfiguration.java
deleted file mode 100644
index 7ad608f..0000000
--- a/htrace-core/src/main/java/org/htrace/HTraceConfiguration.java
+++ /dev/null
@@ -1,84 +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.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);
-
- public static HTraceConfiguration fromMap(Map<String, String> conf) {
- 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/a27cd4da/htrace-core/src/main/java/org/htrace/NullScope.java
----------------------------------------------------------------------
diff --git a/htrace-core/src/main/java/org/htrace/NullScope.java b/htrace-core/src/main/java/org/htrace/NullScope.java
deleted file mode 100644
index 1f90156..0000000
--- a/htrace-core/src/main/java/org/htrace/NullScope.java
+++ /dev/null
@@ -1,34 +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.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 String toString() {
- return "NullScope";
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/htrace-core/src/main/java/org/htrace/Sampler.java
----------------------------------------------------------------------
diff --git a/htrace-core/src/main/java/org/htrace/Sampler.java b/htrace-core/src/main/java/org/htrace/Sampler.java
deleted file mode 100644
index 08c520d..0000000
--- a/htrace-core/src/main/java/org/htrace/Sampler.java
+++ /dev/null
@@ -1,54 +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.htrace;
-
-import org.htrace.impl.AlwaysSampler;
-import org.htrace.impl.NeverSampler;
-
-/**
- * Extremely simple callback to determine the frequency that an action should be
- * performed.
- * <p/>
- * 'T' is the object type you require to create a more advanced sampling
- * function. For example if there is some RPC information in a 'Call' object,
- * you might implement Sampler<Call>. Then when the RPC is received you can call
- * one of the Trace.java functions that takes the extra 'info' parameter, which
- * will be passed into the next function you implemented.
- * <p/>
- * For the example above, the next(T info) function may look like this
- * <p/>
- * public boolean next(T info){
- * if (info == null) {
- * return false;
- * } else if (info.getName().equals("get")) {
- * return Math.random() > 0.5;
- * } else if (info.getName().equals("put")) {
- * return Math.random() > 0.25;
- * } else {
- * return false;
- * }
- * }
- * This would trace 50% of all gets, 75% of all puts and would not trace any other requests.
- */
-public interface Sampler<T> {
-
- public static final Sampler<?> ALWAYS = AlwaysSampler.INSTANCE;
- public static final Sampler<?> NEVER = NeverSampler.INSTANCE;
-
- public boolean next(T info);
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/htrace-core/src/main/java/org/htrace/Span.java
----------------------------------------------------------------------
diff --git a/htrace-core/src/main/java/org/htrace/Span.java b/htrace-core/src/main/java/org/htrace/Span.java
deleted file mode 100644
index d7d0d9a..0000000
--- a/htrace-core/src/main/java/org/htrace/Span.java
+++ /dev/null
@@ -1,116 +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.htrace;
-
-import java.util.List;
-import java.util.Map;
-
-
-/**
- * Base interface for gathering and reporting statistics about a block of
- * execution.
- * <p/>
- * Spans form a tree structure with the parent relationship. The first span in a
- * trace has no parent span.
- */
-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 parent span, returns
- * ROOT_SPAN_ID if this is the root span
- */
- 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<byte[], byte[]> getKVAnnotations();
-
- /**
- * Get any timeline annotations (read only)
- */
- List<TimelineAnnotation> getTimelineAnnotations();
-
- /**
- * Return a unique id for the node or process from which this Span originated.
- * IP address is a reasonable choice.
- *
- * @return
- */
- String getProcessId();
-}
http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/a27cd4da/htrace-core/src/main/java/org/htrace/SpanReceiver.java
----------------------------------------------------------------------
diff --git a/htrace-core/src/main/java/org/htrace/SpanReceiver.java b/htrace-core/src/main/java/org/htrace/SpanReceiver.java
deleted file mode 100644
index 65cfb45..0000000
--- a/htrace-core/src/main/java/org/htrace/SpanReceiver.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.htrace;
-
-
-import java.io.Closeable;
-
-
-/**
- * The collector within a process that is the destination of Spans when a trace
- * is running.
- */
-public interface SpanReceiver extends Closeable {
-
- /**
- * Hosts of SpanReceivers should call this method to provide
- * configuration to SpanReceivers after creating them.
- */
- public void configure(HTraceConfiguration conf);
-
- /**
- * Called when a Span is stopped and can now be stored.
- *
- * @param span
- */
- public void receiveSpan(Span span);
-
-}