You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by ph...@apache.org on 2010/08/05 02:07:25 UTC
svn commit: r982434 [2/2] - in /avro/trunk: ./
lang/java/src/java/org/apache/avro/ipc/
lang/java/src/java/org/apache/avro/ipc/trace/
lang/java/src/test/java/org/apache/avro/ipc/trace/
share/schemas/org/apache/avro/ipc/trace/
Added: avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestSpanTraceFormation.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestSpanTraceFormation.java?rev=982434&view=auto
==============================================================================
--- avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestSpanTraceFormation.java (added)
+++ avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestSpanTraceFormation.java Thu Aug 5 00:07:24 2010
@@ -0,0 +1,279 @@
+/**
+ * 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.avro.ipc.trace;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.avro.Schema;
+import org.apache.avro.generic.GenericData;
+import org.apache.avro.util.Utf8;
+import org.junit.Test;
+
+public class TestSpanTraceFormation {
+
+ @Test
+ public void testSpanEquality() {
+ Span root = new Span();
+ root.spanID = Util.idValue(10);
+ root.parentSpanID = null;
+ root.messageName = new Utf8("startCall");
+
+ Span a = new Span();
+ a.spanID = Util.idValue(11);
+ a.parentSpanID = Util.idValue(10);
+ a.messageName = new Utf8("childCall1");
+
+ Span b = new Span();
+ b.spanID = Util.idValue(12);
+ b.parentSpanID = Util.idValue(10);
+ b.messageName = new Utf8("childCall2");
+
+ Span c = new Span();
+ c.spanID = Util.idValue(13);
+ c.parentSpanID = Util.idValue(10);
+ c.messageName = new Utf8("childCall3");
+
+ List<Span> spans = new LinkedList<Span>();
+ spans.add(root);
+ spans.add(a);
+ spans.add(b);
+ spans.add(c);
+ Trace trace1 = Trace.extractTrace(spans);
+
+ Span d = new Span();
+ d.spanID = Util.idValue(11);
+ d.parentSpanID = Util.idValue(10);
+ d.messageName = new Utf8("childCall1");
+
+ Span e = new Span();
+ e.spanID = Util.idValue(12);
+ e.parentSpanID = Util.idValue(10);
+ e.messageName = new Utf8("childCall2");
+
+ Span f = new Span();
+ f.spanID = Util.idValue(13);
+ f.parentSpanID = Util.idValue(10);
+ f.messageName = new Utf8("childCall3");
+
+ spans.clear();
+ spans.add(d);
+ spans.add(e);
+ spans.add(f);
+ spans.add(root);
+ Trace trace2 = Trace.extractTrace(spans);
+
+ assertEquals(trace1.executionPathHash(), trace2.executionPathHash());
+ }
+
+
+ @Test
+ public void testSpanEquality2() {
+ Span root = new Span();
+ root.spanID = Util.idValue(10);
+ root.parentSpanID = null;
+ root.messageName = new Utf8("startCall");
+
+ Span a = new Span();
+ a.spanID = Util.idValue(11);
+ a.parentSpanID = Util.idValue(10);
+ a.messageName = new Utf8("childCall1");
+
+ Span b = new Span();
+ b.spanID = Util.idValue(12);
+ b.parentSpanID = Util.idValue(10);
+ b.messageName = new Utf8("childCall2");
+
+ Span c = new Span();
+ c.spanID = Util.idValue(13);
+ c.parentSpanID = Util.idValue(10);
+ c.messageName = new Utf8("childCall3");
+
+ List<Span> spans = new LinkedList<Span>();
+ spans.add(root);
+ spans.add(a);
+ spans.add(b);
+ spans.add(c);
+ Trace trace1 = Trace.extractTrace(spans);
+
+ Span d = new Span();
+ d.spanID = Util.idValue(11);
+ d.parentSpanID = Util.idValue(10);
+ d.messageName = new Utf8("childCall1");
+
+ Span e = new Span();
+ e.spanID = Util.idValue(12);
+ e.parentSpanID = Util.idValue(10);
+ e.messageName = new Utf8("childCall2");
+
+ Span f = new Span();
+ f.spanID = Util.idValue(13);
+ f.parentSpanID = Util.idValue(10);
+ f.messageName = new Utf8("childCall3");
+
+ Span g = new Span();
+ g.spanID = Util.idValue(14);
+ g.parentSpanID = Util.idValue(13);
+ g.messageName = new Utf8("childCall4");
+
+ spans.clear();
+ spans.add(d);
+ spans.add(e);
+ spans.add(f);
+ spans.add(g);
+ spans.add(root);
+ Trace trace2 = Trace.extractTrace(spans);
+
+ assertFalse(trace1.executionPathHash() == trace2.executionPathHash());
+ }
+
+ /** Create a span with bogus timing events. */
+ public static Span createFullSpan(Long id, Long parentID, String messageName) {
+ Span out = new Span();
+ out.spanID = Util.idValue(id);
+ if (parentID != null) {
+ out.parentSpanID = Util.idValue(parentID);
+ }
+ out.messageName = new Utf8(messageName);
+
+ out.events = new GenericData.Array<TimestampedEvent>(
+ 4, Schema.createArray(TimestampedEvent.SCHEMA$));
+
+ for (SpanEvent ev: SpanEvent.values()) {
+ TimestampedEvent newEvent = new TimestampedEvent();
+ newEvent.timeStamp = System.currentTimeMillis() * 1000000;
+ newEvent.event = ev;
+ out.events.add(newEvent);
+ }
+
+ out.complete = true;
+
+ return out;
+ }
+
+ /**
+ * Describe this trace with two different orderings and make sure
+ * they equate to being equal.
+ *
+ * b
+ * /
+ * a -b g-i
+ * \ /
+ * d-e-f
+ * \
+ * g-i
+ */
+
+ @Test
+ public void testSpanEquality3() {
+
+ Span a = createFullSpan((long) 1, null, "a");
+ Span b1 = createFullSpan((long) 2, (long) 1, "b");
+ Span b2 = createFullSpan((long) 3, (long) 1, "b");
+ Span d = createFullSpan((long) 4, (long) 1, "d");
+ Span e = createFullSpan((long) 5, (long) 4, "e");
+ Span f = createFullSpan((long) 6, (long) 5, "f");
+ Span g1 = createFullSpan((long) 7, (long) 6, "g");
+ Span g2 = createFullSpan((long) 8, (long) 6, "g");
+ Span i1 = createFullSpan((long) 9, (long) 7, "i");
+ Span i2 = createFullSpan((long) 10, (long) 8, "i");
+
+ List<Span> spans = new LinkedList<Span>();
+ spans.addAll(Arrays.asList(new Span[] {a, b1, b2, d, e, f, g1, g2, i1, i2}));
+ Trace trace1 = Trace.extractTrace(spans);
+
+ // Re-order and make sure still equivalent
+ spans.clear();
+ spans.addAll(Arrays.asList(new Span[] {i2, b1, g1, e, f, d, b2, g2, i1, a}));
+ Trace trace2 = Trace.extractTrace(spans);
+ assertNotNull(trace1);
+ assertNotNull(trace2);
+ assertEquals(trace1.executionPathHash(), trace2.executionPathHash());
+ assertEquals(trace1.executionPathHash(), trace2.executionPathHash());
+
+ // Remove a span and make sure not equivalent
+ spans.clear();
+ spans.addAll(Arrays.asList(new Span[] {i2, b1, g1, e, f, d, b2, g2, a}));
+ Trace trace3 = Trace.extractTrace(spans);
+ assertNotNull(trace3);
+ assertTrue(trace1.executionPathHash() == trace2.executionPathHash());
+ assertTrue(trace1.executionPathHash() != trace3.executionPathHash());
+ assertTrue(trace2.executionPathHash() != trace3.executionPathHash());
+ }
+
+ @Test
+ public void testBasicTraceFormation() {
+ Span root = new Span();
+ root.spanID = Util.idValue(10);
+ root.parentSpanID = null;
+ root.messageName = new Utf8("startCall");
+
+ Span a = new Span();
+ a.spanID = Util.idValue(11);
+ a.parentSpanID = Util.idValue(10);
+ a.messageName = new Utf8("childCall1");
+
+ Span b = new Span();
+ b.spanID = Util.idValue(12);
+ b.parentSpanID = Util.idValue(10);
+ b.messageName = new Utf8("childCall2");
+
+ Span c = new Span();
+ c.spanID = Util.idValue(13);
+ c.parentSpanID = Util.idValue(10);
+ c.messageName = new Utf8("childCall3");
+
+ List<Span> spans = new LinkedList<Span>();
+ spans.add(root);
+ spans.add(a);
+ spans.add(b);
+ spans.add(c);
+ Trace trace = Trace.extractTrace(spans);
+
+ assertNotNull(trace);
+
+ TraceNode rootNode = trace.getRoot();
+ assertEquals(rootNode.span.messageName, new Utf8("startCall"));
+ assertEquals(3, rootNode.children.size());
+ boolean found1, found2, found3;
+ found1 = found2 = found3 = false;
+
+ for (TraceNode tn: rootNode.children) {
+ if (tn.span.messageName.equals(new Utf8("childCall1"))) {
+ found1 = true;
+ }
+ if (tn.span.messageName.equals(new Utf8("childCall2"))) {
+ found2 = true;
+ }
+ if (tn.span.messageName.equals(new Utf8("childCall3"))) {
+ found3 = true;
+ }
+ assertNotNull(tn.children);
+ assertEquals(0, tn.children.size());
+ }
+ assertTrue(found1);
+ assertTrue(found2);
+ assertTrue(found3);
+ }
+ }
Added: avro/trunk/share/schemas/org/apache/avro/ipc/trace/avroTrace.avdl
URL: http://svn.apache.org/viewvc/avro/trunk/share/schemas/org/apache/avro/ipc/trace/avroTrace.avdl?rev=982434&view=auto
==============================================================================
--- avro/trunk/share/schemas/org/apache/avro/ipc/trace/avroTrace.avdl (added)
+++ avro/trunk/share/schemas/org/apache/avro/ipc/trace/avroTrace.avdl Thu Aug 5 00:07:24 2010
@@ -0,0 +1,37 @@
+/**
+ * A Span is our basic unit of tracing. It tracks the critical points
+ * of a single RPC call and records other call meta-data. It also
+ * allows arbitrary string annotations. Both the client and server create
+ * Span objects, each of which is populated with half of the relevant event
+ * data. They share a span ID, which allows us to merge them into one complete
+ * span later on.
+ */
+@namespace("org.apache.avro.ipc.trace")
+
+protocol AvroTrace {
+ enum SpanEvent { SERVER_RECV, SERVER_SEND, CLIENT_RECV, CLIENT_SEND }
+
+ fixed ID(8);
+
+ record TimestampedEvent {
+ long timeStamp; // Unix time, in nanoseconds
+ union { SpanEvent, string} event;
+ }
+
+ record Span {
+ ID traceID; // ID shared by all Spans in a given trace
+ ID spanID; // Random ID for this Span
+ union { ID, null } parentSpanID; // Parent Span ID (null if root Span)
+ string messageName; // Function call represented
+ long requestPayloadSize; // Size (bytes) of the request
+ long responsePayloadSize; // Size (byts) of the response
+ union { string, null} requestorHostname; // Hostname of requestor
+// int requestorPort; // Port of the requestor (currently unused)
+ union { string, null } responderHostname; // Hostname of the responder
+// int responderPort; // Port of the responder (currently unused)
+ array<TimestampedEvent> events; // List of critical events
+ boolean complete; // Whether includes data from both sides
+ }
+
+ array<Span> getAllSpans();
+}
Added: avro/trunk/share/schemas/org/apache/avro/ipc/trace/avroTrace.avpr
URL: http://svn.apache.org/viewvc/avro/trunk/share/schemas/org/apache/avro/ipc/trace/avroTrace.avpr?rev=982434&view=auto
==============================================================================
--- avro/trunk/share/schemas/org/apache/avro/ipc/trace/avroTrace.avpr (added)
+++ avro/trunk/share/schemas/org/apache/avro/ipc/trace/avroTrace.avpr Thu Aug 5 00:07:24 2010
@@ -0,0 +1,69 @@
+{
+ "protocol" : "AvroTrace",
+ "namespace" : "org.apache.avro.ipc.trace",
+ "types" : [ {
+ "type" : "enum",
+ "name" : "SpanEvent",
+ "symbols" : [ "SERVER_RECV", "SERVER_SEND", "CLIENT_RECV", "CLIENT_SEND" ]
+ }, {
+ "type" : "fixed",
+ "name" : "ID",
+ "size" : 8
+ }, {
+ "type" : "record",
+ "name" : "TimestampedEvent",
+ "fields" : [ {
+ "name" : "timeStamp",
+ "type" : "long"
+ }, {
+ "name" : "event",
+ "type" : [ "SpanEvent", "string" ]
+ } ]
+ }, {
+ "type" : "record",
+ "name" : "Span",
+ "fields" : [ {
+ "name" : "traceID",
+ "type" : "ID"
+ }, {
+ "name" : "spanID",
+ "type" : "ID"
+ }, {
+ "name" : "parentSpanID",
+ "type" : [ "ID", "null" ]
+ }, {
+ "name" : "messageName",
+ "type" : "string"
+ }, {
+ "name" : "requestPayloadSize",
+ "type" : "long"
+ }, {
+ "name" : "responsePayloadSize",
+ "type" : "long"
+ }, {
+ "name" : "requestorHostname",
+ "type" : [ "string", "null" ]
+ }, {
+ "name" : "responderHostname",
+ "type" : [ "string", "null" ]
+ }, {
+ "name" : "events",
+ "type" : {
+ "type" : "array",
+ "items" : "TimestampedEvent"
+ }
+ }, {
+ "name" : "complete",
+ "type" : "boolean"
+ } ]
+ } ],
+ "messages" : {
+ "getAllSpans" : {
+ "request" : [ ],
+ "response" : {
+ "type" : "array",
+ "items" : "Span"
+ }
+ }
+ }
+}
\ No newline at end of file