void UpdateActualFilter() { Debug.Assert(_enteredThreadId == Thread.CurrentThread.ManagedThreadId); LogFilter newLevel = _configuredFilter.Combine(_clientFilter); if (newLevel != _actualFilter) { _actualFilter = newLevel; _output.BridgeTarget.TargetActualFilterChanged(); } }
/// <summary> /// Challenges source filters based on FileName/LineNumber, <see cref="IActivityMonitor.ActualFilter">this monitor's actual filter</see> and application /// domain's <see cref="ActivityMonitor.DefaultFilter"/> filters to test whether a log group should actually be emitted. /// </summary> /// <param name="this">This <see cref="IActivityMonitor"/>.</param> /// <param name="level">Log level.</param> /// <param name="fileName">Source file name of the emitter (automatically injected by C# compiler but can be explicitly set).</param> /// <param name="lineNumber">Line number in the source file (automatically injected by C# compiler but can be explicitly set).</param> /// <returns>True if the log should be emitted.</returns> public static bool ShouldLogGroup(this IActivityMonitor @this, LogLevel level, [CallerFilePath] string fileName = null, [CallerLineNumber] int lineNumber = 0) { var h = ActivityMonitor.SourceFilter.FilterSource; int combined = h == null ? 0 : (int)h(ref fileName, ref lineNumber).GroupFilter; // Extract Override filter. int filter = (short)(combined >> 16); // If Override is undefined, combine the ActualFilter and Minimal source filter. if (filter <= 0) { filter = (int)LogFilter.Combine(@this.ActualFilter.Group, (LogLevelFilter)(combined & 0xFFFF)); } level &= LogLevel.Mask; return(filter <= 0 ? (int)ActivityMonitor.DefaultFilter.Group <= (int)level : filter <= (int)level); }
void IActivityMonitorImpl.OnClientMinimalFilterChanged(LogFilter oldLevel, LogFilter newLevel) { // Silently ignores stupid calls. if (oldLevel == newLevel) { return; } bool isNotReentrant = ConcurrentOnlyCheck(); try { Interlocked.MemoryBarrier(); bool dirty = _actualFilterIsDirty; do { _actualFilterIsDirty = false; // Optimization for some cases: if we can be sure that the oldLevel has no impact on the current // client filter, we can conclude without getting all the minimal filters. if (!dirty && ((oldLevel.Line == LogLevelFilter.None || oldLevel.Line > _clientFilter.Line) && (oldLevel.Group == LogLevelFilter.None || oldLevel.Group > _clientFilter.Group))) { // This Client had no impact on the current final client filter: if its new level has // no impact on the current client filter, there is nothing to do. var f = _clientFilter.Combine(newLevel); if (f == _clientFilter) { return; } _clientFilter = f; } else { // Whatever the new level is we have to update our client final filter. _clientFilter = DoGetBoundClientMinimalFilter(); } Interlocked.MemoryBarrier(); }while((dirty = _actualFilterIsDirty)); UpdateActualFilter(); } finally { if (isNotReentrant) { ReentrantAndConcurrentRelease(); } } }
LogFilter DoGetBoundClientMinimalFilter() { Debug.Assert(_enteredThreadId == Thread.CurrentThread.ManagedThreadId); LogFilter minimal = LogFilter.Undefined; List <IActivityMonitorClient> buggyClients = null; foreach (var l in _output.Clients) { IActivityMonitorBoundClient bound = l as IActivityMonitorBoundClient; if (bound != null) { try { minimal = minimal.Combine(bound.MinimalFilter); if (minimal == LogFilter.Debug) { break; } } catch (Exception exCall) { CriticalErrorCollector.Add(exCall, l.GetType().FullName); if (buggyClients == null) { buggyClients = new List <IActivityMonitorClient>(); } buggyClients.Add(l); } } } if (buggyClients != null) { foreach (var l in buggyClients) { _output.ForceRemoveBuggyClient(l); } } return(minimal); }
/// <summary> /// Combines this filter with another one. <see cref="Override"/> and <see cref="Minimal"/> level filters /// are combined with <see cref="LogFilter.Combine(LogFilter)"/>. /// </summary> /// <param name="other">The other filter to combine with this one.</param> /// <returns>The resulting filter.</returns> public SourceLogFilter Combine(SourceLogFilter other) { return(new SourceLogFilter(Override.Combine(other.Override), Minimal.Combine(other.Minimal))); }