This ActivityMonitor logs errors in a directory (if the static RootLogPath property is not null) and raises OnError events. Its main goal is to be internally used by the Monitor framework but can be used as a "normal" monitor (if you believe it is a good idea). The easiest way to configure it is to set an application settings with the key "CK.Core.SystemActivityMonitor.RootLogPath" and the root path for logs as the value.
The RootLogPath uses the Application configuration (if it exists): <appSettings> <add key="CK.Core.SystemActivityMonitor.RootLogPath" value="..." /> </appSettings> If the setting is not there, the Critical errors will NOT be logged except if it is explicitly set: SystemActivityMonitor.RootLogPath = "...";
Inheritance: ActivityMonitor
 public void OnOpenGroup(IActivityLogGroup group)
 {
     if (group.MaskedGroupLevel >= LogLevel.Error)
     {
         string s = DumpErrorText(group.LogTime, group.GroupText, group.MaskedGroupLevel, group.GroupTags, group.EnsureExceptionData());
         SystemActivityMonitor.HandleError(s);
     }
 }
            public void OnUnfilteredLog(ActivityMonitorLogData data)
            {
                var level = data.Level & LogLevel.Mask;

                if (level >= LogLevel.Error)
                {
                    string s = DumpErrorText(data.LogTime, data.Text, data.Level, null, data.Tags);
                    SystemActivityMonitor.HandleError(s);
                }
            }
 /// <summary>
 /// Ensures that the <see cref="Default"/> GrandOutput is created (see <see cref="EnsureActiveDefault"/>) and configured with default settings:
 /// only one one channel with its minimal filter sets to Debug with one text file handler that writes .txt files in "<see cref="SystemActivityMonitor.RootLogPath"/>\GrandOutputDefault" directory.
 /// The <see cref="SystemActivityMonitor.RootLogPath"/> must be valid and if a GrandOutput.config file exists inside, it is loaded as the configuration.
 /// If it exists, it must be valid (otherwise an exception is thrown).
 /// Once loaded, the file is monitored and any change that occurs to it dynamically triggers a <see cref="SetConfiguration"/> with the new file.
 /// </summary>
 /// <param name="monitor">An optional monitor.</param>
 static public GrandOutput EnsureActiveDefaultWithDefaultSettings( IActivityMonitor monitor = null )
 {
     lock( _defaultLock )
     {
         if( _default == null )
         {
             if( monitor == null ) monitor = new SystemActivityMonitor( true, "GrandOutput" ) { MinimalFilter = GrandOutputMinimalFilter };
             using( monitor.OpenGroup( LogLevel.Info, "Attempting Default GrandOutput configuration.", null ) )
             {
                 try
                 {
                     SystemActivityMonitor.AssertRootLogPathIsSet();
                     _configPath = SystemActivityMonitor.RootLogPath + "GrandOutput.config";
                     GrandOutputConfiguration def = CreateDefaultConfig();
                     if( !File.Exists( _configPath ) )
                     {
                         File.WriteAllText( _configPath, _defaultConfig );
                     }
                     if( !def.LoadFromFile( _configPath, monitor ) )
                     {
                         throw new CKException( "Unable to load Configuration file: '{0}'.", _configPath );
                     }
                     GrandOutput output = new GrandOutput();
                     if( !output.SetConfiguration( def, monitor ) )
                     {
                         throw new CKException( "Failed to set Configuration." );
                     }
                     StartMonitoring( monitor );
                     _default = output;
                     ActivityMonitor.AutoConfiguration += m => _default.Register( m );
                 }
                 catch( Exception ex )
                 {
                     monitor.SendLine( LogLevel.Fatal, null, ex );
                     throw;
                 }
             }
         }
     }
     return _default;
 }
示例#4
0
        /// <summary>
        /// Attempts to set a new configuration.
        /// </summary>
        /// <param name="config">The configuration that must be set.</param>
        /// <param name="monitor">Optional monitor.</param>
        /// <param name="millisecondsBeforeForceClose">Optional timeout to wait before forcing the close of the currently active configuration.</param>
        /// <returns>True on success.</returns>
        public bool SetConfiguration( GrandOutputConfiguration config, IActivityMonitor monitor = null, int millisecondsBeforeForceClose = Timeout.Infinite )
        {
            if( config == null ) throw new ArgumentNullException( "config" );
            if( monitor == null ) monitor = new SystemActivityMonitor( true, "GrandOutput" ) { MinimalFilter = GrandOutputMinimalFilter };
            using( monitor.OpenGroup( LogLevel.Info, this == Default ? "Applying Default GrandOutput configuration." : "Applying GrandOutput configuration.", null ) )
            {
                if( _channelHost.SetConfiguration( monitor, config.ChannelsConfiguration ?? new RouteConfiguration(), millisecondsBeforeForceClose ) )
                {
                    if( this == _default &&  config.GlobalDefaultFilter.HasValue ) ActivityMonitor.DefaultFilter = config.GlobalDefaultFilter.Value;

                    if( config.SourceOverrideFilterApplicationMode == SourceFilterApplyMode.Clear || config.SourceOverrideFilterApplicationMode == SourceFilterApplyMode.ClearThenApply )
                    {
                        ActivityMonitor.SourceFilter.ClearOverrides();
                    }
                    if( config.SourceOverrideFilter != null && (config.SourceOverrideFilterApplicationMode == SourceFilterApplyMode.Apply || config.SourceOverrideFilterApplicationMode == SourceFilterApplyMode.ClearThenApply) )
                    {
                        foreach( var k in config.SourceOverrideFilter ) ActivityMonitor.SourceFilter.SetOverrideFilter( k.Value, k.Key );
                    }
                    monitor.CloseGroup( "Success." );
                    return true;
                }
                return false;
            }
        }
 static void Reload( object state )
 {
     if( _watcher == null ) return;
     // Quick and dirty trick to handle Renamed events
     // or too quick events.
     Thread.Sleep( 100 );
     var time = File.GetLastWriteTimeUtc( _configPath );
     if( time != _lastConfigFileWriteTime )
     {
         GrandOutputConfiguration def;
         lock( _watcherLock )
         {
             time = File.GetLastWriteTimeUtc( _configPath );
             if( time == _lastConfigFileWriteTime ) return;
             _lastConfigFileWriteTime = time;
         }
         var monitor = new SystemActivityMonitor( true, "GrandOutput.Default.Reconfiguration" ) { MinimalFilter = GrandOutputMinimalFilter };
         try
         {
             using( monitor.OpenGroup( LogLevel.Info, string.Format( "AppDomain '{0}',  file '{1}' changed (change n°{2}).", AppDomain.CurrentDomain.FriendlyName, _configPath, _default.ConfigurationAttemptCount ), null ) )
             {
                 def = CreateDefaultConfig();
                 if( File.Exists( _configPath ) )
                 {
                     if( time == FileUtil.MissingFileLastWriteTimeUtc ) _lastConfigFileWriteTime = File.GetLastWriteTimeUtc( _configPath );
                     def.LoadFromFile( _configPath, monitor );
                 }
                 else
                 {
                     _lastConfigFileWriteTime = FileUtil.MissingFileLastWriteTimeUtc;
                     monitor.SendLine( LogLevel.Trace, "File missing: applying catch-all default configuration.", null );
                 }
                 if( !_default._channelHost.IsDisposed ) _default.SetConfiguration( def, monitor );
             }
         }
         catch( Exception ex )
         {
             monitor.SendLine( LogLevel.Error, null, ex );
         }
     }
 }