public void NullShouldBeLoggedAsEmpty() { var output = ""; using var logAdministrator = LogAdministrator.CreateNew(); logAdministrator.AddCustomDestination(new DestinationMock(msg => output = msg.Message)); var log = logAdministrator.GetLogger("default"); // null as args -> nothing will be parsed log.Info("This is null: {var}.", null); Assert.Contains("This is null: {var}.", output); output = ""; log.Info("This is null: {null}.", default(DestinationMock)); Assert.Contains("This is null: .", output); output = ""; log.Info("This is one {one} and this is null: {null}.", 1, null); Assert.Contains("This is one 1 and this is null: .", output); output = ""; log.Info("This is one {one} and this is null: {null:D3}.", 1, null); Assert.Contains("This is one 1 and this is null: .", output); var now = DateTime.Now; var formattedNow = now.ToString("yyyy-MM-dd HH:mm:ss.fff"); output = ""; log.Info("This is a time: {time:yyyy-MM-dd HH:mm:ss.fff}", now); Assert.Contains($"This is a time: {formattedNow}", output); }
public void ScopesMustNotBeSharedBetweenThreads() { var error = false; using (var logAdministrator = LogAdministrator.CreateNew()) { logAdministrator.SetLogLevel(LogLevel.Info) .AddCustomDestination(new DestinationMock((msg) => { if (Environment.CurrentManagedThreadId != (int)msg.State) { error = true; } })); void Action() { var log = logAdministrator.GetLogger("test"); using (log.BeginScope(Environment.CurrentManagedThreadId)) { for (var i = 0; i < 10; i++) { log.Info(""); } } } var actions = Enumerable.Range(0, 20).Select <int, Action>(i => Action).ToArray(); Parallel.Invoke(actions); } Assert.False(error); }
public void HttpDestinationTest() { var config = ConfigurationReader.ReadConfiguration <HttpDestinationConfig>(); if (config == null) { return; } LogConfigurationMapper.Instance.AddToMapping <HttpDestination>(); using var admin = LogAdministrator.CreateNew(); admin .SetLogLevel(LogLevel.Debug) .SetCollectMiddleware <ConcurrentCollectMiddleware, HttpDestination>() .AddMiddleware <JsonFormatMiddleware, HttpDestination>() .AddHttpDestination(config.Url, config.Token); var logger = admin.GetLogger(typeof(HttpDestinationTests)); foreach (var i in Enumerable.Range(0, 500)) { logger.Info(i); } }
public static ILoggingBuilder AddNajlotLog(this ILoggingBuilder builder, Action <LogAdministrator> configure) { var admin = LogAdministrator.CreateNew(); configure(admin); return(builder.AddNajlotLog(admin)); }
public void DestinationExceptionsShouldGoToErrorHandler() { var gotError = false; void DestinationErrorOccured(object sender, LogErrorEventArgs e) { gotError = true; } LogErrorHandler.Instance.ErrorOccured += DestinationErrorOccured; try { using var logAdministrator = LogAdministrator.CreateNew(); logAdministrator.AddCustomDestination(new DestinationMock((message) => throw new System.Exception())); Assert.False(gotError); logAdministrator.GetLogger(GetType()).Info(""); Assert.True(gotError); } finally { LogErrorHandler.Instance.ErrorOccured -= DestinationErrorOccured; } }
public static ILoggerFactory AddNajlotLog(this ILoggerFactory loggerFactory, Action <LogAdministrator> configure) { var admin = LogAdministrator.CreateNew(); configure(admin); return(loggerFactory.AddNajlotLog(admin)); }
public void StructuredLoggingMustParseCorrect() { var output = ""; using var logAdministrator = LogAdministrator.CreateNew(); logAdministrator.AddCustomDestination(new DestinationMock(msg => output = msg.Message)); var log = logAdministrator.GetLogger("default"); log.Info("User {User} logon from {IP}", "admin", "127.0.0.1"); Assert.Contains("User admin logon from 127.0.0.1", output); output = ""; log.Info("User {User} logon. {User} comes from ip {IP}", "admin", "127.0.0.1"); Assert.Contains("User admin logon. admin comes from ip 127.0.0.1", output); output = ""; log.Info("All users logged out. Going into idle mode."); Assert.Contains("All users logged out. Going into idle mode.", output); output = ""; log.Info("{count} users {{logged} out. Going into idle mode.", 10); Assert.Contains("10 users {logged} out. Going into idle mode.", output); output = ""; log.Info("User {User} logon from {}", "admin", "127.0.0.1"); Assert.Contains("User admin logon from 127.0.0.1", output); output = ""; log.Info("User {User} logon from {ip}", "admin"); Assert.Contains("User admin logon from ", output); output = ""; log.Info("{{User} {User} logon", "admin"); Assert.Contains("{User} admin logon", output); output = ""; log.Info("User {{{User}} logon from {IP}", "admin", "127.0.0.1"); Assert.Contains("User {admin} logon from 127.0.0.1", output); output = ""; log.Info("ip {", "127.0.0.1"); Assert.Contains("ip {", output); output = ""; log.Info("ip: {ip} {", "127.0.0.1"); Assert.Contains("ip: 127.0.0.1 {", output); output = ""; log.Info("", 1, 2, 3); Assert.Contains(LogLevel.Info.ToString().ToUpper(), output); output = ""; log.Info("{{", 1, 2, 3); Assert.Contains(LogLevel.Info.ToString().ToUpper(), output); }
public void CheckIsLogLevelEnabled() { using var logAdministrator = LogAdministrator.CreateNew(); logAdministrator.SetLogLevel(LogLevel.Warn); var logger = logAdministrator.GetLogger(GetType()); Assert.False(logger.IsEnabled(LogLevel.Info)); Assert.True(logger.IsEnabled(LogLevel.Warn)); Assert.True(logger.IsEnabled(LogLevel.Error)); }
public void NullMessageShouldNotThrowExceptions() { using var logAdministrator = LogAdministrator.CreateNew(); logAdministrator.AddCustomDestination(new DestinationMock(msg => _ = msg.Message)); var log = logAdministrator.GetLogger("default"); // log null variables must not produce exceptions log.Info(null); log.Info(default(string), 0); }
public void LoggerMustLogObjectAndExceptionWithCorrectLogLevel() { var gotLogMessage = false; var ex = new Exception("Something bad happened!"); using var logAdministrator = LogAdministrator.CreateNew(); logAdministrator .SetLogLevel(LogLevel.Fatal) .AddCustomDestination(new DestinationMock(msg => { gotLogMessage = true; })); var log = logAdministrator.GetLogger(GetType()); var obj = new object(); foreach (var logLevel in _logLevels) { logAdministrator.SetLogLevel(logLevel); var shouldGetMessage = logLevel <= LogLevel.Trace; log.Trace(ex, obj); Assert.True(gotLogMessage == shouldGetMessage, $"{logLevel}, but did not got Trace message"); gotLogMessage = false; shouldGetMessage = logLevel <= LogLevel.Debug; log.Debug(ex, obj); Assert.True(gotLogMessage == shouldGetMessage, $"{logLevel}, but did not got Debug message"); gotLogMessage = false; shouldGetMessage = logLevel <= LogLevel.Info; log.Info(ex, obj); Assert.True(gotLogMessage == shouldGetMessage, $"{logLevel}, but did not got Info message"); gotLogMessage = false; shouldGetMessage = logLevel <= LogLevel.Warn; log.Warn(ex, obj); Assert.True(gotLogMessage == shouldGetMessage, $"{logLevel}, but did not got Warn message"); gotLogMessage = false; shouldGetMessage = logLevel <= LogLevel.Error; log.Error(ex, obj); Assert.True(gotLogMessage == shouldGetMessage, $"{logLevel}, but did not got Error message"); gotLogMessage = false; shouldGetMessage = logLevel <= LogLevel.Fatal; log.Fatal(ex, obj); Assert.True(gotLogMessage == shouldGetMessage, $"{logLevel}, but did not got Fatal message"); gotLogMessage = false; } }
public void Only_one() { LogMessage message = null; using var logAdministrator = LogAdministrator.CreateNew(); logAdministrator.AddMiddleware <AddToArgsMiddlewareMock1, DestinationMock>(); logAdministrator.AddCustomDestination(new DestinationMock((msg) => { message = msg; })); var logger = logAdministrator.GetLogger(""); logger.Fatal("{Nr}"); Assert.Equal("1", message.RawArguments[0].ToString()); }
public void NestedScopesMustBeLogged() { var scopesAreCorrect = true; object state = null; using var logAdministrator = LogAdministrator.CreateNew(); logAdministrator.AddCustomDestination(new DestinationMock((msg) => { if (!scopesAreCorrect) { return; } state = msg.State; scopesAreCorrect = msg.RawMessage == state?.ToString(); })); var log = logAdministrator.GetLogger(GetType()); using (log.BeginScope("scope 1")) { log.Info("scope 1"); using (log.BeginScope("scope 2")) { log.Info("scope 2"); log.Info("scope 2"); using (log.BeginScope("scope 3")) { log.Info("scope 3"); } log.Info("scope 2"); } log.Info("scope 1"); } Assert.True(scopesAreCorrect, "scopes are not correct"); log.Info("out of scope"); Assert.Null(state); }
public void CachingShouldNotBreakFollowing() { string output; using var logAdministrator = LogAdministrator.CreateNew(); logAdministrator.AddCustomDestination(new DestinationMock(msg => output = msg.Message)); var log = logAdministrator.GetLogger("default"); log.Info("User {user_id} writes Order {order_id} into DB."); output = ""; log.Info("User {user_id} writes Order {order_id} into DB.", "U123"); Assert.Contains("User U123 writes Order into DB.", output); output = ""; log.Info("User {user_id} writes Order {order_id} into DB.", "U123", 5243); Assert.Contains("User U123 writes Order 5243 into DB.", output); output = ""; log.Info("User {user_id} writes Order {order_id} into DB.", null, null); Assert.Contains("User writes Order into DB.", output); output = ""; log.Info("User {user_id} writes Order {order_id} into DB.", "U123"); Assert.Contains("User U123 writes Order into DB.", output); output = ""; log.Info("User {user_id} writes Order {order_id} into DB."); Assert.Contains("User {user_id} writes Order {order_id} into DB.", output); output = ""; log.Info("User {user_id} writes Order {order_id} into DB.", 123, 456); Assert.Contains("User 123 writes Order 456 into DB.", output); output = ""; log.Info("User {user_id:D3} writes Order {order_id} into DB.", 1, 2); Assert.Contains("User 001 writes Order 2 into DB.", output); output = ""; log.Info("User {user_id:D3} writes Order {order_id} into DB.", "db", 2); Assert.Contains("User db writes Order 2 into DB.", output); }
public void LogConfigurationsShouldBeRead() { var configName = nameof(LogConfigurationsShouldBeRead) + ".config"; if (File.Exists(configName)) { File.Delete(configName); } using (var admin = LogAdministrator.CreateNew()) { admin .AddCustomDestination(new DestinationMock(m => { })) .SetCollectMiddleware <ConcurrentCollectMiddleware, DestinationMock>() .AddMiddleware <JsonFormatMiddleware, DestinationMock>() .ReadConfigurationFromXmlFile(configName, false, true); } Assert.True(File.Exists(configName)); using (var admin = LogAdministrator.CreateNew()) { var name = LogConfigurationMapper.Instance.GetName <DestinationMock>(); var concurrentCollectMiddlewareName = LogConfigurationMapper.Instance.GetName <ConcurrentCollectMiddleware>(); var jsonFormatMiddlewareName = LogConfigurationMapper.Instance.GetName <JsonFormatMiddleware>(); admin .AddCustomDestination(new DestinationMock(m => { })) .GetCollectMiddlewareName(name, out var collectMiddlewareName); // Standard should not be ConcurrentCollectMiddleware Assert.NotEqual(concurrentCollectMiddlewareName, collectMiddlewareName); admin .ReadConfigurationFromXmlFile(configName, true, false) .GetCollectMiddlewareName(name, out collectMiddlewareName) .GetMiddlewareNames(name, out var middlewareNames); Assert.Equal(concurrentCollectMiddlewareName, collectMiddlewareName); Assert.Equal(jsonFormatMiddlewareName, middlewareNames.First(n => n == jsonFormatMiddlewareName)); } }
public void With_Configuration_File() { LogMessage message = null; const string path = "AddToArgsMiddlewareMock1And2.config"; using (var logAdministrator = LogAdministrator.CreateNew()) { logAdministrator.SetCollectMiddleware <ConcurrentCollectMiddleware, DestinationMock>(); logAdministrator.AddMiddleware <AddToArgsMiddlewareMock1, DestinationMock>(); logAdministrator.AddMiddleware <AddToArgsMiddlewareMock2, DestinationMock>(); logAdministrator.AddCustomDestination(new DestinationMock((msg) => { })); if (File.Exists(path)) { File.Delete(path); } logAdministrator.ReadConfigurationFromXmlFile(path, false, true); } using (var logAdministrator = LogAdministrator.CreateNew()) { var logger = logAdministrator.GetLogger(""); logAdministrator.ReadConfigurationFromXmlFile(path, false, false); logAdministrator.AddCustomDestination(new DestinationMock((msg) => { message = msg; })); logger.Fatal("{Nr2}{Nr1}"); logAdministrator.GetCollectMiddlewareName(nameof(DestinationMock), out var collectMiddlewareName); Assert.Equal(nameof(ConcurrentCollectMiddleware), collectMiddlewareName); } Assert.Equal("1", message.RawArguments[0].ToString()); Assert.Equal("2", message.RawArguments[1].ToString()); }
public void StructuredLoggingMustFormatCorrect() { var output = ""; using var logAdministrator = LogAdministrator.CreateNew(); logAdministrator.AddCustomDestination(new DestinationMock(msg => output = msg.Message)); var log = logAdministrator.GetLogger("default"); log.Info("Number of users: {users:D3}", 50); Assert.Contains("Number of users: 050", output); output = ""; log.Info("Three digits {num:D3} and five {num:D5}", 50); Assert.Contains("Three digits 050 and five 00050", output); output = ""; log.Info("Three and five digits {num:D3}{num2:D5}", 50, 60); Assert.Contains("Three and five digits 05000060", output); }
public void MiddlewareCreationExceptionsShouldGoToErrorHandler() { var gotError = false; void CreationErrorOccured(object sender, LogErrorEventArgs e) { gotError = true; } LogErrorHandler.Instance.ErrorOccured += CreationErrorOccured; using (var logAdministrator = LogAdministrator.CreateNew()) { logAdministrator.AddCustomDestination(new DestinationMock((message) => { })); Assert.False(gotError); logAdministrator.AddMiddleware <CtorExceptionThrowingMiddleware, DestinationMock>(); Assert.True(gotError); } LogErrorHandler.Instance.ErrorOccured -= CreationErrorOccured; }
public void After_collection_middleware_added() { LogMessage message = null; using (var logAdministrator = LogAdministrator.CreateNew()) { logAdministrator.SetCollectMiddleware <ConcurrentCollectMiddleware, DestinationMock>(); logAdministrator.AddMiddleware <AddToArgsMiddlewareMock2, DestinationMock>(); logAdministrator.AddMiddleware <AddToArgsMiddlewareMock1, DestinationMock>(); logAdministrator.AddCustomDestination(new DestinationMock((msg) => { message = msg; })); logAdministrator.GetLogger("").Fatal("{Nr2}{Nr1}"); } Assert.Equal("2", message.RawArguments[0].ToString()); Assert.Equal("1", message.RawArguments[1].ToString()); }
public void DestinationConfigurationShouldBeWrittenCorrect() { using var logAdministrator = LogAdministrator.CreateNew(); var destination = new FileDestination(); logAdministrator.AddCustomDestination(destination); var fileDestinationConfiguration = new Dictionary <string, string> { ["OutputPath"] = "my test path", ["KeepFileOpen"] = "true", ["MaxFiles"] = "10", ["LogFilesPath"] = null }; logAdministrator.SetDestinationConfiguration(nameof(FileDestination), fileDestinationConfiguration); Assert.Equal("my test path", destination.OutputPath); Assert.True(destination.KeepFileOpen); Assert.Equal(10, destination.MaxFiles); Assert.Null(destination.LogFilesPath); }
public void ScopesMustNotBeSharedBetweenThreadsInTask() { var error = false; using (var logAdministrator = LogAdministrator.CreateNew()) { logAdministrator.SetLogLevel(LogLevel.Info) .AddCustomDestination(new DestinationMock((msg) => { // state must be the same thread id the message comes from if (msg.RawMessage != msg.State.ToString()) { error = true; } })); void Action() { Task.Factory.StartNew(() => { var log = logAdministrator.GetLogger("test"); using (log.BeginScope(Environment.CurrentManagedThreadId)) { for (var i = 0; i < 10; i++) { log.Info(Environment.CurrentManagedThreadId); } } }).Wait(); } var actions = Enumerable.Range(0, 20).Select <int, Action>(i => Action).ToArray(); Parallel.Invoke(actions); } Assert.False(error); }
public void DestinationConfigurationShouldBeReadCorrect() { using var logAdministrator = LogAdministrator.CreateNew(); logAdministrator.AddConsoleDestination(true); logAdministrator.AddFileDestination("my logfile path", 123); logAdministrator.GetDestinationConfiguration(nameof(ConsoleDestination), out var consoleDestinationConfiguration); Assert.Equal(1, consoleDestinationConfiguration.Count); Assert.Contains("UseColors", consoleDestinationConfiguration.Keys); logAdministrator.GetDestinationConfiguration(nameof(FileDestination), out var fileDestinationConfiguration); Assert.Equal(4, fileDestinationConfiguration.Count); Assert.Contains("OutputPath", fileDestinationConfiguration.Keys); Assert.Contains("KeepFileOpen", fileDestinationConfiguration.Keys); Assert.Contains("MaxFiles", fileDestinationConfiguration.Keys); Assert.Contains("LogFilesPath", fileDestinationConfiguration.Keys); Assert.Equal("my logfile path", fileDestinationConfiguration["OutputPath"]); Assert.False(bool.Parse(fileDestinationConfiguration["KeepFileOpen"])); Assert.Equal(123, int.Parse(fileDestinationConfiguration["MaxFiles"])); Assert.Null(fileDestinationConfiguration["LogFilesPath"]); }
public void LogConfigurationsShouldBeListenedTo() { const string configName = nameof(LogConfigurationsShouldBeListenedTo) + ".config"; if (File.Exists(configName)) { File.Delete(configName); } using (var admin = LogAdministrator.CreateNew()) { admin .AddCustomDestination(new DestinationMock(m => { })) .SetCollectMiddleware <ConcurrentCollectMiddleware, DestinationMock>() .AddMiddleware <JsonFormatMiddleware, DestinationMock>() .ReadConfigurationFromXmlFile(configName, false, true); } Assert.True(File.Exists(configName)); using (var admin = LogAdministrator.CreateNew()) { var name = LogConfigurationMapper.Instance.GetName <DestinationMock>(); var concurrentCollectMiddlewareName = LogConfigurationMapper.Instance.GetName <ConcurrentCollectMiddleware>(); var jsonFormatMiddlewareName = LogConfigurationMapper.Instance.GetName <JsonFormatMiddleware>(); var formatMiddlewareName = LogConfigurationMapper.Instance.GetName <FormatMiddleware>(); admin .AddCustomDestination(new DestinationMock(m => { })) .GetCollectMiddlewareName(name, out var collectMiddlewareName); // Standard should not be ConcurrentCollectMiddleware Assert.NotEqual(concurrentCollectMiddlewareName, collectMiddlewareName); admin .ReadConfigurationFromXmlFile(configName, true, false) .GetCollectMiddlewareName(name, out collectMiddlewareName) .GetMiddlewareNames(name, out var middlewareName); Assert.Equal(concurrentCollectMiddlewareName, collectMiddlewareName); Assert.Equal(jsonFormatMiddlewareName, middlewareName.First(n => n == jsonFormatMiddlewareName)); var content = File.ReadAllText(configName); var syncCollectMiddlewareName = LogConfigurationMapper.Instance.GetName <SyncCollectMiddleware>(); content = content .Replace(concurrentCollectMiddlewareName, syncCollectMiddlewareName) .Replace(jsonFormatMiddlewareName, formatMiddlewareName) .Replace(LogLevel.Debug.ToString(), LogLevel.Trace.ToString()); File.WriteAllText(configName, content); var endTime = DateTime.Now.AddSeconds(5); while (DateTime.Now < endTime && admin.GetCollectMiddlewareName(name, out collectMiddlewareName) != null && collectMiddlewareName == concurrentCollectMiddlewareName) { Thread.Sleep(25); } admin .GetCollectMiddlewareName(name, out collectMiddlewareName) .GetLogLevel(out var logLevel) .GetMiddlewareNames(name, out var middlewareNames); Assert.Equal(syncCollectMiddlewareName, collectMiddlewareName); Assert.Equal(LogLevel.Trace, logLevel); Assert.Equal(formatMiddlewareName, middlewareNames.First(n => n == formatMiddlewareName)); } }