/// <summary> /// Opens this writer if it is not already opened. /// </summary> /// <returns>True on success, false otherwise.</returns> public bool Open() { using (_source.ReentrancyAndConcurrencyLock()) { if (_source == null) { throw new InvalidOperationException("CKMonWriterClient must be registered in an ActivityMonitor."); } if (_file != null) { return(true); } _file = new MonitorBinaryFileOutput(_path, _source.UniqueId, _maxCountPerFile, _useGzipCompression); _prevLogType = LogEntryType.None; _prevlogTime = DateTimeStamp.Unknown; } using (SystemActivityMonitor.EnsureSystemClient(_source)) { using (_source.ReentrancyAndConcurrencyLock()) { if (_file.Initialize(_source)) { var g = _source.CurrentGroup; _currentGroupDepth = g != null ? g.Depth : 0; } else { _file = null; } } } return(_file != null); }
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); } } }
/// <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); } const string _defaultConfig = @"<GrandOutputConfiguration> <Channel MinimalFilter=""Debug""> <Add Type=""TextFile"" Name=""All"" Path=""GrandOutputDefault"" MaxCountPerFile=""20000"" /> </Channel> </GrandOutputConfiguration>";
/// <summary> /// Ensures that the <see cref="Default"/> GrandOutput is created and that any <see cref="ActivityMonitor"/> that will be created in this /// application domain will automatically have a <see cref="GrandOutputClient"/> registered for this Default GrandOutput. /// Use <see cref="EnsureActiveDefaultWithDefaultSettings"/> to initially configure this default. /// </summary> /// <param name="configurator"> /// Optional action that can configure the default GrandOutput. /// If specified will be called after the creation of a new GrandOutput: it will not be called /// if a <see cref="Default"/> is already available. /// This parameter is optional since you can configure it at any time. /// </param> /// <returns>The Default GrandOutput.</returns> /// <remarks> /// This method is thread-safe (a simple lock protects it) and uses a <see cref="ActivityMonitor.AutoConfiguration"/> action /// that <see cref="Register"/>s newly created <see cref="ActivityMonitor"/>. /// </remarks> static public GrandOutput EnsureActiveDefault(Action <GrandOutput> configurator = null) { lock ( _defaultLock ) { if (_default != null) { configurator = null; } else { SystemActivityMonitor.EnsureStaticInitialization(); _default = new GrandOutput(); ActivityMonitor.AutoConfiguration += m => Default.Register(m); } } if (configurator != null) { configurator(_default); } return(_default); }
/// <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); } }