http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/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 deleted file mode 100644 index 9d49cf9..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/impl/MilliSpan.java +++ /dev/null @@ -1,352 +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.impl; - -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 org.apache.htrace.Span; -import org.apache.htrace.SpanId; -import org.apache.htrace.TimelineAnnotation; -import org.apache.htrace.Tracer; - -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/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 deleted file mode 100644 index 3cb3827..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/impl/NeverSampler.java +++ /dev/null @@ -1,37 +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.impl; - -import org.apache.htrace.HTraceConfiguration; -import org.apache.htrace.Sampler; - -/** - * 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/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 deleted file mode 100644 index 57e5299..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/impl/POJOSpanReceiver.java +++ /dev/null @@ -1,53 +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.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; - - 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/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 deleted file mode 100644 index 903e590..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/impl/ProbabilitySampler.java +++ /dev/null @@ -1,48 +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.impl; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.htrace.HTraceConfiguration; -import org.apache.htrace.Sampler; - -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; - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/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 deleted file mode 100644 index f88af7f..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/impl/StandardOutSpanReceiver.java +++ /dev/null @@ -1,45 +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.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 java.io.IOException; - -/** - * Used for testing. Simply prints to standard out any spans it receives. - */ -public class StandardOutSpanReceiver implements SpanReceiver { - private static final Log LOG = LogFactory.getLog(StandardOutSpanReceiver.class); - - public StandardOutSpanReceiver(HTraceConfiguration conf) { - LOG.trace("Created new StandardOutSpanReceiver."); - } - - @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/fd889b65/htrace-core/src/main/java/org/apache/htrace/impl/TracerId.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/main/java/org/apache/htrace/impl/TracerId.java b/htrace-core/src/main/java/org/apache/htrace/impl/TracerId.java deleted file mode 100644 index 83fa558..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/impl/TracerId.java +++ /dev/null @@ -1,291 +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.impl; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.htrace.HTraceConfiguration; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.lang.management.ManagementFactory; -import java.net.InetAddress; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.util.Enumeration; -import java.util.Locale; -import java.util.TreeSet; - -/** - * The HTrace tracer ID.<p/> - * - * HTrace tracer IDs are created from format strings. - * Format strings contain variables which the TracerId class will - * replace with the correct values at runtime.<p/> - * - * <ul> - * <li>${ip}: will be replaced with an ip address.</li> - * <li>${pname}: will be replaced the process name obtained from java.</li> - * </ul><p/> - * - * For example, the string "${pname}/${ip}" will be replaced with something - * like: DataNode/192.168.0.1, assuming that the process' name is DataNode - * and its IP address is 192.168.0.1.<p/> - * - * Process ID strings can contain backslashes as escapes. - * For example, "\a" will map to "a". "\${ip}" will map to the literal - * string "${ip}", not the IP address. A backslash itself can be escaped by a - * preceding backslash. - */ -public final class TracerId { - private static final Log LOG = LogFactory.getLog(TracerId.class); - - /** - * The configuration key to use for process id - */ - public static final String TRACER_ID_KEY = "process.id"; - - /** - * The default process ID to use if no other ID is configured. - */ - private static final String DEFAULT_TRACER_ID = "${pname}/${ip}"; - - private final String tracerId; - - TracerId(String fmt) { - StringBuilder bld = new StringBuilder(); - StringBuilder varBld = null; - boolean escaping = false; - int varSeen = 0; - for (int i = 0, len = fmt.length() ; i < len; i++) { - char c = fmt.charAt(i); - if (c == '\\') { - if (!escaping) { - escaping = true; - continue; - } - } - switch (varSeen) { - case 0: - if (c == '$') { - if (!escaping) { - varSeen = 1; - continue; - } - } - escaping = false; - varSeen = 0; - bld.append(c); - break; - case 1: - if (c == '{') { - if (!escaping) { - varSeen = 2; - varBld = new StringBuilder(); - continue; - } - } - escaping = false; - varSeen = 0; - bld.append("$").append(c); - break; - default: - if (c == '}') { - if (!escaping) { - String var = varBld.toString(); - bld.append(processShellVar(var)); - varBld = null; - varSeen = 0; - continue; - } - } - escaping = false; - varBld.append(c); - varSeen++; - break; - } - } - if (varSeen > 0) { - LOG.warn("Unterminated process ID substitution variable at the end " + - "of format string " + fmt); - } - this.tracerId = bld.toString(); - if (LOG.isTraceEnabled()) { - LOG.trace("ProcessID(fmt=" + fmt + "): computed process ID of \"" + - this.tracerId + "\""); - } - } - - public TracerId(HTraceConfiguration conf) { - this(conf.get(TRACER_ID_KEY, DEFAULT_TRACER_ID)); - } - - private String processShellVar(String var) { - if (var.equals("pname")) { - return getProcessName(); - } else if (var.equals("ip")) { - return getBestIpString(); - } else if (var.equals("pid")) { - return Long.valueOf(getOsPid()).toString(); - } else { - LOG.warn("unknown ProcessID variable " + var); - return ""; - } - } - - static String getProcessName() { - 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]; - } - return (cmdLine == null || cmdLine.isEmpty()) ? "Unknown" : cmdLine; - } - - /** - * Get the best IP address that represents this node.<p/> - * - * This is complicated since nodes can have multiple network interfaces, - * and each network interface can have multiple IP addresses. What we're - * looking for here is an IP address that will serve to identify this node - * to HTrace. So we prefer site-local addresess (i.e. private ones on the - * LAN) to publicly routable interfaces. If there are multiple addresses - * to choose from, we select the one which comes first in textual sort - * order. This should ensure that we at least consistently call each node - * by a single name. - */ - static String getBestIpString() { - Enumeration<NetworkInterface> ifaces; - try { - ifaces = NetworkInterface.getNetworkInterfaces(); - } catch (SocketException e) { - LOG.error("Error getting network interfaces", e); - return "127.0.0.1"; - } - TreeSet<String> siteLocalCandidates = new TreeSet<String>(); - TreeSet<String> candidates = new TreeSet<String>(); - while (ifaces.hasMoreElements()) { - NetworkInterface iface = ifaces.nextElement(); - for (Enumeration<InetAddress> addrs = - iface.getInetAddresses(); addrs.hasMoreElements();) { - InetAddress addr = addrs.nextElement(); - if (!addr.isLoopbackAddress()) { - if (addr.isSiteLocalAddress()) { - siteLocalCandidates.add(addr.getHostAddress()); - } else { - candidates.add(addr.getHostAddress()); - } - } - } - } - if (!siteLocalCandidates.isEmpty()) { - return siteLocalCandidates.first(); - } - if (!candidates.isEmpty()) { - return candidates.first(); - } - return "127.0.0.1"; - } - - /** - * Get the process id from the operating system.<p/> - * - * Unfortunately, there is no simple method to get the process id in Java. - * The approach we take here is to use the shell method (see - * {TracerId#getOsPidFromShellPpid}) unless we are on Windows, where the - * shell is not available. On Windows, we use - * {TracerId#getOsPidFromManagementFactory}, which depends on some - * undocumented features of the JVM, but which doesn't require a shell. - */ - static long getOsPid() { - if ((System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH)). - contains("windows")) { - return getOsPidFromManagementFactory(); - } else { - return getOsPidFromShellPpid(); - } - } - - /** - * Get the process ID by executing a shell and printing the PPID (parent - * process ID).<p/> - * - * This method of getting the process ID doesn't depend on any undocumented - * features of the virtual machine, and should work on almost any UNIX - * operating system. - */ - private static long getOsPidFromShellPpid() { - Process p = null; - StringBuilder sb = new StringBuilder(); - try { - p = new ProcessBuilder("/usr/bin/env", "sh", "-c", "echo $PPID"). - redirectErrorStream(true).start(); - BufferedReader reader = new BufferedReader( - new InputStreamReader(p.getInputStream())); - String line = ""; - while ((line = reader.readLine()) != null) { - sb.append(line.trim()); - } - int exitVal = p.waitFor(); - if (exitVal != 0) { - throw new IOException("Process exited with error code " + - Integer.valueOf(exitVal).toString()); - } - } catch (InterruptedException e) { - LOG.error("Interrupted while getting operating system pid from " + - "the shell.", e); - return 0L; - } catch (IOException e) { - LOG.error("Error getting operating system pid from the shell.", e); - return 0L; - } finally { - if (p != null) { - p.destroy(); - } - } - try { - return Long.parseLong(sb.toString()); - } catch (NumberFormatException e) { - LOG.error("Error parsing operating system pid from the shell.", e); - return 0L; - } - } - - /** - * Get the process ID by looking at the name of the managed bean for the - * runtime system of the Java virtual machine.<p/> - * - * Although this is undocumented, in the Oracle JVM this name is of the form - * [OS_PROCESS_ID]@[HOSTNAME]. - */ - private static long getOsPidFromManagementFactory() { - try { - return Long.parseLong(ManagementFactory.getRuntimeMXBean(). - getName().split("@")[0]); - } catch (NumberFormatException e) { - LOG.error("Failed to get the operating system process ID from the name " + - "of the managed bean for the JVM.", e); - return 0L; - } - } - - public String get() { - return tracerId; - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/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 deleted file mode 100644 index e761fbf..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/wrappers/TraceCallable.java +++ /dev/null @@ -1,69 +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.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/fd889b65/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 deleted file mode 100644 index 03e891f..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/wrappers/TraceExecutorService.java +++ /dev/null @@ -1,118 +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.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/fd889b65/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 deleted file mode 100644 index c1aba29..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/wrappers/TraceProxy.java +++ /dev/null @@ -1,62 +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.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. - */ - public static <T> T trace(T instance) { - return trace(instance, Sampler.ALWAYS); - } - - /** - * Returns an object that will trace all calls to itself. - */ - @SuppressWarnings("unchecked") - public static <T, V> T trace(final T instance, final Sampler sampler) { - InvocationHandler handler = new InvocationHandler() { - @Override - public Object invoke(Object obj, Method method, Object[] args) - throws Throwable { - if (!sampler.next()) { - 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/fd889b65/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 deleted file mode 100644 index 6d370c8..0000000 --- a/htrace-core/src/main/java/org/apache/htrace/wrappers/TraceRunnable.java +++ /dev/null @@ -1,68 +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.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; - } - - public Runnable getRunnable() { - return runnable; - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/test/java/org/apache/htrace/TestBadClient.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/test/java/org/apache/htrace/TestBadClient.java b/htrace-core/src/test/java/org/apache/htrace/TestBadClient.java deleted file mode 100644 index 868c0d0..0000000 --- a/htrace-core/src/test/java/org/apache/htrace/TestBadClient.java +++ /dev/null @@ -1,154 +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 static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.hamcrest.CoreMatchers.containsString; - -import org.apache.htrace.HTraceConfiguration; -import org.apache.htrace.Span; -import org.apache.htrace.SpanReceiver; -import org.apache.htrace.Tracer; -import org.apache.htrace.impl.AlwaysSampler; -import org.apache.htrace.impl.LocalFileSpanReceiver; -import org.apache.htrace.impl.POJOSpanReceiver; -import org.apache.htrace.impl.StandardOutSpanReceiver; -import org.junit.After; -import org.junit.Assert; -import org.junit.Test; - -import java.io.File; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; - -public class TestBadClient { - /** - * Test closing an outer scope when an inner one is still active. - */ - @Test - public void TestClosingOuterScope() throws Exception { - boolean gotException = false; - TraceScope outerScope = Trace.startSpan("outer", AlwaysSampler.INSTANCE); - TraceScope innerScope = Trace.startSpan("inner"); - try { - outerScope.close(); - } catch (RuntimeException e) { - assertThat(e.getMessage(), - containsString("You have probably forgotten to close or detach")); - gotException = true; - } - assertTrue("Expected to get exception because of improper " + - "scope closure.", gotException); - innerScope.close(); - } - - /** - * Test calling detach() two times on a scope object. - */ - @Test - public void TestDoubleDetach() throws Exception { - boolean gotException = false; - TraceScope myScope = Trace.startSpan("myScope", AlwaysSampler.INSTANCE); - myScope.detach(); - try { - myScope.detach(); - } catch (RuntimeException e) { - assertThat(e.getMessage(), - containsString("it has already been detached.")); - gotException = true; - } - assertTrue("Expected to get exception because of double TraceScope " + - "detach.", gotException); - } - - private static class SpanHolder { - Span span; - - void set(Span span) { - this.span = span; - } - } - - /** - * Test correctly passing spans between threads using detach(). - */ - @Test - public void TestPassingSpanBetweenThreads() throws Exception { - final SpanHolder spanHolder = new SpanHolder(); - Thread th = new Thread(new Runnable() { - @Override - public void run() { - TraceScope workerScope = Trace.startSpan("workerSpan", - AlwaysSampler.INSTANCE); - spanHolder.set(workerScope.getSpan()); - workerScope.detach(); - } - }); - th.start(); - th.join(); - - // Create new scope whose parent is the worker thread's span. - TraceScope outermost = Trace.startSpan("outermost", spanHolder.span); - TraceScope nested = Trace.startSpan("nested"); - nested.close(); - outermost.close(); - // Create another span which also descends from the worker thread's span. - TraceScope nested2 = Trace.startSpan("nested2", spanHolder.span); - nested2.close(); - - // Close the worker thread's span. - spanHolder.span.stop(); - - // We can create another descendant, even though the worker thread's span - // has been stopped. - TraceScope lateChildScope = Trace.startSpan("lateChild", spanHolder.span); - lateChildScope.close(); - } - - /** - * Test trying to manually set our TraceScope's parent in a case where there - * is a currently active span. - */ - @Test - public void TestIncorrectStartSpan() throws Exception { - // Create new scope - TraceScope outermost = Trace.startSpan("outermost", - AlwaysSampler.INSTANCE); - // Create nested scope - TraceScope nested = Trace.startSpan("nested", outermost.getSpan()); - // Error - boolean gotException = false; - try { - TraceScope error = Trace.startSpan("error", outermost.getSpan()); - error.close(); - } catch (RuntimeException e) { - assertThat(e.getMessage(), - containsString("there is already a currentSpan")); - gotException = true; - } - assertTrue("Expected to get exception because of incorrect startSpan.", - gotException); - } - - @After - public void resetCurrentSpan() { - Tracer.getInstance().setCurrentSpan(null); - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/test/java/org/apache/htrace/TestCountSampler.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/test/java/org/apache/htrace/TestCountSampler.java b/htrace-core/src/test/java/org/apache/htrace/TestCountSampler.java deleted file mode 100644 index 42ba4e2..0000000 --- a/htrace-core/src/test/java/org/apache/htrace/TestCountSampler.java +++ /dev/null @@ -1,43 +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.HTraceConfiguration; -import org.apache.htrace.impl.CountSampler; -import org.junit.Assert; -import org.junit.Test; - -public class TestCountSampler { - - @Test - public void testNext() { - CountSampler half = new CountSampler(HTraceConfiguration. - fromKeyValuePairs("sampler.frequency", "2")); - CountSampler hundred = new CountSampler(HTraceConfiguration. - fromKeyValuePairs("sampler.frequency", "100")); - int halfCount = 0; - int hundredCount = 0; - for (int i = 0; i < 200; i++) { - if (half.next()) - halfCount++; - if (hundred.next()) - hundredCount++; - } - Assert.assertEquals(2, hundredCount); - Assert.assertEquals(100, halfCount); - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/test/java/org/apache/htrace/TestHTrace.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/test/java/org/apache/htrace/TestHTrace.java b/htrace-core/src/test/java/org/apache/htrace/TestHTrace.java deleted file mode 100644 index 92f96c8..0000000 --- a/htrace-core/src/test/java/org/apache/htrace/TestHTrace.java +++ /dev/null @@ -1,118 +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.TraceGraph.SpansByParent; -import org.apache.htrace.impl.LocalFileSpanReceiver; -import org.apache.htrace.impl.POJOSpanReceiver; -import org.apache.htrace.impl.StandardOutSpanReceiver; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; - -import java.io.File; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -public class TestHTrace { - - @Rule - public TraceCreator traceCreator = new TraceCreator(); - - public static final String SPAN_FILE_FLAG = "spanFile"; - - /** - * Basic system test of HTrace. - * - * @throws Exception - */ - @Test - public void testHtrace() throws Exception { - final int numTraces = 3; - String fileName = System.getProperty(SPAN_FILE_FLAG); - - // writes spans to a file if one is provided to maven with - // -DspanFile="FILENAME", otherwise writes to standard out. - if (fileName != null) { - File f = new File(fileName); - File parent = f.getParentFile(); - if (parent != null && !parent.exists() && !parent.mkdirs()) { - throw new IllegalArgumentException("Couldn't create file: " - + fileName); - } - HashMap<String, String> conf = new HashMap<String, String>(); - conf.put("local-file-span-receiver.path", fileName); - LocalFileSpanReceiver receiver = - new LocalFileSpanReceiver(HTraceConfiguration.fromMap(conf)); - traceCreator.addReceiver(receiver); - } else { - traceCreator.addReceiver(new StandardOutSpanReceiver(HTraceConfiguration.EMPTY)); - } - - traceCreator.addReceiver(new POJOSpanReceiver(HTraceConfiguration.EMPTY){ - @Override - public void close() { - TraceGraph traceGraph = new TraceGraph(getSpans()); - Collection<Span> roots = traceGraph.getSpansByParent().find(SpanId.INVALID); - Assert.assertTrue("Trace tree must have roots", !roots.isEmpty()); - Assert.assertEquals(numTraces, roots.size()); - - Map<String, Span> descriptionToRootSpan = new HashMap<String, Span>(); - for (Span root : roots) { - descriptionToRootSpan.put(root.getDescription(), root); - } - - Assert.assertTrue(descriptionToRootSpan.keySet().contains( - TraceCreator.RPC_TRACE_ROOT)); - Assert.assertTrue(descriptionToRootSpan.keySet().contains( - TraceCreator.SIMPLE_TRACE_ROOT)); - Assert.assertTrue(descriptionToRootSpan.keySet().contains( - TraceCreator.THREADED_TRACE_ROOT)); - - SpansByParent spansByParentId = traceGraph.getSpansByParent(); - Span rpcTraceRoot = descriptionToRootSpan.get(TraceCreator.RPC_TRACE_ROOT); - Assert.assertEquals(1, spansByParentId.find(rpcTraceRoot.getSpanId()).size()); - - Span rpcTraceChild1 = spansByParentId.find(rpcTraceRoot.getSpanId()) - .iterator().next(); - Assert.assertEquals(1, spansByParentId.find(rpcTraceChild1.getSpanId()).size()); - - Span rpcTraceChild2 = spansByParentId.find(rpcTraceChild1.getSpanId()) - .iterator().next(); - Assert.assertEquals(1, spansByParentId.find(rpcTraceChild2.getSpanId()).size()); - - Span rpcTraceChild3 = spansByParentId.find(rpcTraceChild2.getSpanId()) - .iterator().next(); - Assert.assertEquals(0, spansByParentId.find(rpcTraceChild3.getSpanId()).size()); - } - }); - - traceCreator.createThreadedTrace(); - traceCreator.createSimpleTrace(); - traceCreator.createSampleRpcTrace(); - } - - @Test(timeout=60000) - public void testRootSpansHaveNonZeroSpanId() throws Exception { - TraceScope scope = Trace.startSpan("myRootSpan", new SpanId(100L, 200L)); - Assert.assertNotNull(scope); - Assert.assertEquals("myRootSpan", scope.getSpan().getDescription()); - Assert.assertEquals(100L, scope.getSpan().getSpanId().getHigh()); - Assert.assertTrue(scope.getSpan().getSpanId().isValid()); - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/test/java/org/apache/htrace/TestHTraceConfiguration.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/test/java/org/apache/htrace/TestHTraceConfiguration.java b/htrace-core/src/test/java/org/apache/htrace/TestHTraceConfiguration.java deleted file mode 100644 index 440a826..0000000 --- a/htrace-core/src/test/java/org/apache/htrace/TestHTraceConfiguration.java +++ /dev/null @@ -1,63 +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.util.HashMap; -import java.util.Map; - -import org.apache.htrace.HTraceConfiguration; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class TestHTraceConfiguration { - @Test - public void testGetBoolean() throws Exception { - - Map<String, String> m = new HashMap<String, String>(); - m.put("testTrue", " True"); - m.put("testFalse", "falsE "); - HTraceConfiguration configuration = HTraceConfiguration.fromMap(m); - - // Tests for value being there - assertTrue(configuration.getBoolean("testTrue", false)); - assertFalse(configuration.getBoolean("testFalse", true)); - - // Test for absent - assertTrue(configuration.getBoolean("absent", true)); - assertFalse(configuration.getBoolean("absent", false)); - } - - @Test - public void testGetInt() throws Exception { - Map<String, String> m = new HashMap<String, String>(); - m.put("a", "100"); - m.put("b", "0"); - m.put("c", "-100"); - m.put("d", "5"); - - HTraceConfiguration configuration = HTraceConfiguration.fromMap(m); - assertEquals(100, configuration.getInt("a", -999)); - assertEquals(0, configuration.getInt("b", -999)); - assertEquals(-100, configuration.getInt("c", -999)); - assertEquals(5, configuration.getInt("d", -999)); - assertEquals(-999, configuration.getInt("absent", -999)); - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/test/java/org/apache/htrace/TestNullScope.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/test/java/org/apache/htrace/TestNullScope.java b/htrace-core/src/test/java/org/apache/htrace/TestNullScope.java deleted file mode 100644 index 26b1cba..0000000 --- a/htrace-core/src/test/java/org/apache/htrace/TestNullScope.java +++ /dev/null @@ -1,37 +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.Trace; -import org.apache.htrace.TraceScope; -import org.apache.htrace.NullScope; -import org.junit.Assert; -import org.junit.Test; - -public class TestNullScope { - @Test - public void testNullScope() { - Assert.assertTrue(!Trace.isTracing()); - TraceScope tc = Trace.startSpan("NullScopeSingleton"); - Assert.assertTrue(tc == NullScope.INSTANCE); - tc.detach(); - tc.detach(); // should not fail even if called multiple times. - Assert.assertFalse(tc.isDetached()); - tc.close(); - tc.close(); // should not fail even if called multiple times. - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/test/java/org/apache/htrace/TestSampler.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/test/java/org/apache/htrace/TestSampler.java b/htrace-core/src/test/java/org/apache/htrace/TestSampler.java deleted file mode 100644 index 7ff2e31..0000000 --- a/htrace-core/src/test/java/org/apache/htrace/TestSampler.java +++ /dev/null @@ -1,59 +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.util.HashMap; -import java.util.Map; -import org.apache.htrace.Sampler; -import org.apache.htrace.Trace; -import org.apache.htrace.TraceScope; -import org.apache.htrace.impl.AlwaysSampler; -import org.apache.htrace.impl.NeverSampler; -import org.junit.Assert; -import org.junit.Test; - -public class TestSampler { - @Test - public void testSamplerBuilder() { - Sampler alwaysSampler = new SamplerBuilder( - HTraceConfiguration.fromKeyValuePairs("sampler", "AlwaysSampler")). - build(); - Assert.assertEquals(AlwaysSampler.class, alwaysSampler.getClass()); - - Sampler neverSampler = new SamplerBuilder( - HTraceConfiguration.fromKeyValuePairs("sampler", "NeverSampler")). - build(); - Assert.assertEquals(NeverSampler.class, neverSampler.getClass()); - - Sampler neverSampler2 = new SamplerBuilder(HTraceConfiguration. - fromKeyValuePairs("sampler", "NonExistentSampler")). - build(); - Assert.assertEquals(NeverSampler.class, neverSampler2.getClass()); - - Sampler neverSampler3 = new SamplerBuilder(HTraceConfiguration. - fromKeyValuePairs("sampler.is.not.defined", "NonExistentSampler")). - build(); - Assert.assertEquals(NeverSampler.class, neverSampler3.getClass()); - } - - @Test - public void testAlwaysSampler() { - TraceScope cur = Trace.startSpan("test"); - Assert.assertNotNull(cur); - cur.close(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/test/java/org/apache/htrace/TestSpanId.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/test/java/org/apache/htrace/TestSpanId.java b/htrace-core/src/test/java/org/apache/htrace/TestSpanId.java deleted file mode 100644 index 10e6cca..0000000 --- a/htrace-core/src/test/java/org/apache/htrace/TestSpanId.java +++ /dev/null @@ -1,72 +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.util.Random; -import org.apache.htrace.SpanId; -import org.junit.Assert; -import org.junit.Test; - -public class TestSpanId { - private void testRoundTrip(SpanId id) throws Exception { - String str = id.toString(); - SpanId id2 = SpanId.fromString(str); - Assert.assertEquals(id, id2); - } - - @Test - public void testToStringAndFromString() throws Exception { - testRoundTrip(SpanId.INVALID); - testRoundTrip(new SpanId(0x1234567812345678L, 0x1234567812345678L)); - testRoundTrip(new SpanId(0xf234567812345678L, 0xf234567812345678L)); - testRoundTrip(new SpanId(0xffffffffffffffffL, 0xffffffffffffffffL)); - Random rand = new Random(12345); - for (int i = 0; i < 100; i++) { - testRoundTrip(new SpanId(rand.nextLong(), rand.nextLong())); - } - } - - @Test - public void testValidAndInvalidIds() throws Exception { - Assert.assertFalse(SpanId.INVALID.isValid()); - Assert.assertTrue( - new SpanId(0x1234567812345678L, 0x1234567812345678L).isValid()); - Assert.assertTrue( - new SpanId(0xf234567812345678L, 0xf234567812345678L).isValid()); - } - - private void expectLessThan(SpanId a, SpanId b) throws Exception { - int cmp = a.compareTo(b); - Assert.assertTrue("Expected " + a + " to be less than " + b, - (cmp < 0)); - int cmp2 = b.compareTo(a); - Assert.assertTrue("Expected " + b + " to be greater than " + a, - (cmp2 > 0)); - } - - @Test - public void testIdComparisons() throws Exception { - expectLessThan(new SpanId(0x0000000000000001L, 0x0000000000000001L), - new SpanId(0x0000000000000001L, 0x0000000000000002L)); - expectLessThan(new SpanId(0x0000000000000001L, 0x0000000000000001L), - new SpanId(0x0000000000000002L, 0x0000000000000000L)); - expectLessThan(SpanId.INVALID, - new SpanId(0xffffffffffffffffL, 0xffffffffffffffffL)); - expectLessThan(new SpanId(0x1234567812345678L, 0x1234567812345678L), - new SpanId(0x1234567812345678L, 0xf234567812345678L)); - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/test/java/org/apache/htrace/TestSpanReceiverBuilder.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/test/java/org/apache/htrace/TestSpanReceiverBuilder.java b/htrace-core/src/test/java/org/apache/htrace/TestSpanReceiverBuilder.java deleted file mode 100644 index 750142b..0000000 --- a/htrace-core/src/test/java/org/apache/htrace/TestSpanReceiverBuilder.java +++ /dev/null @@ -1,140 +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.LocalFileSpanReceiver; -import org.junit.Assert; -import org.junit.Test; - -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -public class TestSpanReceiverBuilder { - private static final Log LOG = - LogFactory.getLog(TestSpanReceiverBuilder.class); - - /** - * Test that if no span receiver is configured, the builder returns null. - */ - @Test - public void testGetNullSpanReceiver() { - SpanReceiverBuilder builder = - new SpanReceiverBuilder(HTraceConfiguration.EMPTY).logErrors(false); - SpanReceiver rcvr = builder.build(); - Assert.assertEquals(null, rcvr); - } - - private static SpanReceiver createSpanReceiver(Map<String, String> m) { - HTraceConfiguration hconf = HTraceConfiguration.fromMap(m); - SpanReceiverBuilder builder = - new SpanReceiverBuilder(hconf). - logErrors(false); - return builder.build(); - } - - private static final File TMPDIR = - new File(System.getProperty("java.io.tmpdir")); - - /** - * Test getting various SpanReceiver objects. - */ - @Test - public void testGetSpanReceivers() throws Exception { - HashMap<String, String> confMap = new HashMap<String, String>(); - - // Create LocalFileSpanReceiver - File testFile = new File(TMPDIR, UUID.randomUUID().toString()); - try { - confMap.put(LocalFileSpanReceiver.PATH_KEY, testFile.getAbsolutePath()); - confMap.put(SpanReceiverBuilder.SPAN_RECEIVER_CONF_KEY, - "org.apache.htrace.impl.LocalFileSpanReceiver"); - SpanReceiver rcvr = createSpanReceiver(confMap); - Assert.assertNotNull(rcvr); - Assert.assertEquals("org.apache.htrace.impl.LocalFileSpanReceiver", - rcvr.getClass().getName()); - rcvr.close(); - } finally { - if (!testFile.delete()) { - LOG.debug("failed to delete " + testFile); // keep findbugs happy - } - } - - // Create POJOSpanReceiver - confMap.remove(LocalFileSpanReceiver.PATH_KEY); - confMap.put(SpanReceiverBuilder.SPAN_RECEIVER_CONF_KEY, "POJOSpanReceiver"); - SpanReceiver rcvr = createSpanReceiver(confMap); - Assert.assertEquals("org.apache.htrace.impl.POJOSpanReceiver", - rcvr.getClass().getName()); - rcvr.close(); - - // Create StandardOutSpanReceiver - confMap.remove(LocalFileSpanReceiver.PATH_KEY); - confMap.put(SpanReceiverBuilder.SPAN_RECEIVER_CONF_KEY, - "org.apache.htrace.impl.StandardOutSpanReceiver"); - rcvr = createSpanReceiver(confMap); - Assert.assertEquals("org.apache.htrace.impl.StandardOutSpanReceiver", - rcvr.getClass().getName()); - rcvr.close(); - } - - public static class TestSpanReceiver implements SpanReceiver { - final static String SUCCEEDS = "test.span.receiver.succeeds"; - - public TestSpanReceiver(HTraceConfiguration conf) { - if (conf.get(SUCCEEDS) == null) { - throw new RuntimeException("Can't create TestSpanReceiver: " + - "invalid configuration."); - } - } - - @Override - public void receiveSpan(Span span) { - } - - @Override - public void close() throws IOException { - } - } - - /** - * Test trying to create a SpanReceiver that experiences an error in the - * constructor. - */ - @Test - public void testGetSpanReceiverWithConstructorError() throws Exception { - HashMap<String, String> confMap = new HashMap<String, String>(); - - // Create TestSpanReceiver - confMap.put(SpanReceiverBuilder.SPAN_RECEIVER_CONF_KEY, - TestSpanReceiver.class.getName()); - confMap.put(TestSpanReceiver.SUCCEEDS, "true"); - SpanReceiver rcvr = createSpanReceiver(confMap); - Assert.assertEquals(TestSpanReceiver.class.getName(), - rcvr.getClass().getName()); - rcvr.close(); - - // Fail to create TestSpanReceiver - confMap.remove(TestSpanReceiver.SUCCEEDS); - rcvr = createSpanReceiver(confMap); - Assert.assertEquals(null, rcvr); - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/test/java/org/apache/htrace/TraceCreator.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/test/java/org/apache/htrace/TraceCreator.java b/htrace-core/src/test/java/org/apache/htrace/TraceCreator.java deleted file mode 100644 index 565ba05..0000000 --- a/htrace-core/src/test/java/org/apache/htrace/TraceCreator.java +++ /dev/null @@ -1,169 +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.junit.rules.TestRule; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; - -import java.util.Collection; -import java.util.Random; -import java.util.concurrent.ThreadLocalRandom; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -/** - * Does some stuff and traces it. - */ -public class TraceCreator implements TestRule { - private final List<SpanReceiver> receivers = new ArrayList<SpanReceiver>(); - - public static final String RPC_TRACE_ROOT = "createSampleRpcTrace"; - public static final String THREADED_TRACE_ROOT = "createThreadedTrace"; - public static final String SIMPLE_TRACE_ROOT = "createSimpleTrace"; - - public TraceCreator addReceiver(SpanReceiver receiver) { - Trace.addReceiver(receiver); - this.receivers.add(receiver); - return this; - } - - @Override - public Statement apply(final Statement base, Description description) { - return new Statement() { - @Override - public void evaluate() throws Throwable { - try { - base.evaluate(); - for (SpanReceiver receiver : receivers) { - receiver.close(); - } - } finally { - for (SpanReceiver receiver : receivers) { - Trace.removeReceiver(receiver); - } - } - } - }; - } - - public void createSampleRpcTrace() { - TraceScope s = Trace.startSpan(RPC_TRACE_ROOT, Sampler.ALWAYS); - try { - pretendRpcSend(); - } finally { - s.close(); - } - } - - public void createSimpleTrace() { - TraceScope s = Trace.startSpan(SIMPLE_TRACE_ROOT, Sampler.ALWAYS); - try { - importantWork1(); - } finally { - s.close(); - } - } - - /** - * Creates the demo trace (will create different traces from call to call). - */ - public void createThreadedTrace() { - TraceScope s = Trace.startSpan(THREADED_TRACE_ROOT, Sampler.ALWAYS); - try { - Random r = ThreadLocalRandom.current(); - int numThreads = r.nextInt(4) + 1; - Thread[] threads = new Thread[numThreads]; - - for (int i = 0; i < numThreads; i++) { - threads[i] = new Thread(Trace.wrap(new MyRunnable())); - } - for (int i = 0; i < numThreads; i++) { - threads[i].start(); - } - for (int i = 0; i < numThreads; i++) { - try { - threads[i].join(); - } catch (InterruptedException e) { - } - } - importantWork1(); - } finally { - s.close(); - } - } - - private void importantWork1() { - TraceScope cur = Trace.startSpan("important work 1"); - try { - Thread.sleep((long) (2000 * Math.random())); - importantWork2(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } finally { - cur.close(); - } - } - - private void importantWork2() { - TraceScope cur = Trace.startSpan("important work 2"); - try { - Thread.sleep((long) (2000 * Math.random())); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } finally { - cur.close(); - } - } - - private class MyRunnable implements Runnable { - @Override - public void run() { - try { - Thread.sleep(750); - Random r = ThreadLocalRandom.current(); - int importantNumber = 100 / r.nextInt(3); - System.out.println("Important number: " + importantNumber); - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - } catch (ArithmeticException ae) { - TraceScope c = Trace.startSpan("dealing with arithmetic exception."); - try { - Thread.sleep((long) (3000 * Math.random())); - } catch (InterruptedException ie1) { - Thread.currentThread().interrupt(); - } finally { - c.close(); - } - } - } - } - - public void pretendRpcSend() { - pretendRpcReceiveWithTraceInfo(Trace.currentSpan()); - } - - public void pretendRpcReceiveWithTraceInfo(Span parent) { - TraceScope s = Trace.startSpan("received RPC", parent); - try { - importantWork1(); - } finally { - s.close(); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/test/java/org/apache/htrace/TraceGraph.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/test/java/org/apache/htrace/TraceGraph.java b/htrace-core/src/test/java/org/apache/htrace/TraceGraph.java deleted file mode 100644 index 9004ea6..0000000 --- a/htrace-core/src/test/java/org/apache/htrace/TraceGraph.java +++ /dev/null @@ -1,179 +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.MilliSpan; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.Arrays; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.TreeSet; - -/** - * Used to create the graph formed by spans. - */ -public class TraceGraph { - private static final Log LOG = LogFactory.getLog(Tracer.class); - - - public static class SpansByParent { - /** - * Compare two spans by span ID. - */ - private static Comparator<Span> COMPARATOR = - new Comparator<Span>() { - @Override - public int compare(Span a, Span b) { - return a.getSpanId().compareTo(b.getSpanId()); - } - }; - - private final TreeSet<Span> treeSet; - - private final HashMap<SpanId, LinkedList<Span>> parentToSpans; - - SpansByParent(Collection<Span> spans) { - TreeSet<Span> treeSet = new TreeSet<Span>(COMPARATOR); - parentToSpans = new HashMap<SpanId, LinkedList<Span>>(); - for (Span span : spans) { - treeSet.add(span); - for (SpanId parent : span.getParents()) { - LinkedList<Span> list = parentToSpans.get(parent); - if (list == null) { - list = new LinkedList<Span>(); - parentToSpans.put(parent, list); - } - list.add(span); - } - if (span.getParents().length == 0) { - LinkedList<Span> list = parentToSpans.get(SpanId.INVALID); - if (list == null) { - list = new LinkedList<Span>(); - parentToSpans.put(SpanId.INVALID, list); - } - list.add(span); - } - } - this.treeSet = treeSet; - } - - public List<Span> find(SpanId parentId) { - LinkedList<Span> spans = parentToSpans.get(parentId); - if (spans == null) { - return new LinkedList<Span>(); - } - return spans; - } - - public Iterator<Span> iterator() { - return Collections.unmodifiableSortedSet(treeSet).iterator(); - } - } - - public static class SpansByTracerId { - /** - * Compare two spans by process ID, and then by span ID. - */ - private static Comparator<Span> COMPARATOR = - new Comparator<Span>() { - @Override - public int compare(Span a, Span b) { - int cmp = a.getTracerId().compareTo(b.getTracerId()); - if (cmp != 0) { - return cmp; - } - return a.getSpanId().compareTo(b.getSpanId()); - } - }; - - private final TreeSet<Span> treeSet; - - SpansByTracerId(Collection<Span> spans) { - TreeSet<Span> treeSet = new TreeSet<Span>(COMPARATOR); - for (Span span : spans) { - treeSet.add(span); - } - this.treeSet = treeSet; - } - - public List<Span> find(String tracerId) { - List<Span> spans = new ArrayList<Span>(); - Span span = new MilliSpan.Builder(). - spanId(SpanId.INVALID). - tracerId(tracerId). - build(); - while (true) { - span = treeSet.higher(span); - if (span == null) { - break; - } - if (span.getTracerId().equals(tracerId)) { - break; - } - spans.add(span); - } - return spans; - } - - public Iterator<Span> iterator() { - return Collections.unmodifiableSortedSet(treeSet).iterator(); - } - } - - private final SpansByParent spansByParent; - private final SpansByTracerId spansByTracerId; - - /** - * Create a new TraceGraph - * - * @param spans The collection of spans to use to create this TraceGraph. Should - * have at least one root span. - */ - public TraceGraph(Collection<Span> spans) { - this.spansByParent = new SpansByParent(spans); - this.spansByTracerId = new SpansByTracerId(spans); - } - - public SpansByParent getSpansByParent() { - return spansByParent; - } - - public SpansByTracerId getSpansByTracerId() { - return spansByTracerId; - } - - @Override - public String toString() { - StringBuilder bld = new StringBuilder(); - String prefix = ""; - for (Iterator<Span> iter = spansByParent.iterator(); iter.hasNext();) { - Span span = iter.next(); - bld.append(prefix).append(span.toString()); - prefix = "\n"; - } - return bld.toString(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/fd889b65/htrace-core/src/test/java/org/apache/htrace/core/TestBadClient.java ---------------------------------------------------------------------- diff --git a/htrace-core/src/test/java/org/apache/htrace/core/TestBadClient.java b/htrace-core/src/test/java/org/apache/htrace/core/TestBadClient.java new file mode 100644 index 0000000..54de21b --- /dev/null +++ b/htrace-core/src/test/java/org/apache/htrace/core/TestBadClient.java @@ -0,0 +1,146 @@ +/* + * 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 static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.hamcrest.CoreMatchers.containsString; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Test; + +import java.io.File; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; + +public class TestBadClient { + /** + * Test closing an outer scope when an inner one is still active. + */ + @Test + public void TestClosingOuterScope() throws Exception { + boolean gotException = false; + TraceScope outerScope = Trace.startSpan("outer", AlwaysSampler.INSTANCE); + TraceScope innerScope = Trace.startSpan("inner"); + try { + outerScope.close(); + } catch (RuntimeException e) { + assertThat(e.getMessage(), + containsString("You have probably forgotten to close or detach")); + gotException = true; + } + assertTrue("Expected to get exception because of improper " + + "scope closure.", gotException); + innerScope.close(); + } + + /** + * Test calling detach() two times on a scope object. + */ + @Test + public void TestDoubleDetach() throws Exception { + boolean gotException = false; + TraceScope myScope = Trace.startSpan("myScope", AlwaysSampler.INSTANCE); + myScope.detach(); + try { + myScope.detach(); + } catch (RuntimeException e) { + assertThat(e.getMessage(), + containsString("it has already been detached.")); + gotException = true; + } + assertTrue("Expected to get exception because of double TraceScope " + + "detach.", gotException); + } + + private static class SpanHolder { + Span span; + + void set(Span span) { + this.span = span; + } + } + + /** + * Test correctly passing spans between threads using detach(). + */ + @Test + public void TestPassingSpanBetweenThreads() throws Exception { + final SpanHolder spanHolder = new SpanHolder(); + Thread th = new Thread(new Runnable() { + @Override + public void run() { + TraceScope workerScope = Trace.startSpan("workerSpan", + AlwaysSampler.INSTANCE); + spanHolder.set(workerScope.getSpan()); + workerScope.detach(); + } + }); + th.start(); + th.join(); + + // Create new scope whose parent is the worker thread's span. + TraceScope outermost = Trace.startSpan("outermost", spanHolder.span); + TraceScope nested = Trace.startSpan("nested"); + nested.close(); + outermost.close(); + // Create another span which also descends from the worker thread's span. + TraceScope nested2 = Trace.startSpan("nested2", spanHolder.span); + nested2.close(); + + // Close the worker thread's span. + spanHolder.span.stop(); + + // We can create another descendant, even though the worker thread's span + // has been stopped. + TraceScope lateChildScope = Trace.startSpan("lateChild", spanHolder.span); + lateChildScope.close(); + } + + /** + * Test trying to manually set our TraceScope's parent in a case where there + * is a currently active span. + */ + @Test + public void TestIncorrectStartSpan() throws Exception { + // Create new scope + TraceScope outermost = Trace.startSpan("outermost", + AlwaysSampler.INSTANCE); + // Create nested scope + TraceScope nested = Trace.startSpan("nested", outermost.getSpan()); + // Error + boolean gotException = false; + try { + TraceScope error = Trace.startSpan("error", outermost.getSpan()); + error.close(); + } catch (RuntimeException e) { + assertThat(e.getMessage(), + containsString("there is already a currentSpan")); + gotException = true; + } + assertTrue("Expected to get exception because of incorrect startSpan.", + gotException); + } + + @After + public void resetCurrentSpan() { + Tracer.getInstance().setCurrentSpan(null); + } +}
