From f5f67f7fc395826eea366131a8783fd66d521045 Mon Sep 17 00:00:00 2001 From: Savorboard Date: Fri, 16 Jul 2021 17:18:38 +0800 Subject: [PATCH 1/5] Add opentelemetry project --- CAP.sln | 9 ++++- .../CapDiagnosticListener.cs | 35 +++++++++++++++++++ .../DotNetCore.CAP.OpenTelemetry.csproj | 24 +++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/DotNetCore.CAP.OpenTelemetry/CapDiagnosticListener.cs create mode 100644 src/DotNetCore.CAP.OpenTelemetry/DotNetCore.CAP.OpenTelemetry.csproj diff --git a/CAP.sln b/CAP.sln index 8695f7c..39c0b1d 100644 --- a/CAP.sln +++ b/CAP.sln @@ -76,7 +76,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.RedisStreams EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Dashboard.Auth", "samples\Sample.Dashboard.Auth\Sample.Dashboard.Auth.csproj", "{6E059983-DE89-4D53-88F5-D9083BCE257F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetCore.CAP.MultiModuleSubscriberTests", "test\DotNetCore.CAP.MultiModuleSubscriberTests\DotNetCore.CAP.MultiModuleSubscriberTests.csproj", "{23684403-7DA8-489A-8A1E-8056D7683E18}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.MultiModuleSubscriberTests", "test\DotNetCore.CAP.MultiModuleSubscriberTests\DotNetCore.CAP.MultiModuleSubscriberTests.csproj", "{23684403-7DA8-489A-8A1E-8056D7683E18}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.OpenTelemetry", "src\DotNetCore.CAP.OpenTelemetry\DotNetCore.CAP.OpenTelemetry.csproj", "{D32FBDA5-41AC-4563-8CBA-F40C2C10E864}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -184,6 +186,10 @@ Global {23684403-7DA8-489A-8A1E-8056D7683E18}.Debug|Any CPU.Build.0 = Debug|Any CPU {23684403-7DA8-489A-8A1E-8056D7683E18}.Release|Any CPU.ActiveCfg = Release|Any CPU {23684403-7DA8-489A-8A1E-8056D7683E18}.Release|Any CPU.Build.0 = Release|Any CPU + {D32FBDA5-41AC-4563-8CBA-F40C2C10E864}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D32FBDA5-41AC-4563-8CBA-F40C2C10E864}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D32FBDA5-41AC-4563-8CBA-F40C2C10E864}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D32FBDA5-41AC-4563-8CBA-F40C2C10E864}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -214,6 +220,7 @@ Global {54458B54-49CC-454C-82B2-4AED681D9D07} = {9B2AE124-6636-4DE9-83A3-70360DABD0C4} {6E059983-DE89-4D53-88F5-D9083BCE257F} = {3A6B6931-A123-477A-9469-8B468B5385AF} {23684403-7DA8-489A-8A1E-8056D7683E18} = {C09CDAB0-6DD4-46E9-B7F3-3EF2A4741EA0} + {D32FBDA5-41AC-4563-8CBA-F40C2C10E864} = {9B2AE124-6636-4DE9-83A3-70360DABD0C4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {2E70565D-94CF-40B4-BFE1-AC18D5F736AB} diff --git a/src/DotNetCore.CAP.OpenTelemetry/CapDiagnosticListener.cs b/src/DotNetCore.CAP.OpenTelemetry/CapDiagnosticListener.cs new file mode 100644 index 0000000..583daf4 --- /dev/null +++ b/src/DotNetCore.CAP.OpenTelemetry/CapDiagnosticListener.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Diagnostics.Tracing; +using OpenTelemetry.Instrumentation; +using System.Diagnostics; +using System.Reflection; + +namespace DotNetCore.CAP.OpenTelemetry +{ + public class CapDiagnosticListener : EventSource + { + internal static readonly ActivitySource ActivitySource = new ActivitySource("", ""); + + public CapDiagnosticListener() + { + // var count = new System.Diagnostics.Tracing.DiagnosticCounter(); + + } + + } + + internal sealed partial class HttpTelemetry : EventSource + { + public static readonly HttpTelemetry Log = new HttpTelemetry(); + + + [Event(1, Level = EventLevel.Informational)] + private void RequestStart(string scheme, string host, int port, string pathAndQuery, byte versionMajor, byte versionMinor, HttpVersionPolicy versionPolicy) + { + Interlocked.Increment(ref _startedRequests); + WriteEvent(eventId: 1, scheme, host, port, pathAndQuery, versionMajor, versionMinor, versionPolicy); + } + } +} diff --git a/src/DotNetCore.CAP.OpenTelemetry/DotNetCore.CAP.OpenTelemetry.csproj b/src/DotNetCore.CAP.OpenTelemetry/DotNetCore.CAP.OpenTelemetry.csproj new file mode 100644 index 0000000..ef1c4d4 --- /dev/null +++ b/src/DotNetCore.CAP.OpenTelemetry/DotNetCore.CAP.OpenTelemetry.csproj @@ -0,0 +1,24 @@ + + + + netstandard2.1 + DotNetCore.CAP.OpenTelemetry + CAP instrumentation for OpenTelemetry .NET + $(PackageTags);distributed-tracing + + + + bin\$(Configuration)\netstandard2.1\DotNetCore.CAP.OpenTelemetry.xml + 1701;1702;1705;CS1591 + + + + + + + + + + + + From 99ca050bf0d33b6a246b23bbdf720fc6c1882ae5 Mon Sep 17 00:00:00 2001 From: Savorboard Date: Fri, 31 Dec 2021 18:18:03 +0800 Subject: [PATCH 2/5] Add OpenTelemerty Impl --- .../CAP.OpenTelemetryCapOptionsExtension.cs | 30 +++ .../DiagnosticObserver.cs | 246 ++++++++++++++++++ .../DiagnosticProcessorObserver.cs | 30 +++ .../IProcessingServer.DiagnosticRegister.cs | 34 +++ 4 files changed, 340 insertions(+) create mode 100644 src/DotNetCore.CAP.OpenTelemetry/CAP.OpenTelemetryCapOptionsExtension.cs create mode 100644 src/DotNetCore.CAP.OpenTelemetry/DiagnosticObserver.cs create mode 100644 src/DotNetCore.CAP.OpenTelemetry/DiagnosticProcessorObserver.cs create mode 100644 src/DotNetCore.CAP.OpenTelemetry/IProcessingServer.DiagnosticRegister.cs diff --git a/src/DotNetCore.CAP.OpenTelemetry/CAP.OpenTelemetryCapOptionsExtension.cs b/src/DotNetCore.CAP.OpenTelemetry/CAP.OpenTelemetryCapOptionsExtension.cs new file mode 100644 index 0000000..ca11e3d --- /dev/null +++ b/src/DotNetCore.CAP.OpenTelemetry/CAP.OpenTelemetryCapOptionsExtension.cs @@ -0,0 +1,30 @@ +// Copyright (c) .NET Core Community. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +using DotNetCore.CAP.Internal; +using DotNetCore.CAP.OpenTelemetry; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +// ReSharper disable once CheckNamespace +namespace DotNetCore.CAP +{ + internal class OpenTelemetryCapOptionsExtension : ICapOptionsExtension + { + public void AddServices(IServiceCollection services) + { + services.AddSingleton(); + services.TryAddEnumerable(ServiceDescriptor.Singleton()); + } + } + + public static class CapOptionsExtensions + { + public static CapOptions UseOpenTelemetry(this CapOptions options) + { + options.RegisterExtension(new OpenTelemetryCapOptionsExtension()); + + return options; + } + } +} \ No newline at end of file diff --git a/src/DotNetCore.CAP.OpenTelemetry/DiagnosticObserver.cs b/src/DotNetCore.CAP.OpenTelemetry/DiagnosticObserver.cs new file mode 100644 index 0000000..a115e14 --- /dev/null +++ b/src/DotNetCore.CAP.OpenTelemetry/DiagnosticObserver.cs @@ -0,0 +1,246 @@ +// Copyright (c) .NET Core Community. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using DotNetCore.CAP.Diagnostics; +using DotNetCore.CAP.Messages; +using OpenTelemetry; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Trace; +using CapEvents = DotNetCore.CAP.Diagnostics.CapDiagnosticListenerNames; +using Status = OpenTelemetry.Trace.Status; + +namespace DotNetCore.CAP.OpenTelemetry +{ + internal class CapDiagnosticObserver : IObserver> + { + private static readonly ActivitySource ActivitySource = new("DotNetCore.CAP.OpenTelemetry"); + private static readonly TextMapPropagator Propagator = new TraceContextPropagator(); + + private readonly ConcurrentDictionary _contexts = new(); + + private const string OperateNamePrefix = "CAP/"; + private const string ProducerOperateNameSuffix = "/Publisher"; + private const string ConsumerOperateNameSuffix = "/Subscriber"; + + public void OnCompleted() + { + } + + public void OnError(Exception error) + { + } + + public void OnNext(KeyValuePair evt) + { + switch (evt.Key) + { + case CapEvents.BeforePublishMessageStore: + { + var eventData = (CapEventDataPubStore)evt.Value!; + var activity = ActivitySource.StartActivity("Event Persistence: " + eventData.Operation); + if (activity != null) + { + activity.SetTag("component", "CAP"); + activity.SetTag("message.name", eventData.Operation); + activity.AddEvent(new ActivityEvent("CAP message persistence start...", + DateTimeOffset.FromUnixTimeMilliseconds(eventData.OperationTimestamp!.Value))); + _contexts.TryAdd(eventData.Message.GetId(), activity); + } + } + break; + case CapEvents.AfterPublishMessageStore: + { + var eventData = (CapEventDataPubStore)evt.Value!; + if (_contexts.TryRemove(eventData.Message.GetId(), out Activity activity)) + { + activity.AddEvent(new ActivityEvent("CAP message persistence succeeded!", + DateTimeOffset.FromUnixTimeMilliseconds(eventData.OperationTimestamp!.Value), + new ActivityTagsCollection { new("cap.persistence.duration", eventData.ElapsedTimeMs) }) + ); + activity.Dispose(); + } + } + break; + case CapEvents.ErrorPublishMessageStore: + { + var eventData = (CapEventDataPubStore)evt.Value!; + if (_contexts.TryRemove(eventData.Message.GetId(), out Activity activity)) + { + var exception = eventData.Exception!; + + activity.SetStatus(Status.Error.WithDescription(exception.Message)); + + activity.RecordException(exception); + + activity.Dispose(); + } + } + break; + case CapEvents.BeforePublish: + { + var eventData = (CapEventDataPubSend)evt.Value!; + var activity = ActivitySource.StartActivity(OperateNamePrefix + eventData.Operation + ProducerOperateNameSuffix, ActivityKind.Producer); + if (activity != null) + { + activity.SetTag("messaging.system", eventData.BrokerAddress.Name); + activity.SetTag("messaging.destination", eventData.Operation); + activity.SetTag("messaging.destination_kind", "topic"); + activity.SetTag("messaging.url", eventData.BrokerAddress.Endpoint!.Replace("-1", "5672")); + activity.SetTag("messaging.message_id", eventData.TransportMessage.GetId()); + activity.SetTag("messaging.message_payload_size_bytes", eventData.TransportMessage.Body?.Length); + + activity.AddEvent(new ActivityEvent("Message publishing start...", + DateTimeOffset.FromUnixTimeMilliseconds(eventData.OperationTimestamp!.Value))); + + Propagator.Inject(new PropagationContext(activity.Context, Baggage.Current), eventData.TransportMessage, + (msg, key, value) => + { + msg.Headers[key] = value; + }); + + _contexts.TryAdd(eventData.TransportMessage.GetId(), activity); + } + } + break; + case CapEvents.AfterPublish: + { + var eventData = (CapEventDataPubSend)evt.Value!; + if (_contexts.TryRemove(eventData.TransportMessage.GetId(), out Activity activity)) + { + activity.AddEvent(new ActivityEvent("Message publishing succeeded!", + DateTimeOffset.FromUnixTimeMilliseconds(eventData.OperationTimestamp!.Value), + new ActivityTagsCollection { new("cap.send.duration", eventData.ElapsedTimeMs) }) + ); + activity.Dispose(); + } + } + break; + case CapEvents.ErrorPublish: + { + var eventData = (CapEventDataPubSend)evt.Value!; + if (_contexts.TryRemove(eventData.TransportMessage.GetId(), out Activity activity)) + { + var exception = eventData.Exception!; + activity.SetStatus(Status.Error.WithDescription(exception.Message)); + + activity.RecordException(exception); + + activity.Dispose(); + } + } + break; + case CapEvents.BeforeConsume: + { + + var eventData = (CapEventDataSubStore)evt.Value!; + var activity = ActivitySource.StartActivity(OperateNamePrefix + eventData.Operation + ConsumerOperateNameSuffix, ActivityKind.Consumer); + if (activity != null) + { + var parentContext = Propagator.Extract(default, eventData.TransportMessage, (msg, key) => + { + if (msg.Headers.TryGetValue(key, out string? value)) + { + return new[] { value }; + } + return Enumerable.Empty(); + }); + + Baggage.Current = parentContext.Baggage; + + activity.SetTag("messaging.system", eventData.BrokerAddress.Name); + activity.SetTag("messaging.destination", eventData.Operation); + activity.SetTag("messaging.destination_kind", "topic"); + activity.SetTag("messaging.url", eventData.BrokerAddress.Endpoint!.Replace("-1", "5672")); + activity.SetTag("messaging.message_id", eventData.TransportMessage.GetId()); + activity.SetTag("messaging.message_payload_size_bytes", eventData.TransportMessage.Body?.Length); + + activity.AddEvent(new ActivityEvent("CAP message persistence start...", + DateTimeOffset.FromUnixTimeMilliseconds(eventData.OperationTimestamp!.Value))); + + _contexts.TryAdd(eventData.TransportMessage.GetId(), activity); + + } + } + break; + case CapEvents.AfterConsume: + { + var eventData = (CapEventDataSubStore)evt.Value!; + if (_contexts.TryRemove(eventData.TransportMessage.GetId(), out Activity activity)) + { + activity.AddEvent(new ActivityEvent("CAP message persistence succeeded!", + DateTimeOffset.FromUnixTimeMilliseconds(eventData.OperationTimestamp!.Value), + new ActivityTagsCollection { new("cap.receive.duration", eventData.ElapsedTimeMs) })); + + _contexts.TryAdd(eventData.TransportMessage.GetId(), activity); + } + } + break; + case CapEvents.ErrorConsume: + { + var eventData = (CapEventDataSubStore)evt.Value!; + if (_contexts.TryRemove(eventData.TransportMessage.GetId(), out Activity activity)) + { + var exception = eventData.Exception!; + activity.SetStatus(Status.Error.WithDescription(exception.Message)); + + activity.RecordException(exception); + + activity.Dispose(); + } + } + break; + case CapEvents.BeforeSubscriberInvoke: + { + var eventData = (CapEventDataSubExecute)evt.Value!; + var activity = ActivitySource.StartActivity("Subscriber Invoke: " + eventData.MethodInfo!.Name); + if (activity != null) + { + activity.SetTag("component", "CAP"); + activity.SetTag("messaging.operation", "process"); + activity.SetTag("code.function", eventData.MethodInfo.Name); + activity.SetTag("code.namespace", eventData.MethodInfo.GetType().Namespace); + + activity.AddEvent(new ActivityEvent("Begin invoke the subscriber:" + eventData.MethodInfo.Name, + DateTimeOffset.FromUnixTimeMilliseconds(eventData.OperationTimestamp!.Value))); + + _contexts.TryAdd(eventData.Message.GetId(), activity); + } + } + break; + case CapEvents.AfterSubscriberInvoke: + { + var eventData = (CapEventDataSubExecute)evt.Value!; + if (_contexts.TryRemove(eventData.Message.GetId(), out Activity activity)) + { + activity.AddEvent(new ActivityEvent("Subscriber invoke succeeded!", + DateTimeOffset.FromUnixTimeMilliseconds(eventData.OperationTimestamp!.Value), + new ActivityTagsCollection { new("cap.invoke.duration", eventData.ElapsedTimeMs) })); + + activity.Dispose(); + } + + } + break; + case CapEvents.ErrorSubscriberInvoke: + { + var eventData = (CapEventDataSubExecute)evt.Value!; + if (_contexts.TryRemove(eventData.Message.GetId(), out Activity activity)) + { + var exception = eventData.Exception!; + activity.SetStatus(Status.Error.WithDescription(exception.Message)); + activity.RecordException(exception); + activity.Dispose(); + } + } + break; + + } + } + + } +} \ No newline at end of file diff --git a/src/DotNetCore.CAP.OpenTelemetry/DiagnosticProcessorObserver.cs b/src/DotNetCore.CAP.OpenTelemetry/DiagnosticProcessorObserver.cs new file mode 100644 index 0000000..aa72367 --- /dev/null +++ b/src/DotNetCore.CAP.OpenTelemetry/DiagnosticProcessorObserver.cs @@ -0,0 +1,30 @@ +// Copyright (c) .NET Core Community. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +using System; +using System.Diagnostics; +using DotNetCore.CAP.Diagnostics; + +namespace DotNetCore.CAP.OpenTelemetry +{ + public class CapDiagnosticProcessorObserver : IObserver + { + public const string DiagnosticListenerName = CapDiagnosticListenerNames.DiagnosticListenerName; + + public void OnCompleted() + { + } + + public void OnError(Exception error) + { + } + + public void OnNext(DiagnosticListener listener) + { + if (listener.Name == DiagnosticListenerName) + { + listener.Subscribe(new CapDiagnosticObserver()); + } + } + } +} \ No newline at end of file diff --git a/src/DotNetCore.CAP.OpenTelemetry/IProcessingServer.DiagnosticRegister.cs b/src/DotNetCore.CAP.OpenTelemetry/IProcessingServer.DiagnosticRegister.cs new file mode 100644 index 0000000..35af64f --- /dev/null +++ b/src/DotNetCore.CAP.OpenTelemetry/IProcessingServer.DiagnosticRegister.cs @@ -0,0 +1,34 @@ +// Copyright (c) .NET Core Community. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +using System.Diagnostics; +using System.Threading; +using DotNetCore.CAP.Internal; + +namespace DotNetCore.CAP.OpenTelemetry +{ + public class OpenTelemetryDiagnosticRegister : IProcessingServer + { + private readonly CapDiagnosticProcessorObserver _diagnosticProcessorObserver; + + public OpenTelemetryDiagnosticRegister(CapDiagnosticProcessorObserver diagnosticProcessorObserver) + { + _diagnosticProcessorObserver = diagnosticProcessorObserver; + } + + public void Dispose() + { + + } + + public void Pulse() + { + + } + + public void Start(CancellationToken stoppingToken) + { + DiagnosticListener.AllListeners.Subscribe(_diagnosticProcessorObserver); + } + } +} From a3e1d274bf55e4a84c249cd739cc92e8126031f9 Mon Sep 17 00:00:00 2001 From: Savorboard Date: Fri, 31 Dec 2021 18:18:24 +0800 Subject: [PATCH 3/5] Add OpenTelemerty Impl --- .../CapDiagnosticListener.cs | 35 ------------------- .../DotNetCore.CAP.OpenTelemetry.csproj | 15 +++----- 2 files changed, 5 insertions(+), 45 deletions(-) delete mode 100644 src/DotNetCore.CAP.OpenTelemetry/CapDiagnosticListener.cs diff --git a/src/DotNetCore.CAP.OpenTelemetry/CapDiagnosticListener.cs b/src/DotNetCore.CAP.OpenTelemetry/CapDiagnosticListener.cs deleted file mode 100644 index 583daf4..0000000 --- a/src/DotNetCore.CAP.OpenTelemetry/CapDiagnosticListener.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Diagnostics.Tracing; -using OpenTelemetry.Instrumentation; -using System.Diagnostics; -using System.Reflection; - -namespace DotNetCore.CAP.OpenTelemetry -{ - public class CapDiagnosticListener : EventSource - { - internal static readonly ActivitySource ActivitySource = new ActivitySource("", ""); - - public CapDiagnosticListener() - { - // var count = new System.Diagnostics.Tracing.DiagnosticCounter(); - - } - - } - - internal sealed partial class HttpTelemetry : EventSource - { - public static readonly HttpTelemetry Log = new HttpTelemetry(); - - - [Event(1, Level = EventLevel.Informational)] - private void RequestStart(string scheme, string host, int port, string pathAndQuery, byte versionMajor, byte versionMinor, HttpVersionPolicy versionPolicy) - { - Interlocked.Increment(ref _startedRequests); - WriteEvent(eventId: 1, scheme, host, port, pathAndQuery, versionMajor, versionMinor, versionPolicy); - } - } -} diff --git a/src/DotNetCore.CAP.OpenTelemetry/DotNetCore.CAP.OpenTelemetry.csproj b/src/DotNetCore.CAP.OpenTelemetry/DotNetCore.CAP.OpenTelemetry.csproj index ef1c4d4..4592514 100644 --- a/src/DotNetCore.CAP.OpenTelemetry/DotNetCore.CAP.OpenTelemetry.csproj +++ b/src/DotNetCore.CAP.OpenTelemetry/DotNetCore.CAP.OpenTelemetry.csproj @@ -2,20 +2,15 @@ netstandard2.1 - DotNetCore.CAP.OpenTelemetry + enable CAP instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing - - - bin\$(Configuration)\netstandard2.1\DotNetCore.CAP.OpenTelemetry.xml - 1701;1702;1705;CS1591 - - + - - - + + + From acd5865ce07cfc4e4eaa02d638bfcc7e6f600e1e Mon Sep 17 00:00:00 2001 From: Savorboard Date: Tue, 4 Jan 2022 14:28:05 +0800 Subject: [PATCH 4/5] Add open telemetry support. --- CAP.sln | 7 ++ ...sExtension.cs => CAP.Options.Extension.cs} | 25 ++++ .../DiagnosticObserver.cs | 112 +++++++++--------- .../DiagnosticProcessorObserver.cs | 12 +- 4 files changed, 98 insertions(+), 58 deletions(-) rename src/DotNetCore.CAP.OpenTelemetry/{CAP.OpenTelemetryCapOptionsExtension.cs => CAP.Options.Extension.cs} (52%) diff --git a/CAP.sln b/CAP.sln index 8f4620b..db7190d 100644 --- a/CAP.sln +++ b/CAP.sln @@ -84,6 +84,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Pulsar.InMemory", "s EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.RabbitMQ.SqlServer.DispatcherPerGroup", "samples\Sample.RabbitMQ.SqlServer.DispatcherPerGroup\Sample.RabbitMQ.SqlServer.DispatcherPerGroup.csproj", "{DCDF58E8-F823-4F04-9F8C-E8076DC16A68}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.OpenTelemetry", "src\DotNetCore.CAP.OpenTelemetry\DotNetCore.CAP.OpenTelemetry.csproj", "{83DDB126-A00B-4064-86E7-568322CA67EC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -202,6 +204,10 @@ Global {DCDF58E8-F823-4F04-9F8C-E8076DC16A68}.Debug|Any CPU.Build.0 = Debug|Any CPU {DCDF58E8-F823-4F04-9F8C-E8076DC16A68}.Release|Any CPU.ActiveCfg = Release|Any CPU {DCDF58E8-F823-4F04-9F8C-E8076DC16A68}.Release|Any CPU.Build.0 = Release|Any CPU + {83DDB126-A00B-4064-86E7-568322CA67EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {83DDB126-A00B-4064-86E7-568322CA67EC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {83DDB126-A00B-4064-86E7-568322CA67EC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {83DDB126-A00B-4064-86E7-568322CA67EC}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -235,6 +241,7 @@ Global {AB7A10CB-2C7E-49CE-AA21-893772FF6546} = {9B2AE124-6636-4DE9-83A3-70360DABD0C4} {B1D95CCD-0123-41D4-8CCB-9F834ED8D5C5} = {3A6B6931-A123-477A-9469-8B468B5385AF} {DCDF58E8-F823-4F04-9F8C-E8076DC16A68} = {3A6B6931-A123-477A-9469-8B468B5385AF} + {83DDB126-A00B-4064-86E7-568322CA67EC} = {9B2AE124-6636-4DE9-83A3-70360DABD0C4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {2E70565D-94CF-40B4-BFE1-AC18D5F736AB} diff --git a/src/DotNetCore.CAP.OpenTelemetry/CAP.OpenTelemetryCapOptionsExtension.cs b/src/DotNetCore.CAP.OpenTelemetry/CAP.Options.Extension.cs similarity index 52% rename from src/DotNetCore.CAP.OpenTelemetry/CAP.OpenTelemetryCapOptionsExtension.cs rename to src/DotNetCore.CAP.OpenTelemetry/CAP.Options.Extension.cs index ca11e3d..69e939f 100644 --- a/src/DotNetCore.CAP.OpenTelemetry/CAP.OpenTelemetryCapOptionsExtension.cs +++ b/src/DotNetCore.CAP.OpenTelemetry/CAP.Options.Extension.cs @@ -1,10 +1,13 @@ // Copyright (c) .NET Core Community. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. +using System; using DotNetCore.CAP.Internal; using DotNetCore.CAP.OpenTelemetry; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; // ReSharper disable once CheckNamespace namespace DotNetCore.CAP @@ -13,6 +16,7 @@ namespace DotNetCore.CAP { public void AddServices(IServiceCollection services) { + services.AddSingleton(); services.AddSingleton(); services.TryAddEnumerable(ServiceDescriptor.Singleton()); } @@ -27,4 +31,25 @@ namespace DotNetCore.CAP return options; } } + + public static class TracerProviderBuilderExtensions + { + /// + /// Enables the message eventing data collection for CAP. + /// + /// being configured. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddCapInstrumentation(this TracerProviderBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + builder.AddSource("DotNetCore.CAP.OpenTelemetry") + .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("CAP")); + + return builder; + } + } } \ No newline at end of file diff --git a/src/DotNetCore.CAP.OpenTelemetry/DiagnosticObserver.cs b/src/DotNetCore.CAP.OpenTelemetry/DiagnosticObserver.cs index a115e14..0a63df6 100644 --- a/src/DotNetCore.CAP.OpenTelemetry/DiagnosticObserver.cs +++ b/src/DotNetCore.CAP.OpenTelemetry/DiagnosticObserver.cs @@ -12,16 +12,15 @@ using OpenTelemetry; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Trace; using CapEvents = DotNetCore.CAP.Diagnostics.CapDiagnosticListenerNames; -using Status = OpenTelemetry.Trace.Status; namespace DotNetCore.CAP.OpenTelemetry { - internal class CapDiagnosticObserver : IObserver> + public class CapDiagnosticObserver : IObserver> { - private static readonly ActivitySource ActivitySource = new("DotNetCore.CAP.OpenTelemetry"); + private static readonly ActivitySource ActivitySource = new("DotNetCore.CAP.OpenTelemetry", "1.0.0"); private static readonly TextMapPropagator Propagator = new TraceContextPropagator(); - private readonly ConcurrentDictionary _contexts = new(); + private readonly ConcurrentDictionary _contexts = new(); private const string OperateNamePrefix = "CAP/"; private const string ProducerOperateNameSuffix = "/Publisher"; @@ -42,49 +41,57 @@ namespace DotNetCore.CAP.OpenTelemetry case CapEvents.BeforePublishMessageStore: { var eventData = (CapEventDataPubStore)evt.Value!; + var useParent = false; + if (Activity.Current != null) + { + if (_contexts.TryAdd(eventData.Message.GetId(), Activity.Current.Context)) + { + useParent = true; + } + } var activity = ActivitySource.StartActivity("Event Persistence: " + eventData.Operation); if (activity != null) { - activity.SetTag("component", "CAP"); activity.SetTag("message.name", eventData.Operation); activity.AddEvent(new ActivityEvent("CAP message persistence start...", DateTimeOffset.FromUnixTimeMilliseconds(eventData.OperationTimestamp!.Value))); - _contexts.TryAdd(eventData.Message.GetId(), activity); + + if (!useParent) + { + _contexts[eventData.Message.GetId()] = Activity.Current!.Context; + } } } break; case CapEvents.AfterPublishMessageStore: { var eventData = (CapEventDataPubStore)evt.Value!; - if (_contexts.TryRemove(eventData.Message.GetId(), out Activity activity)) - { - activity.AddEvent(new ActivityEvent("CAP message persistence succeeded!", - DateTimeOffset.FromUnixTimeMilliseconds(eventData.OperationTimestamp!.Value), - new ActivityTagsCollection { new("cap.persistence.duration", eventData.ElapsedTimeMs) }) - ); - activity.Dispose(); - } + + Activity.Current?.AddEvent(new ActivityEvent("CAP message persistence succeeded!", + DateTimeOffset.FromUnixTimeMilliseconds(eventData.OperationTimestamp!.Value), + new ActivityTagsCollection { new("cap.persistence.duration", eventData.ElapsedTimeMs) }) + ); + + Activity.Current?.Stop(); } break; case CapEvents.ErrorPublishMessageStore: { var eventData = (CapEventDataPubStore)evt.Value!; - if (_contexts.TryRemove(eventData.Message.GetId(), out Activity activity)) + if (Activity.Current is { } activity) { var exception = eventData.Exception!; - activity.SetStatus(Status.Error.WithDescription(exception.Message)); - activity.RecordException(exception); - - activity.Dispose(); + activity.Stop(); } } break; case CapEvents.BeforePublish: { var eventData = (CapEventDataPubSend)evt.Value!; - var activity = ActivitySource.StartActivity(OperateNamePrefix + eventData.Operation + ProducerOperateNameSuffix, ActivityKind.Producer); + _contexts.TryRemove(eventData.TransportMessage.GetId(), out var context); + var activity = ActivitySource.StartActivity(OperateNamePrefix + eventData.Operation + ProducerOperateNameSuffix, ActivityKind.Producer, context); if (activity != null) { activity.SetTag("messaging.system", eventData.BrokerAddress.Name); @@ -102,56 +109,52 @@ namespace DotNetCore.CAP.OpenTelemetry { msg.Headers[key] = value; }); - - _contexts.TryAdd(eventData.TransportMessage.GetId(), activity); } } break; case CapEvents.AfterPublish: { var eventData = (CapEventDataPubSend)evt.Value!; - if (_contexts.TryRemove(eventData.TransportMessage.GetId(), out Activity activity)) + if (Activity.Current is { } activity) { activity.AddEvent(new ActivityEvent("Message publishing succeeded!", DateTimeOffset.FromUnixTimeMilliseconds(eventData.OperationTimestamp!.Value), new ActivityTagsCollection { new("cap.send.duration", eventData.ElapsedTimeMs) }) ); - activity.Dispose(); + activity.Stop(); } } break; case CapEvents.ErrorPublish: { var eventData = (CapEventDataPubSend)evt.Value!; - if (_contexts.TryRemove(eventData.TransportMessage.GetId(), out Activity activity)) + if (Activity.Current is { } activity) { var exception = eventData.Exception!; activity.SetStatus(Status.Error.WithDescription(exception.Message)); - activity.RecordException(exception); - - activity.Dispose(); + activity.Stop(); } } break; case CapEvents.BeforeConsume: { - var eventData = (CapEventDataSubStore)evt.Value!; - var activity = ActivitySource.StartActivity(OperateNamePrefix + eventData.Operation + ConsumerOperateNameSuffix, ActivityKind.Consumer); - if (activity != null) + var parentContext = Propagator.Extract(default, eventData.TransportMessage, (msg, key) => { - var parentContext = Propagator.Extract(default, eventData.TransportMessage, (msg, key) => + if (msg.Headers.TryGetValue(key, out string? value)) { - if (msg.Headers.TryGetValue(key, out string? value)) - { - return new[] { value }; - } - return Enumerable.Empty(); - }); + return new[] { value }; + } + return Enumerable.Empty(); + }); - Baggage.Current = parentContext.Baggage; + var activity = ActivitySource.StartActivity(OperateNamePrefix + eventData.Operation + ConsumerOperateNameSuffix, + ActivityKind.Consumer, + parentContext.ActivityContext); + if (activity != null) + { activity.SetTag("messaging.system", eventData.BrokerAddress.Name); activity.SetTag("messaging.destination", eventData.Operation); activity.SetTag("messaging.destination_kind", "topic"); @@ -162,66 +165,63 @@ namespace DotNetCore.CAP.OpenTelemetry activity.AddEvent(new ActivityEvent("CAP message persistence start...", DateTimeOffset.FromUnixTimeMilliseconds(eventData.OperationTimestamp!.Value))); - _contexts.TryAdd(eventData.TransportMessage.GetId(), activity); - + _contexts[eventData.TransportMessage.GetId() + eventData.TransportMessage.GetGroup()] = activity.Context; } } break; case CapEvents.AfterConsume: { var eventData = (CapEventDataSubStore)evt.Value!; - if (_contexts.TryRemove(eventData.TransportMessage.GetId(), out Activity activity)) + if (Activity.Current is { } activity) { activity.AddEvent(new ActivityEvent("CAP message persistence succeeded!", DateTimeOffset.FromUnixTimeMilliseconds(eventData.OperationTimestamp!.Value), new ActivityTagsCollection { new("cap.receive.duration", eventData.ElapsedTimeMs) })); - _contexts.TryAdd(eventData.TransportMessage.GetId(), activity); + activity.Stop(); } } break; case CapEvents.ErrorConsume: { var eventData = (CapEventDataSubStore)evt.Value!; - if (_contexts.TryRemove(eventData.TransportMessage.GetId(), out Activity activity)) + if (Activity.Current is { } activity) { var exception = eventData.Exception!; activity.SetStatus(Status.Error.WithDescription(exception.Message)); activity.RecordException(exception); - activity.Dispose(); + activity.Stop(); } } break; case CapEvents.BeforeSubscriberInvoke: { var eventData = (CapEventDataSubExecute)evt.Value!; - var activity = ActivitySource.StartActivity("Subscriber Invoke: " + eventData.MethodInfo!.Name); + _contexts.TryRemove(eventData.Message.GetId() + eventData.Message.GetGroup(), out var context); + var activity = ActivitySource.StartActivity("Subscriber Invoke: " + eventData.MethodInfo!.Name, ActivityKind.Internal, + context); if (activity != null) { - activity.SetTag("component", "CAP"); activity.SetTag("messaging.operation", "process"); activity.SetTag("code.function", eventData.MethodInfo.Name); - activity.SetTag("code.namespace", eventData.MethodInfo.GetType().Namespace); activity.AddEvent(new ActivityEvent("Begin invoke the subscriber:" + eventData.MethodInfo.Name, DateTimeOffset.FromUnixTimeMilliseconds(eventData.OperationTimestamp!.Value))); - - _contexts.TryAdd(eventData.Message.GetId(), activity); } } break; case CapEvents.AfterSubscriberInvoke: { var eventData = (CapEventDataSubExecute)evt.Value!; - if (_contexts.TryRemove(eventData.Message.GetId(), out Activity activity)) + if (Activity.Current is { } activity) { activity.AddEvent(new ActivityEvent("Subscriber invoke succeeded!", DateTimeOffset.FromUnixTimeMilliseconds(eventData.OperationTimestamp!.Value), new ActivityTagsCollection { new("cap.invoke.duration", eventData.ElapsedTimeMs) })); - - activity.Dispose(); + + activity.Stop(); } } @@ -229,18 +229,16 @@ namespace DotNetCore.CAP.OpenTelemetry case CapEvents.ErrorSubscriberInvoke: { var eventData = (CapEventDataSubExecute)evt.Value!; - if (_contexts.TryRemove(eventData.Message.GetId(), out Activity activity)) + if (Activity.Current is { } activity) { var exception = eventData.Exception!; activity.SetStatus(Status.Error.WithDescription(exception.Message)); activity.RecordException(exception); - activity.Dispose(); + activity.Stop(); } } break; - } } - } } \ No newline at end of file diff --git a/src/DotNetCore.CAP.OpenTelemetry/DiagnosticProcessorObserver.cs b/src/DotNetCore.CAP.OpenTelemetry/DiagnosticProcessorObserver.cs index aa72367..a98897c 100644 --- a/src/DotNetCore.CAP.OpenTelemetry/DiagnosticProcessorObserver.cs +++ b/src/DotNetCore.CAP.OpenTelemetry/DiagnosticProcessorObserver.cs @@ -4,13 +4,22 @@ using System; using System.Diagnostics; using DotNetCore.CAP.Diagnostics; +using Microsoft.Extensions.Logging; namespace DotNetCore.CAP.OpenTelemetry { public class CapDiagnosticProcessorObserver : IObserver { + private readonly ILogger _logger; + private readonly CapDiagnosticObserver _capObserver; public const string DiagnosticListenerName = CapDiagnosticListenerNames.DiagnosticListenerName; + public CapDiagnosticProcessorObserver(ILogger logger, CapDiagnosticObserver capObserver) + { + _logger = logger; + _capObserver = capObserver; + } + public void OnCompleted() { } @@ -23,7 +32,8 @@ namespace DotNetCore.CAP.OpenTelemetry { if (listener.Name == DiagnosticListenerName) { - listener.Subscribe(new CapDiagnosticObserver()); + listener.Subscribe(_capObserver); + _logger.LogInformation($"Loaded diagnostic listener [{DiagnosticListenerName}]."); } } } From 59bf063e4afd386ae7ebdfe3a6f73cf65e519022 Mon Sep 17 00:00:00 2001 From: Savorboard Date: Tue, 4 Jan 2022 15:21:29 +0800 Subject: [PATCH 5/5] Add docs for opentelemerty --- docs/content/img/opentelemetry.png | Bin 0 -> 92717 bytes .../user-guide/en/monitoring/opentelemetry.md | 42 ++++++++++++++++ .../user-guide/zh/monitoring/opentelemetry.md | 45 ++++++++++++++++++ docs/mkdocs.yml | 5 +- 4 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 docs/content/img/opentelemetry.png create mode 100644 docs/content/user-guide/en/monitoring/opentelemetry.md create mode 100644 docs/content/user-guide/zh/monitoring/opentelemetry.md diff --git a/docs/content/img/opentelemetry.png b/docs/content/img/opentelemetry.png new file mode 100644 index 0000000000000000000000000000000000000000..87fd0aefb94c9e1aac791a75179ba175afaac474 GIT binary patch literal 92717 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 UGQ?eT=d*gZjBX;YJ3aY709YX`k^lez literal 0 HcmV?d00001 diff --git a/docs/content/user-guide/en/monitoring/opentelemetry.md b/docs/content/user-guide/en/monitoring/opentelemetry.md new file mode 100644 index 0000000..b4be2d2 --- /dev/null +++ b/docs/content/user-guide/en/monitoring/opentelemetry.md @@ -0,0 +1,42 @@ +# OpenTelemetry + +https://opentelemetry.io/ + +OpenTelemetry is a collection of tools, APIs, and SDKs. Use it to instrument, generate, collect, and export telemetry data (metrics, logs, and traces) to help you analyze your software’s performance and behavior. + +## Integration + +You can find it [here](https://opentelemetry.io/docs/instrumentation/net/getting-started/) about how to use OpenTelemetry in console applications or ASP.NET Core, at here we mainly describe how to tracing CAP data to OpenTelemetry. + +### Configuration + +Install the CAP OpenTelemetry package into the project. + +```C# +dotnet add package DotNetCore.Cap.OpenTelemetry +``` + +The OpenTelemetry data comes from [diagnostics](diagnostics.md), add the configuration to enable data collection. + +```C# +services.AddCap(x => +{ + //*** + x.UseOpenTelemetry(); // <-- Add this line +}); + +``` + +Add the instrumentation of CAP to the configuration of OpenTelemetry. + +```C# +services.AddOpenTelemetryTracing((builder) => builder + .AddAspNetCoreInstrumentation() + .AddCapInstrumentation() // <-- Add this line + .AddZipkinExporter() +); +``` + +Here is a diagram of CAP's tracking data in Zipkin: + + \ No newline at end of file diff --git a/docs/content/user-guide/zh/monitoring/opentelemetry.md b/docs/content/user-guide/zh/monitoring/opentelemetry.md new file mode 100644 index 0000000..da3b3e7 --- /dev/null +++ b/docs/content/user-guide/zh/monitoring/opentelemetry.md @@ -0,0 +1,45 @@ +# OpenTelemetry + +https://opentelemetry.io/ + +OpenTelemetry是工具、api和sdk的集合。 使用它来检测、生成、收集和导出遥测数据(度量、日志和跟踪),以帮助您分析软件的性能和行为。 + +## 集成 + +You can find it [here](https://opentelemetry.io/docs/instrumentation/net/getting-started/) about how to use OpenTelemetry in console applications or ASP.NET Core, at here we mainly describe how to tracing CAP data to OpenTelemetry. + +你可以在[这里](https://opentelemetry.io/docs/instrumentation/net/getting-started/)找到关于如何在控制台应用或ASP.NET Core 中使用OpenTelemetry。 +在这里我们主要描述如何将CAP集成到OpenTelemetry中。 + +### 配置 + +安装CAP的OpenTelemetry包到项目中。 + +```C# +dotnet add package DotNetCore.Cap.OpenTelemetry +``` + +OpenTelemetry 的跟踪数据来自于[Diagnostics](diagnostics.md)发送的诊断数据,使用下面的配置行来启用收集数据。 + +```C# +services.AddCap(x => +{ + //*** + x.UseOpenTelemetry(); // <-- Add this line +}); + +``` + +添加 CAP Instrumentation 到 OpenTelemetry的扩展配置中。 + +```C# +services.AddOpenTelemetryTracing((builder) => builder + .AddAspNetCoreInstrumentation() + .AddCapInstrumentation() // <-- Add this line + .AddZipkinExporter() +); +``` + +以下是CAP的跟踪数据在 Zipkin 中的一个示意图: + + \ No newline at end of file diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 8dd3daf..52aee2a 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -113,6 +113,7 @@ nav: - Consul: user-guide/en/monitoring/consul.md - Dashboard: user-guide/en/monitoring/dashboard.md - Diagnostics: user-guide/en/monitoring/diagnostics.md + - OpenTelemetry: user-guide/en/monitoring/opentelemetry.md - Samples: - Github: user-guide/en/samples/github.md - eShopOnContainers: user-guide/en/samples/eshoponcontainers.md @@ -149,8 +150,8 @@ nav: - 监控: - Consul: user-guide/zh/monitoring/consul.md - Dashboard: user-guide/zh/monitoring/dashboard.md - - 性能追踪: user-guide/zh/monitoring/diagnostics.md - - 健康检查: user-guide/zh/monitoring/health-checks.md + - Diagnostics: user-guide/zh/monitoring/diagnostics.md + - OpenTelemetry: user-guide/zh/monitoring/opentelemetry.md - 示例: - Castle DynamicProxy: user-guide/zh/samples/castle.dynamicproxy.md - Github: user-guide/zh/samples/github.md