-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from osstotalsoft/feature/RDINC-847-OpenTracing
RDINC-847 Open Tracing draft version
- Loading branch information
Showing
15 changed files
with
404 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
src/Messaging/NBB.Messaging.OpenTracing/NBB.Messaging.OpenTracing.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netstandard2.0</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="OpenTracing" Version="$(OpenTracingPackageVersion)" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\Core\NBB.Core.Pipeline\NBB.Core.Pipeline.csproj" /> | ||
<ProjectReference Include="..\..\Correlation\NBB.Correlation\NBB.Correlation.csproj" /> | ||
<ProjectReference Include="..\NBB.Messaging.Abstractions\NBB.Messaging.Abstractions.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
66 changes: 66 additions & 0 deletions
66
src/Messaging/NBB.Messaging.OpenTracing/Publisher/OpenTracingPublisherDecorator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
using NBB.Core.Abstractions; | ||
using NBB.Correlation; | ||
using NBB.Messaging.Abstractions; | ||
using NBB.Messaging.DataContracts; | ||
using OpenTracing; | ||
using OpenTracing.Propagation; | ||
using OpenTracing.Tag; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
namespace NBB.Messaging.OpenTracing.Publisher | ||
{ | ||
public class OpenTracingPublisherDecorator : IMessageBusPublisher | ||
{ | ||
private readonly IMessageBusPublisher _inner; | ||
private readonly ITracer _tracer; | ||
|
||
public OpenTracingPublisherDecorator(IMessageBusPublisher inner, ITracer tracer) | ||
{ | ||
_inner = inner; | ||
_tracer = tracer; | ||
} | ||
|
||
public Task PublishAsync<T>(T message, CancellationToken cancellationToken, Action<MessagingEnvelope> customizer = null, string topicName = null) | ||
{ | ||
void NewCustomizer(MessagingEnvelope outgoingEnvelope) | ||
{ | ||
if (_tracer.ActiveSpan != null) | ||
{ | ||
_tracer.Inject(_tracer.ActiveSpan.Context, BuiltinFormats.TextMap, | ||
new TextMapInjectAdapter(outgoingEnvelope.Headers)); | ||
} | ||
|
||
customizer?.Invoke(outgoingEnvelope); | ||
} | ||
|
||
string operationName = $"Publisher {message.GetType().GetPrettyName()}"; | ||
using (var scope = _tracer.BuildSpan(operationName) | ||
.WithTag(Tags.Component, "NBB.Messaging.Publisher") | ||
.WithTag(Tags.SpanKind, Tags.SpanKindServer) | ||
.WithTag("correlationId", CorrelationManager.GetCorrelationId()?.ToString()) | ||
.StartActive(finishSpanOnDispose: true)) | ||
{ | ||
try | ||
{ | ||
return _inner.PublishAsync(message, cancellationToken, NewCustomizer); | ||
} | ||
catch (Exception exception) | ||
{ | ||
scope.Span.Log(new Dictionary<string, object>(3) | ||
{ | ||
{ LogFields.Event, Tags.Error.Key }, | ||
{ LogFields.ErrorKind, exception.GetType().Name }, | ||
{ LogFields.ErrorObject, exception } | ||
}); | ||
|
||
scope.Span.SetTag(Tags.Error, true); | ||
|
||
throw; | ||
} | ||
} | ||
} | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/Messaging/NBB.Messaging.OpenTracing/Subscriber/MessagingPipelineExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
using NBB.Core.Pipeline; | ||
using NBB.Messaging.DataContracts; | ||
|
||
namespace NBB.Messaging.OpenTracing.Subscriber | ||
{ | ||
public static class MessagingPipelineExtensions | ||
{ | ||
/// <summary> | ||
/// Adds to the pipeline a middleware that creates an OpenTracing span. | ||
/// </summary> | ||
/// <param name="pipelineBuilder">The pipeline builder.</param> | ||
/// <returns>The pipeline builder for further configuring the pipeline. It is used used in the fluent configuration API.</returns> | ||
public static IPipelineBuilder<MessagingEnvelope> UseOpenTracing( | ||
this IPipelineBuilder<MessagingEnvelope> pipelineBuilder) | ||
=> UseMiddleware<OpenTracingMiddleware>(pipelineBuilder); | ||
|
||
|
||
private static IPipelineBuilder<MessagingEnvelope> UseMiddleware<TMiddleware>(this IPipelineBuilder<MessagingEnvelope> pipelineBuilder) where TMiddleware : IPipelineMiddleware<MessagingEnvelope> | ||
=> pipelineBuilder.UseMiddleware<TMiddleware, MessagingEnvelope>(); | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
src/Messaging/NBB.Messaging.OpenTracing/Subscriber/OpenTracingMiddleware.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
using NBB.Core.Pipeline; | ||
using NBB.Messaging.DataContracts; | ||
using OpenTracing; | ||
using OpenTracing.Propagation; | ||
using OpenTracing.Tag; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using NBB.Core.Abstractions; | ||
using NBB.Correlation; | ||
using NBB.Messaging.Abstractions; | ||
|
||
namespace NBB.Messaging.OpenTracing.Subscriber | ||
{ | ||
public class OpenTracingMiddleware : IPipelineMiddleware<MessagingEnvelope> | ||
{ | ||
private readonly ITracer _tracer; | ||
|
||
public OpenTracingMiddleware(ITracer tracer) | ||
{ | ||
_tracer = tracer; | ||
} | ||
|
||
public async Task Invoke(MessagingEnvelope data, CancellationToken cancellationToken, Func<Task> next) | ||
{ | ||
var extractedSpanContext = _tracer.Extract(BuiltinFormats.TextMap, new TextMapExtractAdapter(data.Headers)); | ||
string operationName = $"Subscriber {data.Payload.GetType().GetPrettyName()}"; | ||
|
||
using(var scope = _tracer.BuildSpan(operationName) | ||
.AsChildOf(extractedSpanContext) | ||
.WithTag(Tags.Component, "NBB.Messaging.Subscriber") | ||
.WithTag(Tags.SpanKind, Tags.SpanKindServer) | ||
.WithTag("correlationId", CorrelationManager.GetCorrelationId()?.ToString()) | ||
.StartActive(finishSpanOnDispose: true)) { | ||
|
||
try | ||
{ | ||
await next(); | ||
} | ||
catch (Exception exception) | ||
{ | ||
scope.Span.Log(new Dictionary<string, object>(3) | ||
{ | ||
{ LogFields.Event, Tags.Error.Key }, | ||
{ LogFields.ErrorKind, exception.GetType().Name }, | ||
{ LogFields.ErrorObject, exception } | ||
}); | ||
|
||
scope.Span.SetTag(Tags.Error, true); | ||
|
||
throw; | ||
} | ||
} | ||
return; | ||
} | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
src/Tools/Serilog/NBB.Tools.Serilog.OpenTracingSink/Internal/OpenTracingContribFilter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Serilog.Events; | ||
|
||
namespace NBB.Tools.Serilog.OpenTracingSink.Internal | ||
{ | ||
internal static class OpenTracingContribFilter | ||
{ | ||
private static List<string> ExcludedLogSources = new List<string>() | ||
{ | ||
"Microsoft.EntityFrameworkCore", | ||
"Microsoft.AspNetCore.Hosting" | ||
}; | ||
|
||
|
||
public static bool ShouldExclude(LogEvent logEvent) | ||
{ | ||
const string sourceContextPropertyName = global::Serilog.Core.Constants.SourceContextPropertyName; | ||
|
||
if (!logEvent.Properties.TryGetValue(sourceContextPropertyName, out var source) || | ||
!(source is ScalarValue scalarSource) || | ||
!(scalarSource.Value is string stringValue)) | ||
{ | ||
return false; | ||
} | ||
|
||
return ExcludedLogSources.Any(x => stringValue.StartsWith(x)); | ||
} | ||
} | ||
} |
68 changes: 68 additions & 0 deletions
68
src/Tools/Serilog/NBB.Tools.Serilog.OpenTracingSink/Internal/OpenTracingSink.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
using OpenTracing; | ||
using OpenTracing.Util; | ||
using Serilog.Core; | ||
using Serilog.Events; | ||
using System; | ||
using System.Collections.Generic; | ||
|
||
namespace NBB.Tools.Serilog.OpenTracingSink.Internal | ||
{ | ||
internal class OpenTracingSink : ILogEventSink | ||
{ | ||
private readonly ITracer _tracer; | ||
private readonly Func<LogEvent, bool> _filter; | ||
|
||
public OpenTracingSink(Func<LogEvent, bool> filter = null) | ||
{ | ||
_tracer = GlobalTracer.Instance; | ||
_filter = filter ?? (logEvent => false); | ||
} | ||
|
||
public void Emit(LogEvent logEvent) | ||
{ | ||
ISpan span = _tracer.ActiveSpan; | ||
|
||
if (span == null) | ||
{ | ||
// Creating a new span for a log message seems brutal so we ignore messages if we can't attach it to an active span. | ||
return; | ||
} | ||
|
||
if (_tracer.IsNoopTracer()) | ||
{ | ||
return; | ||
} | ||
|
||
if (_filter(logEvent)) | ||
{ | ||
return; | ||
} | ||
|
||
var fields = new Dictionary<string, object>(); | ||
|
||
try | ||
{ | ||
fields[LogFields.Event] = "log"; | ||
fields[LogFields.Message] = logEvent.RenderMessage(); | ||
fields["level"] = logEvent.Level; | ||
|
||
if (logEvent.Exception != null) | ||
{ | ||
fields[LogFields.ErrorKind] = logEvent.Exception.GetType().FullName; | ||
fields[LogFields.ErrorObject] = logEvent.Exception; | ||
} | ||
|
||
foreach (var property in logEvent.Properties) | ||
{ | ||
fields[property.Key] = property.Value.ToString(); | ||
} | ||
} | ||
catch (Exception logException) | ||
{ | ||
fields["opentracing.contrib.netcore.error"] = logException.ToString(); | ||
} | ||
|
||
span.Log(fields); | ||
} | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
src/Tools/Serilog/NBB.Tools.Serilog.OpenTracingSink/Internal/TracerExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
using OpenTracing; | ||
using OpenTracing.Noop; | ||
using OpenTracing.Util; | ||
|
||
namespace NBB.Tools.Serilog.OpenTracingSink.Internal | ||
{ | ||
internal static class TracerExtensions | ||
{ | ||
public static bool IsNoopTracer(this ITracer tracer) | ||
{ | ||
if (tracer is NoopTracer) | ||
return true; | ||
|
||
if (tracer is GlobalTracer && !GlobalTracer.IsRegistered()) | ||
return true; | ||
|
||
return false; | ||
} | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
src/Tools/Serilog/NBB.Tools.Serilog.OpenTracingSink/NBB.Tools.Serilog.OpenTracingSink.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netstandard2.0</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="OpenTracing" Version="$(OpenTracingPackageVersion)" /> | ||
<PackageReference Include="Serilog" Version="$(SerilogPackageVersion)" /> | ||
</ItemGroup> | ||
</Project> |
28 changes: 28 additions & 0 deletions
28
src/Tools/Serilog/NBB.Tools.Serilog.OpenTracingSink/OpenTracingConfigurationExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
using NBB.Tools.Serilog.OpenTracingSink.Internal; | ||
using Serilog; | ||
using Serilog.Configuration; | ||
using Serilog.Core; | ||
using Serilog.Events; | ||
using System; | ||
|
||
namespace NBB.Tools.Serilog.OpenTracingSink | ||
{ | ||
public static class OpenTracingConfigurationExtensions | ||
{ | ||
public static LoggerConfiguration OpenTracing( | ||
this LoggerSinkConfiguration sinkConfiguration, | ||
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, | ||
LoggingLevelSwitch levelSwitch = null, | ||
bool exludeOpenTracingContribEvents = true | ||
) | ||
{ | ||
if (sinkConfiguration == null) throw new ArgumentNullException(nameof(sinkConfiguration)); | ||
|
||
var sink = exludeOpenTracingContribEvents ? | ||
new Internal.OpenTracingSink(OpenTracingContribFilter.ShouldExclude) : | ||
new Internal.OpenTracingSink(); | ||
|
||
return sinkConfiguration.Sink(sink, restrictedToMinimumLevel, levelSwitch); | ||
} | ||
} | ||
} |
Oops, something went wrong.