diff --git a/Src/zipkin4net/Src/Annotation/ConsumerStart.cs b/Src/zipkin4net/Src/Annotation/ConsumerStart.cs
new file mode 100644
index 0000000..374f636
--- /dev/null
+++ b/Src/zipkin4net/Src/Annotation/ConsumerStart.cs
@@ -0,0 +1,18 @@
+namespace zipkin4net.Annotation
+{
+ public sealed class ConsumerStart : IAnnotation
+ {
+ internal ConsumerStart()
+ {}
+
+ public override string ToString()
+ {
+ return GetType().Name;
+ }
+
+ public void Accept(IAnnotationVisitor visitor)
+ {
+ visitor.Visit(this);
+ }
+ }
+}
diff --git a/Src/zipkin4net/Src/Annotation/ConsumerStop.cs b/Src/zipkin4net/Src/Annotation/ConsumerStop.cs
new file mode 100644
index 0000000..eeec17f
--- /dev/null
+++ b/Src/zipkin4net/Src/Annotation/ConsumerStop.cs
@@ -0,0 +1,18 @@
+namespace zipkin4net.Annotation
+{
+ public sealed class ConsumerStop : IAnnotation
+ {
+ internal ConsumerStop()
+ {}
+
+ public override string ToString()
+ {
+ return GetType().Name;
+ }
+
+ public void Accept(IAnnotationVisitor visitor)
+ {
+ visitor.Visit(this);
+ }
+ }
+}
diff --git a/Src/zipkin4net/Src/Annotation/IAnnotationVisitor.cs b/Src/zipkin4net/Src/Annotation/IAnnotationVisitor.cs
index 9090cf1..4de91a6 100644
--- a/Src/zipkin4net/Src/Annotation/IAnnotationVisitor.cs
+++ b/Src/zipkin4net/Src/Annotation/IAnnotationVisitor.cs
@@ -8,6 +8,11 @@ public interface IAnnotationVisitor
void Visit(ServerSend serverSend);
void Visit(WireSend wireSend);
void Visit(WireRecv wireRecv);
+ void Visit(ProducerStart producerStart);
+ void Visit(ProducerStop producerStop);
+ void Visit(ConsumerStart consumerStart);
+ void Visit(ConsumerStop consumerStop);
+ void Visit(MessageAddr messageAddr);
void Visit(Rpc rpc);
void Visit(ServiceName serviceName);
void Visit(LocalAddr localAddr);
diff --git a/Src/zipkin4net/Src/Annotation/MessageAddr.cs b/Src/zipkin4net/Src/Annotation/MessageAddr.cs
new file mode 100644
index 0000000..3c48a81
--- /dev/null
+++ b/Src/zipkin4net/Src/Annotation/MessageAddr.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Net;
+
+namespace zipkin4net.Annotation
+{
+ public sealed class MessageAddr : IAnnotation
+ {
+ public string ServiceName { get; }
+ public IPEndPoint Endpoint { get; }
+
+ internal MessageAddr(string serviceName, IPEndPoint endpoint)
+ {
+ ServiceName = serviceName;
+ Endpoint = endpoint;
+ }
+
+ public override string ToString()
+ {
+ return string.Format("{0}: {1}/{2}", GetType().Name, ServiceName, Endpoint);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj.GetType() != GetType()) return false;
+ var messageAddr = (MessageAddr)obj;
+ return Endpoint.Equals(messageAddr.Endpoint)
+ && string.Equals(ServiceName, messageAddr.ServiceName, StringComparison.OrdinalIgnoreCase);
+ }
+
+ public override int GetHashCode()
+ {
+ var hashCode = -2129424941;
+ hashCode = hashCode * -1521134295 + ServiceName.GetHashCode();
+ hashCode = hashCode * -1521134295 + Endpoint.GetHashCode();
+ return hashCode;
+ }
+
+ public void Accept(IAnnotationVisitor visitor)
+ {
+ visitor.Visit(this);
+ }
+ }
+}
diff --git a/Src/zipkin4net/Src/Annotation/ProducerStart.cs b/Src/zipkin4net/Src/Annotation/ProducerStart.cs
new file mode 100644
index 0000000..36e62a2
--- /dev/null
+++ b/Src/zipkin4net/Src/Annotation/ProducerStart.cs
@@ -0,0 +1,18 @@
+namespace zipkin4net.Annotation
+{
+ public sealed class ProducerStart : IAnnotation
+ {
+ internal ProducerStart()
+ {}
+
+ public override string ToString()
+ {
+ return GetType().Name;
+ }
+
+ public void Accept(IAnnotationVisitor visitor)
+ {
+ visitor.Visit(this);
+ }
+ }
+}
diff --git a/Src/zipkin4net/Src/Annotation/ProducerStop.cs b/Src/zipkin4net/Src/Annotation/ProducerStop.cs
new file mode 100644
index 0000000..34fcf42
--- /dev/null
+++ b/Src/zipkin4net/Src/Annotation/ProducerStop.cs
@@ -0,0 +1,18 @@
+namespace zipkin4net.Annotation
+{
+ public sealed class ProducerStop : IAnnotation
+ {
+ internal ProducerStop()
+ {}
+
+ public override string ToString()
+ {
+ return GetType().Name;
+ }
+
+ public void Accept(IAnnotationVisitor visitor)
+ {
+ visitor.Visit(this);
+ }
+ }
+}
diff --git a/Src/zipkin4net/Src/Annotations.cs b/Src/zipkin4net/Src/Annotations.cs
index 27d3e54..8f2c323 100644
--- a/Src/zipkin4net/Src/Annotations.cs
+++ b/Src/zipkin4net/Src/Annotations.cs
@@ -15,6 +15,10 @@ public static class Annotations
private static readonly IAnnotation AnnServerSend = new ServerSend();
private static readonly IAnnotation AnnWireSend = new WireSend();
private static readonly IAnnotation AnnWireRecv = new WireRecv();
+ private static readonly IAnnotation AnnProducerStart = new ProducerStart();
+ private static readonly IAnnotation AnnProducerStop = new ProducerStop();
+ private static readonly IAnnotation AnnConsumerStart = new ConsumerStart();
+ private static readonly IAnnotation AnnConsumerStop = new ConsumerStop();
private static readonly IAnnotation AnnLocalOperationStop = new LocalOperationStop();
public static IAnnotation ClientRecv()
@@ -47,6 +51,31 @@ public static IAnnotation WireRecv()
return AnnWireRecv;
}
+ public static IAnnotation ProducerStart()
+ {
+ return AnnProducerStart;
+ }
+
+ public static IAnnotation ProducerStop()
+ {
+ return AnnProducerStop;
+ }
+
+ public static IAnnotation ConsumerStart()
+ {
+ return AnnConsumerStart;
+ }
+
+ public static IAnnotation ConsumerStop()
+ {
+ return AnnConsumerStop;
+ }
+
+ public static IAnnotation MessageAddr(string serviceName, IPEndPoint endPoint)
+ {
+ return new MessageAddr(serviceName, endPoint);
+ }
+
public static IAnnotation LocalOperationStart(string name)
{
return new LocalOperationStart(name);
diff --git a/Src/zipkin4net/Src/Tracers/Zipkin/ZipkinAnnotationVisitor.cs b/Src/zipkin4net/Src/Tracers/Zipkin/ZipkinAnnotationVisitor.cs
index 20460b1..09dd851 100644
--- a/Src/zipkin4net/Src/Tracers/Zipkin/ZipkinAnnotationVisitor.cs
+++ b/Src/zipkin4net/Src/Tracers/Zipkin/ZipkinAnnotationVisitor.cs
@@ -49,6 +49,31 @@ public void Visit(WireRecv wireRecv)
AddTimestampedAnnotation(zipkinCoreConstants.WIRE_RECV);
}
+ public void Visit(ProducerStart producerStart)
+ {
+ AddTimestampedAnnotation(zipkinCoreConstants.MESSAGE_SEND);
+ }
+
+ public void Visit(ProducerStop producerStop)
+ {
+ _span.SetAsComplete(_record.Timestamp);
+ }
+
+ public void Visit(ConsumerStart consumerStart)
+ {
+ AddTimestampedAnnotation(zipkinCoreConstants.MESSAGE_RECV);
+ }
+
+ public void Visit(ConsumerStop consumerStop)
+ {
+ _span.SetAsComplete(_record.Timestamp);
+ }
+
+ public void Visit(MessageAddr messageAddr)
+ {
+ AddBinaryAnnotation(zipkinCoreConstants.MESSAGE_ADDR, true, messageAddr.ServiceName, messageAddr.Endpoint);
+ }
+
public void Visit(Event ev)
{
AddTimestampedAnnotation(ev.EventName);
diff --git a/Src/zipkin4net/Src/zipkin4net.csproj b/Src/zipkin4net/Src/zipkin4net.csproj
index e5778f5..0a7609c 100644
--- a/Src/zipkin4net/Src/zipkin4net.csproj
+++ b/Src/zipkin4net/Src/zipkin4net.csproj
@@ -1,4 +1,4 @@
-
+
@@ -53,6 +53,11 @@
+
+
+
+
+
@@ -136,4 +141,4 @@
-->
-
\ No newline at end of file
+
diff --git a/Src/zipkin4net/Tests/T_Annotations.cs b/Src/zipkin4net/Tests/T_Annotations.cs
index 208ba34..789b77c 100644
--- a/Src/zipkin4net/Tests/T_Annotations.cs
+++ b/Src/zipkin4net/Tests/T_Annotations.cs
@@ -21,6 +21,11 @@ public void FactoryReturnsCorrectTypes()
Assert.IsInstanceOf(Annotations.Event(""));
Assert.IsInstanceOf(Annotations.ClientAddr(null));
Assert.IsInstanceOf(Annotations.ServerAddr(null, null));
+ Assert.IsInstanceOf(Annotations.MessageAddr(null, null));
+ Assert.IsInstanceOf(Annotations.ConsumerStart());
+ Assert.IsInstanceOf(Annotations.ConsumerStop());
+ Assert.IsInstanceOf(Annotations.ProducerStart());
+ Assert.IsInstanceOf(Annotations.ProducerStop());
}
}
diff --git a/Src/zipkin4net/Tests/Tracers/Zipkin/T_Span.cs b/Src/zipkin4net/Tests/Tracers/Zipkin/T_Span.cs
index c4c547a..5ae809d 100644
--- a/Src/zipkin4net/Tests/Tracers/Zipkin/T_Span.cs
+++ b/Src/zipkin4net/Tests/Tracers/Zipkin/T_Span.cs
@@ -17,6 +17,8 @@ public void DurationAndSpanStartedSetWhenSetAsComplete()
VerifySpanDurationComputedWhenSetAsComplete(Annotations.ServerRecv(), Annotations.ServerSend(), isRootSpan: true, isSpanStartedAndDurationSet: true);
VerifySpanDurationComputedWhenSetAsComplete(Annotations.ServerRecv(), Annotations.ServerSend(), isRootSpan: false, isSpanStartedAndDurationSet: false);
VerifySpanDurationComputedWhenSetAsComplete(Annotations.LocalOperationStart("Operation"), Annotations.LocalOperationStop(), isRootSpan: false, isSpanStartedAndDurationSet: true);
+ VerifySpanDurationComputedWhenSetAsComplete(Annotations.ProducerStart(), Annotations.ProducerStop(), isRootSpan: false, isSpanStartedAndDurationSet: false);
+ VerifySpanDurationComputedWhenSetAsComplete(Annotations.ConsumerStart(), Annotations.ConsumerStop(), isRootSpan: false, isSpanStartedAndDurationSet: false);
}
private static void VerifySpanDurationComputedWhenSetAsComplete(IAnnotation start, IAnnotation stop, bool isRootSpan, bool isSpanStartedAndDurationSet)
@@ -122,6 +124,10 @@ public void SpanDoesntHaveDurationIfIncomplete()
Assert.False(GetSpanDuration(offset, Annotations.ClientSend()).HasValue);
Assert.False(GetSpanDuration(offset, Annotations.LocalOperationStart("Operation")).HasValue);
Assert.False(GetSpanDuration(offset, Annotations.LocalOperationStop()).HasValue);
+ Assert.False(GetSpanDuration(offset, Annotations.ConsumerStart()).HasValue);
+ Assert.False(GetSpanDuration(offset, Annotations.ConsumerStop()).HasValue);
+ Assert.False(GetSpanDuration(offset, Annotations.ProducerStart()).HasValue);
+ Assert.False(GetSpanDuration(offset, Annotations.ProducerStop()).HasValue);
}
diff --git a/Src/zipkin4net/Tests/Tracers/Zipkin/T_ZipkinAnnotationVisitor.cs b/Src/zipkin4net/Tests/Tracers/Zipkin/T_ZipkinAnnotationVisitor.cs
index bca0790..c0c02c5 100644
--- a/Src/zipkin4net/Tests/Tracers/Zipkin/T_ZipkinAnnotationVisitor.cs
+++ b/Src/zipkin4net/Tests/Tracers/Zipkin/T_ZipkinAnnotationVisitor.cs
@@ -118,6 +118,9 @@ public void SimpleAnnotationsCorrectlyAdded()
AnnotationCorrectlyAdded(Annotations.WireRecv(), zipkinCoreConstants.WIRE_RECV, false, false);
AnnotationCorrectlyAdded(Annotations.WireSend(), zipkinCoreConstants.WIRE_SEND, false, false);
AnnotationCorrectlyAdded(Annotations.LocalOperationStart("Operation"), zipkinCoreConstants.LOCAL_COMPONENT, true, false);
+ AnnotationCorrectlyAdded(Annotations.ConsumerStart(), zipkinCoreConstants.MESSAGE_RECV, false, false);
+ AnnotationCorrectlyAdded(Annotations.ProducerStart(), zipkinCoreConstants.MESSAGE_SEND, false, false);
+ AnnotationCorrectlyAdded(Annotations.MessageAddr("service", new IPEndPoint(0, 1)), zipkinCoreConstants.MESSAGE_ADDR, true, false);
}
private static void AnnotationCorrectlyAdded(IAnnotation ann, string expectedValue, bool isBinaryAnnotation, bool spanCompleted)