diff --git a/src/OpenTracing.Contrib.NetCore/AspNetCore/AspNetCoreDiagnostics.cs b/src/OpenTracing.Contrib.NetCore/AspNetCore/AspNetCoreDiagnostics.cs index 9048f36..34325e3 100644 --- a/src/OpenTracing.Contrib.NetCore/AspNetCore/AspNetCoreDiagnostics.cs +++ b/src/OpenTracing.Contrib.NetCore/AspNetCore/AspNetCoreDiagnostics.cs @@ -22,8 +22,9 @@ internal sealed class AspNetCoreDiagnostics : DiagnosticListenerObserver protected override string GetListenerName() => DiagnosticListenerName; - public AspNetCoreDiagnostics(ILoggerFactory loggerFactory, ITracer tracer, IOptions options) - : base(loggerFactory, tracer) + public AspNetCoreDiagnostics(ILoggerFactory loggerFactory, ITracer tracer, + IOptions options, IOptions genericEventOptions) + : base(loggerFactory, tracer, genericEventOptions.Value) { if (options?.Value == null) throw new ArgumentNullException(nameof(options)); diff --git a/src/OpenTracing.Contrib.NetCore/CoreFx/GenericDiagnostics.cs b/src/OpenTracing.Contrib.NetCore/CoreFx/GenericDiagnostics.cs index f0b6049..b2fbde0 100644 --- a/src/OpenTracing.Contrib.NetCore/CoreFx/GenericDiagnostics.cs +++ b/src/OpenTracing.Contrib.NetCore/CoreFx/GenericDiagnostics.cs @@ -13,18 +13,26 @@ namespace OpenTracing.Contrib.NetCore.CoreFx internal sealed class GenericDiagnostics : DiagnosticObserver { private readonly GenericDiagnosticOptions _options; + private readonly GenericEventOptions _genericEventOptions; - public GenericDiagnostics(ILoggerFactory loggerFactory, ITracer tracer, IOptions options) + public GenericDiagnostics(ILoggerFactory loggerFactory, ITracer tracer, IOptions options, + IOptions genericEventOptions) : base(loggerFactory, tracer) { _options = options?.Value ?? throw new ArgumentNullException(nameof(options)); + _genericEventOptions = genericEventOptions.Value; } public override IDisposable SubscribeIfMatch(DiagnosticListener diagnosticListener) { + if (_genericEventOptions.IgnoreAll) + { + return null; + } + if (!_options.IgnoredListenerNames.Contains(diagnosticListener.Name)) { - return new GenericDiagnosticsSubscription(this, diagnosticListener); + return new GenericDiagnosticsSubscription(this, diagnosticListener, _genericEventOptions); } return null; @@ -40,14 +48,19 @@ private class GenericDiagnosticsSubscription : IObserver value) if (!IsEnabled(eventName)) return; - _genericEventProcessor.ProcessEvent(eventName, untypedArg); + _genericEventProcessor?.ProcessEvent(eventName, untypedArg); } catch (Exception ex) { diff --git a/src/OpenTracing.Contrib.NetCore/CoreFx/HttpHandlerDiagnostics.cs b/src/OpenTracing.Contrib.NetCore/CoreFx/HttpHandlerDiagnostics.cs index fab8215..86af255 100644 --- a/src/OpenTracing.Contrib.NetCore/CoreFx/HttpHandlerDiagnostics.cs +++ b/src/OpenTracing.Contrib.NetCore/CoreFx/HttpHandlerDiagnostics.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using OpenTracing.Contrib.NetCore.Configuration; using OpenTracing.Contrib.NetCore.Internal; using OpenTracing.Propagation; using OpenTracing.Tag; @@ -31,8 +32,9 @@ internal sealed class HttpHandlerDiagnostics : DiagnosticListenerObserver protected override string GetListenerName() => DiagnosticListenerName; - public HttpHandlerDiagnostics(ILoggerFactory loggerFactory, ITracer tracer, IOptions options) - : base(loggerFactory, tracer) + public HttpHandlerDiagnostics(ILoggerFactory loggerFactory, ITracer tracer, + IOptions options, IOptions genericEventOptions) + : base(loggerFactory, tracer, genericEventOptions.Value) { _options = options?.Value ?? throw new ArgumentNullException(nameof(options)); } diff --git a/src/OpenTracing.Contrib.NetCore/EntityFrameworkCore/EntityFrameworkCoreDiagnostics.cs b/src/OpenTracing.Contrib.NetCore/EntityFrameworkCore/EntityFrameworkCoreDiagnostics.cs index 32df144..94c1ef4 100644 --- a/src/OpenTracing.Contrib.NetCore/EntityFrameworkCore/EntityFrameworkCoreDiagnostics.cs +++ b/src/OpenTracing.Contrib.NetCore/EntityFrameworkCore/EntityFrameworkCoreDiagnostics.cs @@ -2,6 +2,7 @@ using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using OpenTracing.Contrib.NetCore.Configuration; using OpenTracing.Contrib.NetCore.Internal; using OpenTracing.Tag; @@ -19,8 +20,9 @@ internal sealed class EntityFrameworkCoreDiagnostics : DiagnosticListenerObserve protected override string GetListenerName() => DiagnosticListenerName; - public EntityFrameworkCoreDiagnostics(ILoggerFactory loggerFactory, ITracer tracer, IOptions options) - : base(loggerFactory, tracer) + public EntityFrameworkCoreDiagnostics(ILoggerFactory loggerFactory, ITracer tracer, + IOptions options, IOptions genericEventOptions) + : base(loggerFactory, tracer, genericEventOptions.Value) { _options = options?.Value ?? throw new ArgumentNullException(nameof(options)); } diff --git a/src/OpenTracing.Contrib.NetCore/Internal/DiagnosticListenerObserver.cs b/src/OpenTracing.Contrib.NetCore/Internal/DiagnosticListenerObserver.cs index 979884c..9522eff 100644 --- a/src/OpenTracing.Contrib.NetCore/Internal/DiagnosticListenerObserver.cs +++ b/src/OpenTracing.Contrib.NetCore/Internal/DiagnosticListenerObserver.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Diagnostics; using Microsoft.Extensions.Logging; +using OpenTracing.Contrib.NetCore.Configuration; namespace OpenTracing.Contrib.NetCore.Internal { @@ -15,10 +16,13 @@ internal abstract class DiagnosticListenerObserver : DiagnosticObserver, IObserv /// protected abstract string GetListenerName(); - protected DiagnosticListenerObserver(ILoggerFactory loggerFactory, ITracer tracer) + protected DiagnosticListenerObserver(ILoggerFactory loggerFactory, ITracer tracer, GenericEventOptions options) : base(loggerFactory, tracer) { - _genericEventProcessor = new GenericEventProcessor(GetListenerName(), Tracer, Logger); + if (!options.IsIgnored(GetListenerName())) + { + _genericEventProcessor = new GenericEventProcessor(GetListenerName(), Tracer, Logger, options); + } } public override IDisposable SubscribeIfMatch(DiagnosticListener diagnosticListener) @@ -60,7 +64,7 @@ protected virtual bool IsEnabled(string eventName) protected void ProcessUnhandledEvent(string eventName, object untypedArg) { - _genericEventProcessor.ProcessEvent(eventName, untypedArg); + _genericEventProcessor?.ProcessEvent(eventName, untypedArg); } protected void DisposeActiveScope(bool isScopeRequired, Exception exception = null) diff --git a/src/OpenTracing.Contrib.NetCore/Internal/GenericEventOptions.cs b/src/OpenTracing.Contrib.NetCore/Internal/GenericEventOptions.cs new file mode 100644 index 0000000..49b370e --- /dev/null +++ b/src/OpenTracing.Contrib.NetCore/Internal/GenericEventOptions.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; + +namespace OpenTracing.Contrib.NetCore.Internal +{ + public class GenericEventOptions + { + private bool _hasFilter; + private bool _ignoreAll; + private Dictionary> _ignoredEvents; + private HashSet _ignoredListeners; + + /// + /// is ignore all events log + /// + public bool IgnoreAll + { + get => _ignoreAll; + set + { + _ignoreAll = value; + CheckHasFilter(); + } + } + + /// + /// listener names which will be ignored for logging + /// + public HashSet IgnoredListenerNames + { + get => _ignoredListeners; + set + { + _ignoredListeners = value; + CheckHasFilter(); + } + } + + /// + /// events which will be ignored for logging. Key is listener name, HashSet item is event name of the listener + /// + public Dictionary> IgnoredEvents + { + get => _ignoredEvents; + set + { + _ignoredEvents = value; + CheckHasFilter(); + } + } + + public void IgnoreListener(string listenerName) + { + if (listenerName == null) + throw new ArgumentNullException(nameof(listenerName)); + + if (IgnoredListenerNames == null) + IgnoredListenerNames = new HashSet(); + + IgnoredListenerNames.Add(listenerName); + _hasFilter = true; + } + + public void IgnoreEvent(string listenerName, string eventName) + { + if (listenerName == null) + throw new ArgumentNullException(nameof(listenerName)); + + if (eventName == null) + throw new ArgumentNullException(nameof(eventName)); + + if (IgnoredListenerNames == null) + IgnoredListenerNames = new HashSet(); + + if (!IgnoredEvents.TryGetValue(listenerName, out var ignoredListenerEvents)) + { + ignoredListenerEvents = new HashSet(); + IgnoredEvents.Add(listenerName, ignoredListenerEvents); + } + + ignoredListenerEvents.Add(eventName); + _hasFilter = true; + } + + /// + /// usually used in DiagnosticObserver + /// + /// + /// + public bool IsIgnored(string listenerName) + { + if (!_hasFilter) + return false; + + if (IgnoreAll) + return true; + + return IgnoredListenerNames.Count > 0 + && IgnoredListenerNames.Contains(listenerName); + } + + public bool IsIgnored(string listenerName, string eventName) + { + if (!_hasFilter) + return false; + + if (IgnoreAll) + return true; + + return IgnoredEvents.TryGetValue(listenerName, out var set) + && set.Contains(eventName); + } + + private void CheckHasFilter() + { + if (IgnoredListenerNames == null) + IgnoredListenerNames = new HashSet(); + + if (IgnoredEvents == null) + IgnoredEvents = new Dictionary>(); + + _hasFilter = IgnoreAll + || IgnoredListenerNames.Count > 0 + || IgnoredEvents.Count > 0; + } + } +} diff --git a/src/OpenTracing.Contrib.NetCore/Internal/GenericEventProcessor.cs b/src/OpenTracing.Contrib.NetCore/Internal/GenericEventProcessor.cs index 3c0b20f..52f3b1d 100644 --- a/src/OpenTracing.Contrib.NetCore/Internal/GenericEventProcessor.cs +++ b/src/OpenTracing.Contrib.NetCore/Internal/GenericEventProcessor.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Diagnostics; using Microsoft.Extensions.Logging; +using OpenTracing.Contrib.NetCore.Configuration; using OpenTracing.Tag; namespace OpenTracing.Contrib.NetCore.Internal @@ -12,12 +13,14 @@ internal class GenericEventProcessor private readonly ITracer _tracer; private readonly ILogger _logger; private readonly bool _isLogLevelTraceEnabled; + private readonly GenericEventOptions _options; - public GenericEventProcessor(string listenerName, ITracer tracer, ILogger logger) + public GenericEventProcessor(string listenerName, ITracer tracer, ILogger logger, GenericEventOptions options) { _listenerName = listenerName ?? throw new ArgumentNullException(nameof(listenerName)); _tracer = tracer ?? throw new ArgumentNullException(nameof(tracer)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _options = options; _isLogLevelTraceEnabled = _logger.IsEnabled(LogLevel.Trace); } @@ -26,6 +29,11 @@ public void ProcessEvent(string eventName, object untypedArg) { Activity activity = Activity.Current; + if (_options != null && _options.IsIgnored(_listenerName, eventName)) + { + return; + } + if (activity != null && eventName.EndsWith(".Start", StringComparison.Ordinal)) { HandleActivityStart(eventName, activity, untypedArg);