/// <summary> /// Initializes a new instance of <see cref="CKMonWriterClient"/> that can be registered to write compressed or uncompressed .ckmon file for this monitor. /// </summary> /// <param name="path">The path. Can be absolute. When relative, it will be under <see cref="SystemActivityMonitor.RootLogPath"/> that must be set.</param> /// <param name="maxCountPerFile">Maximum number of entries per file. Must be greater than 1.</param> /// <param name="minimalFilter">Minimal filter for this client.</param> /// <param name="useGzipCompression">Whether to output compressed .ckmon files. Defaults to false (do not compress).</param> public CKMonWriterClient( string path, int maxCountPerFile, LogFilter minimalFilter, bool useGzipCompression = false ) { _path = path; _maxCountPerFile = maxCountPerFile; _minimalFilter = minimalFilter; _useGzipCompression = useGzipCompression; }
void IActivityMonitorBridgeCallback.OnTargetActualFilterChanged() { Interlocked.MemoryBarrier(); var s = _source; _targetActualFilter = LogFilter.Invalid; Interlocked.MemoryBarrier(); if( s != null ) s.SetClientMinimalFilterDirty(); }
internal StandardChannel( IGrandOutputSink commonSink, EventDispatcher dispatcher, IRouteConfigurationLock configLock, HandlerBase[] handlers, string configurationName, GrandOutputChannelConfigData configData ) { _dispatcher = dispatcher; _receiver = new EventDispatcher.FinalReceiver( commonSink, handlers, configLock ); _receiverNoCommonSink = new EventDispatcher.FinalReceiver( null, handlers, configLock ); _configurationName = configurationName; if( configData != null ) _minimalFilter = configData.MinimalFilter; }
/// <summary> /// Initializes a new <see cref="ActivityMonitorTextWriterClient"/> bound to a /// function that must write a string, with a filter. /// </summary> /// <param name="writer">Function that writes the content.</param> /// <param name="filter">Filter to apply</param> public ActivityMonitorTextWriterClient( Action<string> writer, LogFilter filter ) : base( filter ) { if( writer == null ) throw new ArgumentNullException( "writer" ); _writer = writer; _buffer = new StringBuilder(); _prefixLevel = _prefix = String.Empty; _currentTags = ActivityMonitor.Tags.Empty; }
/// <summary> /// Overridden to compare <see cref="Line"/> and <see cref="Group"/>. /// </summary> /// <param name="obj">Other object.</param> /// <returns>True if Line and Group are equal.</returns> public override bool Equals(object obj) { if (obj is LogFilter) { LogFilter x = (LogFilter)obj; return(x.Line == Line && x.Group == Group); } return(false); }
/// <summary> /// Matches a <see cref="LogFilter"/>: it can be a predefined filter as ("Undefined", "Debug", "Verbose", etc.) /// or as {GroupLogLevelFilter,LineLogLevelFilter} pairs like "{None,None}", "{Error,Trace}". /// </summary> /// <param name="m">This <see cref="StringMatcher"/>.</param> /// <param name="f">Resulting filter.</param> /// <returns>True on success, false on error.</returns> public static bool MatchLogFilter( this StringMatcher m, out LogFilter f ) { f = LogFilter.Undefined; if( !m.MatchText( "Undefined" ) ) { if( m.MatchText( "Debug" ) ) { f = LogFilter.Debug; } else if( m.MatchText( "Verbose" ) ) { f = LogFilter.Verbose; } else if( m.MatchText( "Monitor" ) ) { f = LogFilter.Monitor; } else if( m.MatchText( "Terse" ) ) { f = LogFilter.Terse; } else if( m.MatchText( "Release" ) ) { f = LogFilter.Release; } else if( m.MatchText( "Off" ) ) { f = LogFilter.Off; } else if( m.MatchText( "Invalid" ) ) { f = LogFilter.Invalid; } else { int savedIndex = m.StartIndex; if( !m.MatchChar( '{' ) ) return m.BackwardAddError( savedIndex ); LogLevelFilter group, line; m.MatchWhiteSpaces(); if( !m.MatchLogLevelFilter( out group ) ) return m.BackwardAddError( savedIndex ); m.MatchWhiteSpaces(); if( !m.MatchChar( ',' ) ) return m.BackwardAddError( savedIndex ); m.MatchWhiteSpaces(); if( !m.MatchLogLevelFilter( out line ) ) return m.BackwardAddError( savedIndex ); m.MatchWhiteSpaces(); if( !m.MatchChar( '}' ) ) return m.BackwardAddError( savedIndex ); f = new LogFilter( group, line ); } } return true; }
void UpdateActualFilter() { Debug.Assert(_enteredThreadId == Thread.CurrentThread.ManagedThreadId); LogFilter newLevel = _configuredFilter.Combine(_clientFilter); if (newLevel != _actualFilter) { _actualFilter = newLevel; _output.BridgeTarget.TargetActualFilterChanged(); } }
void DoResyncActualFilter() { do { Interlocked.MemoryBarrier(); _actualFilterIsDirty = false; _clientFilter = DoGetBoundClientMinimalFilter(); Interlocked.MemoryBarrier(); }while(_actualFilterIsDirty); UpdateActualFilter(); }
void IActivityMonitorBridgeCallback.OnTargetActualFilterChanged() { Interlocked.MemoryBarrier(); var s = _source; _targetActualFilter = LogFilter.Invalid; Interlocked.MemoryBarrier(); if (s != null) { s.SetClientMinimalFilterDirty(); } }
/// <summary> /// Initializes a new <see cref="ActivityMonitorTextWriterClient"/> bound to a /// function that must write a string, with a filter. /// </summary> /// <param name="writer">Function that writes the content.</param> /// <param name="filter">Filter to apply</param> public ActivityMonitorTextWriterClient(Action <string> writer, LogFilter filter) : base(filter) { if (writer == null) { throw new ArgumentNullException("writer"); } _writer = writer; _buffer = new StringBuilder(); _prefixLevel = _prefix = String.Empty; _currentTags = ActivityMonitor.Tags.Empty; }
/// <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); }
/// <summary> /// This is necessarily called in the context of the activity: we can call the bridge that can call /// the Monitor's ActualFilter that will be resynchronized if needed. /// </summary> LogFilter GetActualTargetFilter() { Interlocked.MemoryBarrier(); var f = _targetActualFilter; if (f == LogFilter.Invalid) { do { f = _bridgeTarget.TargetFinalFilter; _targetActualFilter = f; Interlocked.MemoryBarrier(); }while(_targetActualFilter == LogFilter.Invalid); } return(f); }
void DoUnfilteredLog(ActivityMonitorLogData data) { Debug.Assert(_enteredThreadId == Thread.CurrentThread.ManagedThreadId); Debug.Assert(data.Level != LogLevel.None); Debug.Assert(!String.IsNullOrEmpty(data.Text)); if (!data.IsFilteredLog) { if (_actualFilterIsDirty) { DoResyncActualFilter(); } if (_actualFilter.Line == LogLevelFilter.Off) { return; } } _lastLogTime = data.CombineTagsAndAdjustLogTime(_currentTag, _lastLogTime); List <IActivityMonitorClient> buggyClients = null; foreach (var l in _output.Clients) { try { l.OnUnfilteredLog(data); } 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); } _clientFilter = DoGetBoundClientMinimalFilter(); UpdateActualFilter(); } }
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> /// forceBuggyRemove is not used here since this client is not lockable. /// </summary> void IActivityMonitorBoundClient.SetMonitor( IActivityMonitorImpl source, bool forceBuggyRemove ) { if( source != null && _monitorSource != null ) throw ActivityMonitorClient.CreateMultipleRegisterOnBoundClientException( this ); // Silently ignore null => null or monitor => same monitor. if( source != _monitorSource ) { _currentMinimalFilter = LogFilter.Undefined; _prevLogType = LogEntryType.None; _prevlogTime = DateTimeStamp.Unknown; Debug.Assert( (source == null) != (_monitorSource == null) ); if( (_monitorSource = source) == null ) { // Releases the channel if any. _channel = null; } else { var g = _monitorSource.CurrentGroup; _currentGroupDepth = g != null ? g.Depth : 0; Interlocked.Increment( ref _version ); } } }
public void Initialize() { ChannelOption option = new ChannelOption( _minimalFilter ); foreach( var s in _receiver.Handlers ) s.CollectChannelOption( option ); _minimalFilter = option.CurrentMinimalFilter; }
void DoCloseGroup(DateTimeStamp logTime, object userConclusion = null) { Debug.Assert(_enteredThreadId == Thread.CurrentThread.ManagedThreadId); Group g = _current; if (g != null) { // Handles the rejected case first (easiest). if (g.IsRejectedGroup) { if (g.SavedMonitorFilter != _configuredFilter) { DoSetConfiguredFilter(g.SavedMonitorFilter); } _currentTag = g.SavedMonitorTags; _current = g.Index > 0 ? _groups[g.Index - 1] : null; } else { #region Closing the group g.CloseLogTime = _lastLogTime = new DateTimeStamp(_lastLogTime, logTime.IsKnown ? logTime : DateTimeStamp.UtcNow); var conclusions = userConclusion as List <ActivityLogGroupConclusion>; if (conclusions == null && userConclusion != null) { conclusions = new List <ActivityLogGroupConclusion>(); string s = userConclusion as string; if (s != null) { conclusions.Add(new ActivityLogGroupConclusion(Tags.UserConclusion, s)); } else { if (userConclusion is ActivityLogGroupConclusion) { conclusions.Add((ActivityLogGroupConclusion)userConclusion); } else { IEnumerable <ActivityLogGroupConclusion> multi = userConclusion as IEnumerable <ActivityLogGroupConclusion>; if (multi != null) { conclusions.AddRange(multi); } else { conclusions.Add(new ActivityLogGroupConclusion(Tags.UserConclusion, userConclusion.ToString())); } } } } g.GroupClosing(ref conclusions); bool hasBuggyClients = false; List <IActivityMonitorClient> buggyClients = null; foreach (var l in _output.Clients) { try { l.OnGroupClosing(g, ref conclusions); } 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); } buggyClients.Clear(); hasBuggyClients = true; } if (g.SavedMonitorFilter != _configuredFilter) { DoSetConfiguredFilter(g.SavedMonitorFilter); } _currentTag = g.SavedMonitorTags; _current = g.Index > 0 ? _groups[g.Index - 1] : null; _currentUnfiltered = (Group)g.Parent; var sentConclusions = conclusions != null?conclusions.ToArray() : Util.Array.Empty <ActivityLogGroupConclusion>(); foreach (var l in _output.Clients) { try { l.OnGroupClosed(g, sentConclusions); } 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); } hasBuggyClients = true; } if (hasBuggyClients) { _clientFilter = DoGetBoundClientMinimalFilter(); UpdateActualFilter(); } #endregion } string prevTopic = g.PreviousTopic; if (prevTopic != null) { DoSetTopic(prevTopic, g.FileName, g.LineNumber); } g.GroupClosed(); } }
/// <summary> /// Combines this filter with another one only if <see cref="Line"/> or <see cref="Group"/> is <see cref="LogLevelFilter.None"/>. /// </summary> /// <param name="other">The other filter to combine with this one.</param> /// <returns>The resulting filter.</returns> public LogFilter CombineNoneOnly( LogFilter other ) { var l = Line == LogLevelFilter.None ? other.Line : Line; var g = Group == LogLevelFilter.None ? other.Group : Group; return new LogFilter( g, l ); }
/// <summary> /// Combines this filter with another one. <see cref="Line"/> and <see cref="Group"/> level filters /// are combined with <see cref="Combine(LogLevelFilter,LogLevelFilter)"/>. /// </summary> /// <param name="other">The other filter to combine with this one.</param> /// <returns>The resulting filter.</returns> public LogFilter Combine(LogFilter other) { return(new LogFilter(Combine(Group, other.Group), Combine(Line, other.Line))); }
/// <summary> /// Sets a minimal <see cref="LogFilter"/> for a given file. /// Use <see cref="LogFilter.Undefined"/> to clear it. /// </summary> /// <param name="minimalFilter">The minimal filter to set for the file.</param> /// <param name="fileName">The file name: do not specify it to inject the path of your source file.</param> public static void SetMinimalFilter( LogFilter minimalFilter, [CallerFilePath]string fileName = null ) { SetFilter( new SourceLogFilter( LogFilter.Undefined, minimalFilter ), fileName ); }
void Create() { { var m = new ActivityMonitor(); } { var m = new ActivityMonitor( applyAutoConfigurations: false ); } { IActivityMonitor m = new ActivityMonitor(); var counter = new ActivityMonitorErrorCounter(); m.Output.RegisterClient( counter ); m.Fatal().Send( "An horrible error occurred." ); Assert.That( counter.Current.FatalCount == 1 ); m.Output.UnregisterClient( counter ); } { IActivityMonitor m = new ActivityMonitor(); int errorCount = 0; using( m.OnError( () => ++errorCount ) ) { m.Fatal().Send( "An horrible error occurred." ); } Assert.That( errorCount == 1 ); } { IActivityMonitor m = new ActivityMonitor(); m.MinimalFilter = LogFilter.Off; // ... m.MinimalFilter = LogFilter.Debug; } { IActivityMonitor m = new ActivityMonitor(); m.MinimalFilter = LogFilter.Terse; using( m.SetMinimalFilter( LogFilter.Debug ) ) { Assert.That( m.ActualFilter == LogFilter.Debug ); } Assert.That( m.ActualFilter == LogFilter.Terse, "Filter has been restored to previous value." ); } { IActivityMonitor m = new ActivityMonitor(); m.MinimalFilter = LogFilter.Off; // ... using( m.OpenWarn().Send( "Ouch..." ) ) { Assert.That( m.ActualFilter == LogFilter.Off ); m.MinimalFilter = LogFilter.Debug; // ... in debug filter ... } Assert.That( m.ActualFilter == LogFilter.Off, "Back to Off." ); var strange = new LogFilter( LogLevelFilter.Fatal, LogLevelFilter.Trace ); } }
/// <summary> /// Initialize a new <see cref="ActivityMonitorTextHelperClient"/> with a filter. /// </summary> protected ActivityMonitorTextHelperClient( LogFilter filter ) { _curLevel = -1; _openGroups = new Stack<bool>(); _filter = filter; }
/// <summary> /// Reads a <see cref="XElement"/> with an optional "MinimalFilter" attribute. /// </summary> /// <param name="xml">The xml element.</param> public GrandOutputChannelConfigData( XElement xml ) { MinimalFilter = xml.GetAttributeLogFilter( "MinimalFilter", true ).Value; }
/// <summary> /// Sets an override <see cref="LogFilter"/> for a given file: when not <see cref="LogFilter.Undefined"/> this /// takes precedence over <see cref="IActivityMonitor.ActualFilter"/>. /// Use <see cref="LogFilter.Undefined"/> to clear it. /// </summary> /// <param name="overrideFilter">The override filter to set for the file.</param> /// <param name="fileName">The file name: do not specify it to inject the path of your source file.</param> public static void SetOverrideFilter(LogFilter overrideFilter, [CallerFilePath] string fileName = null) { SetFilter(new SourceLogFilter(overrideFilter, LogFilter.Undefined), fileName); }
/// <summary> /// Sets a minimal <see cref="LogFilter"/> for a given file. /// Use <see cref="LogFilter.Undefined"/> to clear it. /// </summary> /// <param name="minimalFilter">The minimal filter to set for the file.</param> /// <param name="fileName">The file name: do not specify it to inject the path of your source file.</param> public static void SetMinimalFilter(LogFilter minimalFilter, [CallerFilePath] string fileName = null) { SetFilter(new SourceLogFilter(LogFilter.Undefined, minimalFilter), fileName); }
/// <summary> /// Tries to parse a <see cref="LogFilter"/>: it can be a predefined filter as ("Undefined", "Debug", "Verbose", etc.) /// or as {GroupLogLevelFilter,LineLogLevelFilter} pairs like "{None,None}", "{Error,Trace}". /// </summary> /// <param name="s">Filter to parse.</param> /// <param name="f">Resulting filter.</param> /// <returns>True on success, false on error.</returns> public static bool TryParse(string s, out LogFilter f) { var m = new StringMatcher(s); return(m.MatchLogFilter(out f) && m.IsEnd); }
/// <summary> /// Initialize a new <see cref="ActivityMonitorTextHelperClient"/> with a filter. /// </summary> protected ActivityMonitorTextHelperClient(LogFilter filter) { _curLevel = -1; _openGroups = new Stack <bool>(); _filter = filter; }
/// <summary> /// Tests if <see cref="Combine(LogFilter)">combining</see> this and <paramref name="x"/> will result in a different filter than x. /// </summary> /// <param name="x">The other filter.</param> /// <returns>True if combining this filter and <paramref name="x"/> will change x.</returns> public bool HasImpactOn(LogFilter x) { return((Line != LogLevelFilter.None && Line < x.Line) || (Group != LogLevelFilter.None && Group < x.Group)); }
internal void DoInitialize( IActivityMonitor m, XElement xml ) { MinimalFilter = xml.GetAttributeLogFilter( "MinimalFilter", true ).Value; Initialize( m, xml ); }
public LogFilterSentinel(IActivityMonitor l, LogFilter filter) { _prevLevel = l.MinimalFilter; _monitor = l; l.MinimalFilter = filter; }
/// <summary> /// Sets an override <see cref="LogFilter"/> for a given file: when not <see cref="LogFilter.Undefined"/> this /// takes precedence over <see cref="IActivityMonitor.ActualFilter"/>. /// Use <see cref="LogFilter.Undefined"/> to clear it. /// </summary> /// <param name="overrideFilter">The override filter to set for the file.</param> /// <param name="fileName">The file name: do not specify it to inject the path of your source file.</param> public static void SetOverrideFilter( LogFilter overrideFilter, [CallerFilePath]string fileName = null ) { SetFilter( new SourceLogFilter( overrideFilter, LogFilter.Undefined ), fileName ); }
/// <summary> /// Tests if <see cref="Combine(LogFilter)">combining</see> this and <paramref name="x"/> will result in a different filter than x. /// </summary> /// <param name="x">The other filter.</param> /// <returns>True if combining this filter and <paramref name="x"/> will change x.</returns> public bool HasImpactOn( LogFilter x ) { return (Line != LogLevelFilter.None && Line < x.Line) || (Group != LogLevelFilter.None && Group < x.Group); }
/// <summary> /// Initializes a new <see cref="SourceLogFilter"/> with a given filter for <see cref="Override"/>s and <see cref="Minimal"/>. /// </summary> /// <param name="overrideFilter">Overridden filter.</param> /// <param name="minimalFilter">Minimal filter.</param> public SourceLogFilter(LogFilter overrideFilter, LogFilter minimalFilter) { Override = overrideFilter; Minimal = minimalFilter; }
/// <summary> /// Initializes a new <see cref="SourceLogFilter"/> with a given filter for <see cref="Override"/>s and <see cref="Minimal"/>. /// </summary> /// <param name="overrideFilter">Overridden filter.</param> /// <param name="minimalFilter">Minimal filter.</param> public SourceLogFilter( LogFilter overrideFilter, LogFilter minimalFilter ) { Override = overrideFilter; Minimal = minimalFilter; }
/// <summary> /// Base constructor bound to base configuration object. /// </summary> /// <param name="config">The configuration object.</param> protected HandlerBase( HandlerConfiguration config ) { _name = config.Name; _minimalFilter = config.MinimalFilter; }
/// <summary> /// Tries to parse a <see cref="LogFilter"/>: it can be a predefined filter as ("Undefined", "Debug", "Verbose", etc.) /// or as {GroupLogLevelFilter,LineLogLevelFilter} pairs like "{None,None}", "{Error,Trace}". /// </summary> /// <param name="s">Filter to parse.</param> /// <param name="f">Resulting filter.</param> /// <returns>True on success, false on error.</returns> public static bool TryParse( string s, out LogFilter f ) { var m = new StringMatcher( s ); return m.MatchLogFilter( out f ) && m.IsEnd; }
/// <summary> /// Sets a filter level on this <see cref="IActivityMonitor"/>. The current <see cref="IActivityMonitor.MinimalFilter"/> will be automatically /// restored when the returned <see cref="IDisposable"/> will be disposed. /// Even if when a Group is closed, the IActivityMonitor.Filter is automatically restored to its original value /// (captured when the Group was opened), this may be useful to locally change the filter level without bothering to restore the /// initial value (this is what OpenGroup/CloseGroup do with both the Filter and the AutoTags). /// </summary> /// <param name="this">This <see cref="IActivityMonitor"/> object.</param> /// <param name="f">The new filter.</param> /// <returns>A <see cref="IDisposable"/> object that will restore the current level.</returns> public static IDisposable SetMinimalFilter(this IActivityMonitor @this, LogFilter f) { return(new LogFilterSentinel(@this, f)); }
/// <summary> /// Matches a <see cref="LogFilter"/>: it can be a predefined filter as ("Undefined", "Debug", "Verbose", etc.) /// or as {GroupLogLevelFilter,LineLogLevelFilter} pairs like "{None,None}", "{Error,Trace}". /// </summary> /// <param name="m">This <see cref="StringMatcher"/>.</param> /// <param name="f">Resulting filter.</param> /// <returns>True on success, false on error.</returns> public static bool MatchLogFilter(this StringMatcher m, out LogFilter f) { f = LogFilter.Undefined; if (!m.MatchText("Undefined")) { if (m.MatchText("Debug")) { f = LogFilter.Debug; } else if (m.MatchText("Verbose")) { f = LogFilter.Verbose; } else if (m.MatchText("Monitor")) { f = LogFilter.Monitor; } else if (m.MatchText("Terse")) { f = LogFilter.Terse; } else if (m.MatchText("Release")) { f = LogFilter.Release; } else if (m.MatchText("Off")) { f = LogFilter.Off; } else if (m.MatchText("Invalid")) { f = LogFilter.Invalid; } else { int savedIndex = m.StartIndex; if (!m.MatchChar('{')) { return(m.BackwardAddError(savedIndex)); } LogLevelFilter group, line; m.MatchWhiteSpaces(); if (!m.MatchLogLevelFilter(out group)) { return(m.BackwardAddError(savedIndex)); } m.MatchWhiteSpaces(); if (!m.MatchChar(',')) { return(m.BackwardAddError(savedIndex)); } m.MatchWhiteSpaces(); if (!m.MatchLogLevelFilter(out line)) { return(m.BackwardAddError(savedIndex)); } m.MatchWhiteSpaces(); if (!m.MatchChar('}')) { return(m.BackwardAddError(savedIndex)); } f = new LogFilter(group, line); } } return(true); }
/// <summary> /// This is necessarily called in the context of the activity: we can call the bridge that can call /// the Monitor's ActualFilter that will be resynchronized if needed. /// </summary> LogFilter GetActualTargetFilter() { Interlocked.MemoryBarrier(); var f = _targetActualFilter; if( f == LogFilter.Invalid ) { do { f = _bridgeTarget.TargetFinalFilter; _targetActualFilter = f; Interlocked.MemoryBarrier(); } while( _targetActualFilter == LogFilter.Invalid ); } return f; }
/// <summary> /// Internal constructor used by Sequence and Parallel. /// </summary> /// <param name="config">Parallel or sequence configuration.</param> internal HandlerBase( CK.RouteConfig.Impl.ActionCompositeConfiguration config ) { _name = config.Name; _minimalFilter = LogFilter.Undefined; }
void CheckFilter( bool callOnClientMinimalFilterChanged, LogFilter f ) { if( _currentMinimalFilter != f ) { var prev = _currentMinimalFilter; _currentMinimalFilter = f; if( callOnClientMinimalFilterChanged ) _monitorSource.OnClientMinimalFilterChanged( prev, f ); } }
/// <summary> /// forceBuggyRemove is not used here since this client is not lockable. /// </summary> void IActivityMonitorBoundClient.SetMonitor( Impl.IActivityMonitorImpl source, bool forceBuggyRemove ) { if( source != null && _source != null ) throw ActivityMonitorClient.CreateMultipleRegisterOnBoundClientException( this ); if( _source != null ) { _bridgeTarget.RemoveCallback( this ); // Unregistering. for( int i = 0; i < _openedGroups.Count; ++i ) { if( _openedGroups[i] ) { _targetMonitor.CloseGroup( new ActivityLogGroupConclusion( ActivityMonitorResources.ClosedByBridgeRemoved, TagBridgePrematureClose ) ); } } _openedGroups.Clear(); } else { _bridgeTarget.AddCallback( this ); _targetActualFilter = _bridgeTarget.TargetFinalFilter; if( _pullTargetTopicAndAutoTagsFromTarget ) { source.InitializeTopicAndAutoTags( this._targetMonitor.Topic, _targetMonitor.AutoTags ); } } _source = source; Interlocked.MemoryBarrier(); }
internal ChannelOption( LogFilter mainRouteFilter ) { _currentFilter = mainRouteFilter; }
/// <summary> /// Combines this filter with another one. <see cref="Line"/> and <see cref="Group"/> level filters /// are combined with <see cref="Combine(LogLevelFilter,LogLevelFilter)"/>. /// </summary> /// <param name="other">The other filter to combine with this one.</param> /// <returns>The resulting filter.</returns> public LogFilter Combine( LogFilter other ) { return new LogFilter( Combine( Group, other.Group ), Combine( Line, other.Line ) ); }
/// <summary> /// Enables any handler to publish the minimal filter level it requires (if any). /// </summary> /// <param name="filter">Filter required by a <see cref="HandlerBase"/>.</param> public void SetMinimalFilter( LogFilter filter ) { _currentFilter = _currentFilter.Combine( filter ); }
/// <summary> /// Initializes a new instance of <see cref="GrandOutputChannelConfigData"/>. /// The <see cref="MinimalFilter"/> is <see cref="LogFilter.Undefined"/>. /// </summary> public GrandOutputChannelConfigData() { MinimalFilter = LogFilter.Undefined; }