public App() { InitializeComponent(); Serilog.Debugging.SelfLog.Enable(msg => System.Diagnostics.Debug.WriteLine(msg)); var levelSwitch = new LoggingLevelSwitch(); levelSwitch.MinimumLevel = LogEventLevel.Verbose; var debugLogTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} {SourceContext} [{Level}] {Message}{NewLine}{Exception}"; Log.Logger = new LoggerConfiguration() .MinimumLevel.ControlledBy(levelSwitch) .WriteTo.Debug(outputTemplate: debugLogTemplate) .CreateLogger(); Log.Debug("====== resource debug info ========="); var assembly = typeof(App).GetTypeInfo().Assembly; foreach (var res in assembly.GetManifestResourceNames()) Log.Debug("found resource: " + res); Log.Debug("===================================="); // This lookup NOT required for Windows platforms - the Culture will be automatically set if (Device.OS == TargetPlatform.iOS || Device.OS == TargetPlatform.Android) { // determine the correct, supported .NET culture var ci = DependencyService.Get<ILocalize>().GetCurrentCultureInfo(); XportBand.Properties.Resources.Culture = ci; // set the RESX for resource localization DependencyService.Get<ILocalize>().SetLocale(ci); // set the Thread for locale-aware methods } //NavigationPage shellView = new NavigationPage(new MainView()); //MainPage = shellView; MainPage = new NavigationPage(new MainView()); }
public DurableSeqSink( string serverUrl, string bufferBaseFilename, string apiKey, int batchPostingLimit, TimeSpan period, long? bufferFileSizeLimitBytes, long? eventBodyLimitBytes, LoggingLevelSwitch levelControlSwitch, HttpMessageHandler messageHandler, long? retainedInvalidPayloadsLimitBytes) { if (serverUrl == null) throw new ArgumentNullException(nameof(serverUrl)); if (bufferBaseFilename == null) throw new ArgumentNullException(nameof(bufferBaseFilename)); _shipper = new HttpLogShipper( serverUrl, bufferBaseFilename, apiKey, batchPostingLimit, period, eventBodyLimitBytes, levelControlSwitch, messageHandler, retainedInvalidPayloadsLimitBytes); _sink = new RollingFileSink( bufferBaseFilename + "-{Date}.json", new RawJsonFormatter(), bufferFileSizeLimitBytes, null); }
public void LoggingLevelSwitchDynamicallyChangesLevel() { var events = new List<LogEvent>(); var sink = new DelegatingSink(events.Add); var levelSwitch = new LoggingLevelSwitch(LogEventLevel.Information); var log = new LoggerConfiguration() .MinimumLevel.ControlledBy(levelSwitch) .WriteTo.Sink(sink) .CreateLogger() .ForContext<LoggerTests>(); log.Debug("Suppressed"); log.Information("Emitted"); log.Warning("Emitted"); // Change the level levelSwitch.MinimumLevel = LogEventLevel.Error; log.Warning("Suppressed"); log.Error("Emitted"); log.Fatal("Emitted"); Assert.Equal(4, events.Count); Assert.True(events.All(evt => evt.RenderMessage() == "Emitted")); }
static LoggerConfig() { LoggingLevelController = new LoggingLevelSwitch(); UpdateLoggingLevelController = new LoggingLevelSwitch(); _logDirectory = HostingEnvironment.MapPath(ConfigurationManager.AppSettings["TM.Paths.Log"]); var file = File.CreateText(Path.Combine(_logDirectory, "serilog.debug.log")); Serilog.Debugging.SelfLog.Out = TextWriter.Synchronized(file); }
/// <summary> /// Initializes a new instance of the <see cref="UserSettings"/> class. /// </summary> /// <param name="loggingLevelSwitch">An object used to change logging level at runtime.</param> public UserSettings(Serilog.Core.LoggingLevelSwitch loggingLevelSwitch) { this.InitializeComponent(); this.lblMessage.Text = "User Settings"; this.chkShowReleaseCandidates.Checked = Properties.Settings.Default.ShowReleaseCandidates; this.chkShareStatistics.Checked = Properties.Settings.Default.ShareStatistics; this.chkEnableLocalPackageInstall.Checked = Properties.Settings.Default.EnableLocalPackageInstall; this.loggingLevelSwitch = loggingLevelSwitch; this.PopulateLoggingLevelSwitchCombo(); }
/// <summary> /// Adds a sink that writes log events to a http://getseq.net Seq event server. /// </summary> /// <param name="loggerSinkConfiguration">The logger configuration.</param> /// <param name="serverUrl">The base URL of the Seq server that log events will be written to.</param> /// <param name="restrictedToMinimumLevel">The minimum log event level required /// in order to write an event to the sink.</param> /// <param name="batchPostingLimit">The maximum number of events to post in a single batch.</param> /// <param name="period">The time to wait between checking for event batches.</param> /// <param name="bufferBaseFilename">Path for a set of files that will be used to buffer events until they /// can be successfully transmitted across the network. Individual files will be created using the /// pattern <paramref name="bufferBaseFilename"/>-{Date}.json.</param> /// <param name="apiKey">A Seq <i>API key</i> that authenticates the client to the Seq server.</param> /// <param name="bufferFileSizeLimitBytes">The maximum size, in bytes, to which the buffer /// log file for a specific date will be allowed to grow. By default no limit will be applied.</param> /// <param name="eventBodyLimitBytes">The maximum size, in bytes, that the JSON representation of /// an event may take before it is dropped rather than being sent to the Seq server. Specify null for no limit. /// The default is 265 KB.</param> /// <param name="controlLevelSwitch">If provided, the switch will be updated based on the Seq server's level setting /// for the corresponding API key. Passing the same key to MinimumLevel.ControlledBy() will make the whole pipeline /// dynamically controlled. Do not specify <paramref name="restrictedToMinimumLevel"/> with this setting.</param> /// <param name="messageHandler">Used to construct the HttpClient that will be used to send the log meesages to Seq.</param> /// <param name="retainedInvalidPayloadsLimitBytes">A soft limit for the number of bytes to use for storing failed requests. /// The limit is soft in that it can be exceeded by any single error payload, but in that case only that single error /// payload will be retained.</param> /// <returns>Logger configuration, allowing configuration to continue.</returns> /// <exception cref="ArgumentNullException">A required parameter is null.</exception> public static LoggerConfiguration Seq( this LoggerSinkConfiguration loggerSinkConfiguration, string serverUrl, LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, int batchPostingLimit = SeqSink.DefaultBatchPostingLimit, TimeSpan? period = null, string apiKey = null, string bufferBaseFilename = null, long? bufferFileSizeLimitBytes = null, long? eventBodyLimitBytes = 256 * 1024, LoggingLevelSwitch controlLevelSwitch = null, HttpMessageHandler messageHandler = null, long? retainedInvalidPayloadsLimitBytes = null) { if (loggerSinkConfiguration == null) throw new ArgumentNullException(nameof(loggerSinkConfiguration)); if (serverUrl == null) throw new ArgumentNullException(nameof(serverUrl)); if (bufferFileSizeLimitBytes.HasValue && bufferFileSizeLimitBytes < 0) throw new ArgumentException("Negative value provided; file size limit must be non-negative"); var defaultedPeriod = period ?? SeqSink.DefaultPeriod; ILogEventSink sink; if (bufferBaseFilename == null) { sink = new SeqSink( serverUrl, apiKey, batchPostingLimit, defaultedPeriod, eventBodyLimitBytes, controlLevelSwitch, messageHandler); } else { #if DURABLE sink = new DurableSeqSink( serverUrl, bufferBaseFilename, apiKey, batchPostingLimit, defaultedPeriod, bufferFileSizeLimitBytes, eventBodyLimitBytes, controlLevelSwitch, messageHandler, retainedInvalidPayloadsLimitBytes); #else // We keep the API consistent for easier packaging and to support bait-and-switch. throw new NotSupportedException("Durable log shipping is not supported on this platform."); #endif } return loggerSinkConfiguration.Sink(sink, restrictedToMinimumLevel); }
/// <summary> /// Initializes a new instance of the <see cref="Start"/> class. /// </summary> /// <param name="loggingLevelSwitch">An object that can be used to dynamically change the logging level at runtime.</param> public Start(Serilog.Core.LoggingLevelSwitch loggingLevelSwitch) { this.InitializeComponent(); this.InitializeTabs(); this.LoadPackages(); this.ReadUserSettings(); this.loggingLevelSwitch = loggingLevelSwitch; this.downloadProgressLogTimer = new Timer() { Interval = 2000 }; this.downloadProgressLogTimer.Tick += this.DownloadProgressLogTimer_Tick; }
private static LoggerConfiguration GetConfiguration() { string minimumLogLevel = ConfigurationManager.GetConfigurationValue("ParameterConfigFileLocation", "MinimumLogLevel"); var levelSwitch = new LoggingLevelSwitch(); LogEventLevel logLevel; Enum.TryParse(minimumLogLevel, out logLevel); levelSwitch.MinimumLevel = logLevel; return new LoggerConfiguration().MinimumLevel.ControlledBy(levelSwitch).WriteTo.RollingFile(GetLogFileName()); }
public void GetEffectiveLevel(string context, out LogEventLevel minimumLevel, out LoggingLevelSwitch levelSwitch) { foreach (var levelOverride in _overrides) { if (context.StartsWith(levelOverride.ContextPrefix) || context == levelOverride.Context) { minimumLevel = LevelAlias.Minimum; levelSwitch = levelOverride.LevelSwitch; return; } } minimumLevel = _defaultMinimumLevel; levelSwitch = _defaultLevelSwitch; }
private static LoggerConfiguration GetConfiguration() { string minimumLogLevel = DbConfig.GetMixERPParameter(AppUsers.GetCurrentUserDB(), "MinimumLogLevel"); LoggingLevelSwitch levelSwitch = new LoggingLevelSwitch(); LogEventLevel logLevel; Enum.TryParse(minimumLogLevel, out logLevel); levelSwitch.MinimumLevel = logLevel; return new LoggerConfiguration().MinimumLevel.ControlledBy(levelSwitch) .WriteTo.RollingFile(GetLogFileName()); }
public LevelOverrideMap( IDictionary<string, LoggingLevelSwitch> overrides, LogEventLevel defaultMinimumLevel, LoggingLevelSwitch defaultLevelSwitch) { if (overrides == null) throw new ArgumentNullException(nameof(overrides)); _defaultLevelSwitch = defaultLevelSwitch; _defaultMinimumLevel = defaultLevelSwitch != null ? LevelAlias.Minimum : defaultMinimumLevel; // Descending order means that if we have a match, we're sure about it being the most specific. _overrides = overrides .OrderByDescending(o => o.Key) .Select(o => new LevelOverride(o.Key, o.Value)) .ToArray(); }
public LevelOverrideMap( IDictionary <string, LoggingLevelSwitch> overrides, LogEventLevel defaultMinimumLevel, LoggingLevelSwitch defaultLevelSwitch) { if (overrides == null) { throw new ArgumentNullException(nameof(overrides)); } _defaultLevelSwitch = defaultLevelSwitch; _defaultMinimumLevel = defaultLevelSwitch != null ? LevelAlias.Minimum : defaultMinimumLevel; // Descending order means that if we have a match, we're sure about it being the most specific. _overrides = overrides .OrderByDescending(o => o.Key) .Select(o => new LevelOverride(o.Key, o.Value)) .ToArray(); }
static void Main(string[] args) { var levelSwitch = new LoggingLevelSwitch(); levelSwitch.MinimumLevel = LogEventLevel.Verbose; var messages = new StringWriter(); //Serilogger Log.Logger = new LoggerConfiguration() .MinimumLevel.ControlledBy(levelSwitch) .Enrich.WithProperty("Name", "MudFund") .Enrich.WithProperty("Version", "1.0.0") .WriteTo.ColoredConsole() .CreateLogger(); //Load a portfolio var portfolio = new Portfolio(); portfolio.Load(@"portfolio.txt"); //Start collecting stock info. var stockFactory = new Factory(@"stockdb.txt",portfolio.StockList); stockFactory.stocksPerTransaction = 10; stockFactory.transactionDelay = 86400; //daily pullback 24hrs,86400sec stockFactory.LoadHistorical(); //may take time to load stockFactory.Start(); //----------------------------------------------------- //----------------------------------------------------- //----------------------------------------------------- // IMPLEMENT AI ON STOCK DATA IN FILE. //Run the prediction on stockdata //Port the output of the predictor //to elasticsearch in order to view stock info //----------------------------------------------------- //----------------------------------------------------- //----------------------------------------------------- Console.ReadLine(); }
public SeqSink( string serverUrl, string apiKey, int batchPostingLimit, TimeSpan period, long? eventBodyLimitBytes, LoggingLevelSwitch levelControlSwitch, HttpMessageHandler messageHandler) : base(batchPostingLimit, period) { if (serverUrl == null) throw new ArgumentNullException(nameof(serverUrl)); _apiKey = apiKey; _eventBodyLimitBytes = eventBodyLimitBytes; _levelControlSwitch = levelControlSwitch; var baseUri = serverUrl; if (!baseUri.EndsWith("/")) baseUri += "/"; _httpClient = messageHandler != null ? new HttpClient(messageHandler) : new HttpClient(); _httpClient.BaseAddress = new Uri(baseUri); }
public static void Main(string[] args) { // By sharing between the Seq sink and logger itself, // Seq API keys can be used to control the level of the whole logging pipeline. var levelSwitch = new LoggingLevelSwitch(); Log.Logger = new LoggerConfiguration() .MinimumLevel.ControlledBy(levelSwitch) .WriteTo.LiterateConsole() .WriteTo.Seq("http://localhost:5341", apiKey: "yeEZyL3SMcxEKUijBjN", controlLevelSwitch: levelSwitch) .CreateLogger(); Log.Information("Sample starting up"); foreach (var i in Enumerable.Range(0, 1000)) { Log.Information("Running loop {Counter}", i); Thread.Sleep(1000); Log.Debug("Loop iteration done"); } }
public static void Main() { //try //{ // add unhandled exception handler App.DispatcherUnhandledException += App_DispatcherUnhandledException; AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException; TaskScheduler.UnobservedTaskException += TaskSchedulerOnUnobservedTaskException; // Setup logging, default to information level to start with to log the startup and key system information var levelSwitch = new Serilog.Core.LoggingLevelSwitch(Serilog.Events.LogEventLevel.Information); Log.Information("============ DaxStudio Startup ============="); ConfigureLogging(levelSwitch); // Default web requests like AAD Auth to use windows credentials for proxy auth System.Net.WebRequest.DefaultWebProxy.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials; // add the custom DAX Studio accent color theme App.AddDaxStudioAccentColor(); // TODO - do we need to customize the navigator window to fix the styling? //app.AddResourceDictionary("pack://application:,,,/DaxStudio.UI;Component/Resources/Styles/AvalonDock.NavigatorWindow.xaml"); // then load Caliburn Micro bootstrapper Log.Debug("Loading Caliburn.Micro bootstrapper"); AppBootstrapper bootstrapper = new AppBootstrapper(Assembly.GetAssembly(typeof(DaxStudioHost)), true); _eventAggregator = bootstrapper.GetEventAggregator(); // read command line arguments App.ReadCommandLineArgs(); AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; // force control tooltips to display even if disabled ToolTipService.ShowOnDisabledProperty.OverrideMetadata( typeof(Control), new FrameworkPropertyMetadata(true)); // get the global options _options = bootstrapper.GetOptions(); _options.Initialize(); Log.Information("User Options initialized"); // check if we are running portable that we have write access to the settings if (_options.IsRunningPortable) { if (CanWriteToSettings()) { Log.Information(Constants.LogMessageTemplate, nameof(EntryPoint), nameof(Main), "Test for read/write access to Settings.json: PASS"); } else { Log.Error(Constants.LogMessageTemplate, nameof(EntryPoint), nameof(Main), "Test for read/write access to Settings.json: FAIL"); ShowSettingPermissionErrorDialog(); App.Shutdown(3); return; } } // load selected theme var themeManager = bootstrapper.GetThemeManager(); themeManager.SetTheme(_options.Theme); Log.Information("ThemeManager configured"); //var theme = options.Theme;// "Light"; //if (theme == "Dark") app.LoadDarkTheme(); //else app.LoadLightTheme(); // log startup switches if (_options.AnyExternalAccessAllowed()) { var args = App.Args().AsDictionaryForTelemetry(); Telemetry.TrackEvent("App.Startup", args); } // only used for testing of crash reporting UI if (App.Args().TriggerCrashTest) { throw new ArgumentException("Test Exception triggered by command line argument"); } // Launch the User Interface Log.Information("Launching User Interface"); bootstrapper.DisplayShell(); App.Run(); //} //catch (Exception ex) //{ // Log.Fatal(ex, "Class: {0} Method: {1} Error: {2}", "EntryPoint", "Main", ex.Message); // Log.CloseAndFlush(); // //#if DEBUG // // MessageBox.Show(ex.Message, "DAX Studio Standalone unhandled exception"); // //#else // // use CrashReporter.Net to send bug to DrDump // LogFatalCrash(ex, ex.Message, _options); // //#endif //} //finally //{ Log.Information("============ DaxStudio Shutdown ============="); Log.CloseAndFlush(); //} }
public static void Main() { try { // add unhandled exception handler App.DispatcherUnhandledException += App_DispatcherUnhandledException; AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException; TaskScheduler.UnobservedTaskException += TaskSchedulerOnUnobservedTaskException; // Setup logging var levelSwitch = new Serilog.Core.LoggingLevelSwitch(Serilog.Events.LogEventLevel.Error); ConfigureLogging(levelSwitch); Log.Information("============ DaxStudio Startup ============="); // add the custom DAX Studio accent color theme App.AddDaxStudioAccentColor(); // TODO - do we need to customize the navigator window to fix the styling? //app.AddResourceDictionary("pack://application:,,,/DaxStudio.UI;Component/Resources/Styles/AvalonDock.NavigatorWindow.xaml"); // then load Caliburn Micro bootstrapper Log.Debug("Loading Caliburn.Micro bootstrapper"); AppBootstrapper bootstrapper = new AppBootstrapper(Assembly.GetAssembly(typeof(DaxStudioHost)), true); _eventAggregator = bootstrapper.GetEventAggregator(); // read command line arguments App.ReadCommandLineArgs(); AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; if (App.Args().TriggerCrashTest) { throw new ArgumentException("Test Exception triggered by command line argument"); } // force control tooltips to display even if disabled ToolTipService.ShowOnDisabledProperty.OverrideMetadata( typeof(Control), new FrameworkPropertyMetadata(true)); // get the global options _options = bootstrapper.GetOptions(); _options.Initialize(); Log.Information("User Options initialized"); // check if we are running portable that we have write access to the settings if (_options.IsRunningPortable) { if (CanWriteToSettings()) { Log.Information(Constants.LogMessageTemplate, nameof(EntryPoint), nameof(Main), "Test for read/write access to Settings.json: PASS"); } else { Log.Error(Constants.LogMessageTemplate, nameof(EntryPoint), nameof(Main), "Test for read/write access to Settings.json: FAIL"); ShowSettingPermissionErrorDialog(); App.Shutdown(3); return; } } // load selected theme var themeManager = bootstrapper.GetThemeManager(); themeManager.SetTheme(_options.Theme); Log.Information("ThemeManager configured"); //var theme = options.Theme;// "Light"; //if (theme == "Dark") app.LoadDarkTheme(); //else app.LoadLightTheme(); // log startup switches var args = App.Args().AsDictionaryForTelemetry(); Telemetry.TrackEvent("App.Startup", args); // Launch the User Interface Log.Information("Launching User Interface"); bootstrapper.DisplayShell(); App.Run(); } //catch (ArgumentOutOfRangeException argEx) //{ // var st = new System.Diagnostics.StackTrace(argEx); // var sf = st.GetFrame(0); // if (sf.GetMethod().Name == "GetLineByOffset") // { // if (_eventAggregator != null) _eventAggregator.PublishOnUIThread(new OutputMessage(MessageType.Warning, "Editor syntax highlighting attempted to scan beyond the end of the current line")); // Log.Warning(argEx, "{class} {method} AvalonEdit TextDocument.GetLineByOffset: {message}", "EntryPoint", "Main", "Argument out of range exception"); // } //} catch (Exception ex) { Log.Fatal(ex, "Class: {0} Method: {1} Error: {2} Stack: {3}", "EntryPoint", "Main", ex.Message, ex.StackTrace); Log.CloseAndFlush(); //#if DEBUG // MessageBox.Show(ex.Message, "DAX Studio Standalone unhandled exception"); //#else // use CrashReporter.Net to send bug to DrDump CrashReporter.ReportCrash(ex, "DAX Studio Standalone Fatal crash in Main() method"); //#endif } finally { Log.Information("============ DaxStudio Shutdown ============="); Log.CloseAndFlush(); } }
public void GetEffectiveLevel(string context, out LogEventLevel minimumLevel, out LoggingLevelSwitch levelSwitch) { foreach (var levelOverride in _overrides) { if (context.StartsWith(levelOverride.ContextPrefix) || context == levelOverride.Context) { minimumLevel = LevelAlias.Minimum; levelSwitch = levelOverride.LevelSwitch; return; } } minimumLevel = _defaultMinimumLevel; levelSwitch = _defaultLevelSwitch; }
public LevelOverride(string context, LoggingLevelSwitch levelSwitch) { Context = context; ContextPrefix = context + "."; LevelSwitch = levelSwitch; }
private LoggerConfiguration GetConfiguration() { string minimumLogLevel = ConfigurationHelper.GetMixERPParameter("MinimumLogLevel"); LoggingLevelSwitch levelSwitch = new LoggingLevelSwitch(); LogEventLevel logLevel; Enum.TryParse(minimumLogLevel, out logLevel); levelSwitch.MinimumLevel = logLevel; return new LoggerConfiguration().MinimumLevel.ControlledBy(levelSwitch) .WriteTo.RollingFile(this.GetLogFileName()); }
protected override async Task EmitBatchAsync(IEnumerable<LogEvent> events) { _nextRequiredLevelCheckUtc = DateTime.UtcNow.Add(RequiredLevelCheckInterval); var payload = new StringWriter(); payload.Write("{\"Events\":["); var delimStart = ""; foreach (var logEvent in events) { if (_eventBodyLimitBytes.HasValue) { var scratch = new StringWriter(); RawJsonFormatter.FormatContent(logEvent, scratch); var buffered = scratch.ToString(); if (Encoding.UTF8.GetByteCount(buffered) > _eventBodyLimitBytes.Value) { SelfLog.WriteLine("Event JSON representation exceeds the byte size limit of {0} set for this sink and will be dropped; data: {1}", _eventBodyLimitBytes, buffered); } else { payload.Write(delimStart); payload.Write(buffered); delimStart = ","; } } else { payload.Write(delimStart); RawJsonFormatter.FormatContent(logEvent, payload); delimStart = ","; } } payload.Write("]}"); var content = new StringContent(payload.ToString(), Encoding.UTF8, "application/json"); if (!string.IsNullOrWhiteSpace(_apiKey)) content.Headers.Add(ApiKeyHeaderName, _apiKey); var result = await _httpClient.PostAsync(BulkUploadResource, content).ConfigureAwait(false); if (!result.IsSuccessStatusCode) throw new LoggingFailedException($"Received failed result {result.StatusCode} when posting events to Seq"); var returned = await result.Content.ReadAsStringAsync(); var minimumAcceptedLevel = SeqApi.ReadEventInputResult(returned); if (minimumAcceptedLevel == null) { if (_levelControlSwitch != null) _levelControlSwitch.MinimumLevel = LevelAlias.Minimum; } else { if (_levelControlSwitch == null) _levelControlSwitch = new LoggingLevelSwitch(minimumAcceptedLevel.Value); else _levelControlSwitch.MinimumLevel = minimumAcceptedLevel.Value; } }
public LevelOverride(string context, LoggingLevelSwitch levelSwitch) { Context = context; ContextPrefix = context + "."; LevelSwitch = levelSwitch; }
/// <summary> /// Sets the minimum level to be dynamically controlled by the provided switch. /// </summary> /// <param name="levelSwitch">The switch.</param> /// <returns>Configuration object allowing method chaining.</returns> public LoggerConfiguration ControlledBy(LoggingLevelSwitch levelSwitch) { if (levelSwitch == null) throw new ArgumentNullException("levelSwitch"); _setLevelSwitch(levelSwitch); return _loggerConfiguration; }
public void DynamicallySwitchingSinkRestrictsOutput() { var eventsReceived = 0; var levelSwitch = new LoggingLevelSwitch(); var logger = new LoggerConfiguration() .WriteTo.Sink( new DelegatingSink(e => eventsReceived++), levelSwitch: levelSwitch) .CreateLogger(); logger.Write(Some.InformationEvent()); levelSwitch.MinimumLevel = LogEventLevel.Warning; logger.Write(Some.InformationEvent()); levelSwitch.MinimumLevel = LogEventLevel.Verbose; logger.Write(Some.InformationEvent()); Assert.Equal(2, eventsReceived); }
/// <summary> /// Override the minimum level for events from a specific namespace or type name. /// </summary> /// <param name="source">The (partial) namespace or type name to set the override for.</param> /// <param name="levelSwitch">The switch controlling loggers for matching sources.</param> /// <returns>Configuration object allowing method chaining.</returns> public LoggerConfiguration Override(string source, LoggingLevelSwitch levelSwitch) { if (source == null) throw new ArgumentNullException(nameof(source)); if (levelSwitch == null) throw new ArgumentNullException(nameof(levelSwitch)); var trimmed = source.Trim(); if (trimmed.Length == 0) throw new ArgumentException("A source name must be provided.", nameof(source)); _addOverride(trimmed, levelSwitch); return _loggerConfiguration; }
public MinimumLevelSwitchCommand( LoggingLevelSwitch controller ) { Controller = controller; }