diff --git a/EonaCat.Logger/EonaCatCoreLogger/FileLoggerProvider.cs b/EonaCat.Logger/EonaCatCoreLogger/FileLoggerProvider.cs index b3bd064..bba28e7 100644 --- a/EonaCat.Logger/EonaCatCoreLogger/FileLoggerProvider.cs +++ b/EonaCat.Logger/EonaCatCoreLogger/FileLoggerProvider.cs @@ -243,6 +243,8 @@ public sealed class FileLoggerProvider : BatchingLoggerProvider private string BuildMessage(LogMessage msg) { + var settings = msg.Settings ?? LoggerSettings; + if (!IncludeCorrelationId) { return msg.Message + Environment.NewLine; @@ -281,6 +283,7 @@ public sealed class FileLoggerProvider : BatchingLoggerProvider } state.Stream.Write(state.Buffer, 0, state.BufferPosition); + state.Stream.Flush(); state.BufferPosition = 0; } @@ -339,7 +342,7 @@ public sealed class FileLoggerProvider : BatchingLoggerProvider FlushBuffer(state); state.Stream?.Dispose(); } - catch + catch { // Do nothing during shutdown flush } diff --git a/EonaCat.Logger/EonaCatCoreLogger/Internal/BatchingLogger.cs b/EonaCat.Logger/EonaCatCoreLogger/Internal/BatchingLogger.cs index 768de82..1f2af09 100644 --- a/EonaCat.Logger/EonaCatCoreLogger/Internal/BatchingLogger.cs +++ b/EonaCat.Logger/EonaCatCoreLogger/Internal/BatchingLogger.cs @@ -12,10 +12,7 @@ namespace EonaCat.Logger.EonaCatCoreLogger.Internal private readonly BatchingLoggerProvider _provider; private readonly LoggerSettings _settings; - public BatchingLogger( - BatchingLoggerProvider provider, - string category, - LoggerSettings settings) + public BatchingLogger(BatchingLoggerProvider provider, string category, LoggerSettings settings) { _provider = provider ?? throw new ArgumentNullException(nameof(provider)); _category = category ?? throw new ArgumentNullException(nameof(category)); @@ -54,28 +51,39 @@ namespace EonaCat.Logger.EonaCatCoreLogger.Internal { var timestamp = Now; + // Use the settings from the LogMessage if available + LoggerSettings effectiveSettings = (_settings); + string category = _category; + + if (state is LogMessage logMessage && logMessage.Settings != null) + { + effectiveSettings = logMessage.Settings; + if (!string.IsNullOrWhiteSpace(logMessage.Category)) + { + category = logMessage.Category; + } + } + string formatted = LogHelper.FormatMessageWithHeader( - _settings, + effectiveSettings, logLevel.FromLogLevel(), rawMessage, timestamp.DateTime, - _category); + category); - var writtenMessage = _provider.AddMessage(timestamp, formatted, _category); + var writtenMessage = _provider.AddMessage(timestamp, formatted, category); - _settings?.RaiseOnLog(new EonaCatLogMessage + effectiveSettings?.RaiseOnLog(new EonaCatLogMessage { DateTime = timestamp.DateTime, Message = writtenMessage, LogType = logLevel.FromLogLevel(), - Category = _category, + Category = category, Exception = exception, - Origin = string.IsNullOrWhiteSpace(_settings.LogOrigin) + Origin = string.IsNullOrWhiteSpace(effectiveSettings.LogOrigin) ? "BatchingLogger" - : _settings.LogOrigin + : effectiveSettings.LogOrigin }); - - } catch (Exception ex) { diff --git a/EonaCat.Logger/EonaCatCoreLogger/Internal/BatchingLoggerProvider.cs b/EonaCat.Logger/EonaCatCoreLogger/Internal/BatchingLoggerProvider.cs index 7c55e65..6f62385 100644 --- a/EonaCat.Logger/EonaCatCoreLogger/Internal/BatchingLoggerProvider.cs +++ b/EonaCat.Logger/EonaCatCoreLogger/Internal/BatchingLoggerProvider.cs @@ -88,11 +88,13 @@ public abstract class BatchingLoggerProvider : ILoggerProvider, IDisposable } - private LogMessage CreateLogMessage(string message, DateTimeOffset ts, string category) + private LogMessage CreateLogMessage(string message, DateTimeOffset ts, string category, LoggerSettings? settings = null) { - if (LoggerSettings.UseMask) + var effectiveSettings = settings ?? LoggerSettings; + + if (effectiveSettings.UseMask) { - var masker = new SensitiveDataMasker(LoggerSettings); + var masker = new SensitiveDataMasker(effectiveSettings); message = masker.MaskSensitiveInformation(message); } @@ -100,7 +102,8 @@ public abstract class BatchingLoggerProvider : ILoggerProvider, IDisposable { Message = message, Timestamp = ts, - Category = category + Category = category, + Settings = effectiveSettings }; } diff --git a/EonaCat.Logger/EonaCatCoreLogger/Internal/LogMessage.cs b/EonaCat.Logger/EonaCatCoreLogger/Internal/LogMessage.cs index 76d964d..f2e30cb 100644 --- a/EonaCat.Logger/EonaCatCoreLogger/Internal/LogMessage.cs +++ b/EonaCat.Logger/EonaCatCoreLogger/Internal/LogMessage.cs @@ -1,4 +1,5 @@ -using System; +using EonaCat.Logger.Managers; +using System; namespace EonaCat.Logger.EonaCatCoreLogger.Internal; // This file is part of the EonaCat project(s) which is released under the Apache License. @@ -10,4 +11,5 @@ public struct LogMessage public string Message { get; set; } public string Category { get; set; } public int EstimatedSize { get; set; } + public LoggerSettings? Settings { get; set; } } \ No newline at end of file diff --git a/EonaCat.Logger/Managers/LogHelper.cs b/EonaCat.Logger/Managers/LogHelper.cs index 7c89a26..60b2827 100644 --- a/EonaCat.Logger/Managers/LogHelper.cs +++ b/EonaCat.Logger/Managers/LogHelper.cs @@ -1,4 +1,5 @@ using EonaCat.Json; +using EonaCat.Logger.EonaCatCoreLogger.Internal; using EonaCat.Logger.Extensions; using EonaCat.Logger.Servers.GrayLog; using EonaCat.Logger.Servers.Splunk.Models; @@ -8,6 +9,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Net; +using System.Reflection; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; @@ -51,10 +53,9 @@ public static class LogHelper internal static string ConvertToSyslogRfc5424(LoggerSettings settings, ELogType logType, string currentMessage, DateTime dateTime, string category = null) { - string formattedMessage = FormatMessageWithHeader(settings, logType, currentMessage, dateTime, category); - if (string.IsNullOrWhiteSpace(formattedMessage)) + if (string.IsNullOrWhiteSpace(currentMessage)) { - return formattedMessage; + return currentMessage; } string hostname = HostName; @@ -63,22 +64,21 @@ public static class LogHelper int severity = (int)logType; int pri = (facility * 8) + severity; string timestamp = dateTime.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"); - var syslogMessage = $"<{pri}>1 {timestamp} {hostname} - - {formattedMessage}"; + var syslogMessage = $"<{pri}>1 {timestamp} {hostname} - - {currentMessage}"; if (settings?.Id != null) { - syslogMessage = $"<{pri}>1 {timestamp} {hostname} {settings?.Id} - - {formattedMessage}"; + syslogMessage = $"<{pri}>1 {timestamp} {hostname} {settings?.Id} - - {currentMessage}"; } - syslogMessage = $"<{pri}>1 {timestamp} {hostname} - - {formattedMessage}"; + syslogMessage = $"<{pri}>1 {timestamp} {hostname} - - {currentMessage}"; return syslogMessage; } internal static string ConvertToSyslogRfc3164(LoggerSettings settings, ELogType logType, string currentMessage, DateTime dateTime, string category = null) { - string formattedMessage = FormatMessageWithHeader(settings, logType, currentMessage, dateTime, category); - if (string.IsNullOrWhiteSpace(formattedMessage)) + if (string.IsNullOrWhiteSpace(currentMessage)) { - return formattedMessage; + return currentMessage; } string hostname = HostName; @@ -86,7 +86,7 @@ public static class LogHelper int severity = (int)logType; int pri = (facility * 8) + severity; string timestamp = dateTime.ToString("MMM dd HH:mm:ss"); - string syslogMessage = $"<{pri}>{timestamp} {hostname} {settings?.Id ?? DllInfo.ApplicationName}: {formattedMessage}"; + string syslogMessage = $"<{pri}>{timestamp} {hostname} {settings?.Id ?? DllInfo.ApplicationName}: {currentMessage}"; return syslogMessage; } @@ -224,15 +224,30 @@ public static class LogHelper internal static void SendToFile(ILogger logger, LoggerSettings settings, ELogType logType, string message) { - if (logger == null || settings == null || !settings.EnableFileLogging || string.IsNullOrWhiteSpace(message)) + if (logger == null || settings == null || string.IsNullOrWhiteSpace(message)) { return; } - if (IsLogLevelEnabled(settings, logType)) + if (!IsLogLevelEnabled(settings, logType)) { - Log(logger, logType.ToLogLevel(), message); + return; } + + var logMessage = new LogMessage + { + Message = message, + Timestamp = DateTimeOffset.Now, + Category = settings.FileLoggerOptions.Category, + Settings = settings + }; + + logger.Log( + logType.ToLogLevel(), + eventId: default, + state: logMessage, + exception: null, + formatter: (state, ex) => state.Message); } private static bool IsLogLevelEnabled(LoggerSettings loggerSettings, ELogType logType) diff --git a/EonaCat.Logger/Managers/LogManager.cs b/EonaCat.Logger/Managers/LogManager.cs index 12fab58..222d692 100644 --- a/EonaCat.Logger/Managers/LogManager.cs +++ b/EonaCat.Logger/Managers/LogManager.cs @@ -15,6 +15,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; +using System.Runtime; using System.Threading; using System.Threading.Tasks; @@ -31,24 +32,26 @@ namespace EonaCat.Logger.Managers private bool _isDisposing; private string _category; - public LogManager(LoggerSettings settings, string category = null) + public LogManager(LoggerSettings settings = null, string category = null) { Settings = settings ?? CreateDefaultSettings(); - _category = string.IsNullOrWhiteSpace(category) ? null : category; - _category = settings.FileLoggerOptions.Category; - if (string.IsNullOrEmpty(_category)) + _category = !string.IsNullOrWhiteSpace(category) + ? category + : Settings.FileLoggerOptions.Category; + + if (string.IsNullOrWhiteSpace(Settings.FileLoggerOptions.Category)) { - _category = category; - settings.FileLoggerOptions.Category = _category; + Settings.FileLoggerOptions.Category = _category ?? DllInfo.ApplicationName; } SetupLogManager(); - SetupFileLogger(settings); + SetupFileLogger(Settings); - // Subscribe to static events LogHelper.OnException += LogHelper_OnException; LogHelper.OnLogLevelDisabled += LogHelper_OnLogLevelDisabled; + + CreateLogger(_category); } public static LogManager Instance => _instance.Value; @@ -172,13 +175,7 @@ namespace EonaCat.Logger.Managers private void CreateLogger(string categoryName = null) { - if (Logger != null) - { - // already created - return; - } - - if (_isDisposing) + if (Logger != null || _isDisposing) { return; } @@ -186,7 +183,8 @@ namespace EonaCat.Logger.Managers LoggerProvider?.Dispose(); LoggerFactory?.Dispose(); - IServiceCollection serviceCollection = new ServiceCollection(); + var serviceCollection = new ServiceCollection(); + serviceCollection.AddSingleton(Settings); if (Settings.TypesToLog == null || !Settings.TypesToLog.Any()) { @@ -197,20 +195,22 @@ namespace EonaCat.Logger.Managers }; } + // Add logging serviceCollection.AddLogging(builder => builder.SetMinimumLevel(Settings.TypesToLog.Max().ToLogLevel()) - .AddEonaCatFileLogger(options => - { - LoggerConfigurator.ApplyFileLoggerSettings(options, Settings.FileLoggerOptions); - })); + .AddEonaCatFileLogger(options => + LoggerConfigurator.ApplyFileLoggerSettings(options, Settings.FileLoggerOptions) + )); + + var serviceProvider = serviceCollection.BuildServiceProvider(); + LoggerProvider = serviceProvider.GetRequiredService(); + LoggerFactory = serviceProvider.GetRequiredService(); + Logger = LoggerFactory.CreateLogger(categoryName ?? Settings.Id); - var serviceProvider = serviceCollection.BuildServiceProvider(); - LoggerProvider = serviceProvider.GetService(); - LoggerFactory = serviceProvider.GetService(); - Logger = LoggerFactory.CreateLogger(_category ?? Settings.Id); LogHelper.SendToFile(Logger, Settings, ELogType.INFO, LogHelper.GetStartupMessage()); } + private async Task InternalWriteAsync(DateTime dateTime, string message, ELogType logType = ELogType.INFO, bool? writeToConsole = null, string customSplunkSourceType = null, string grayLogFacility = null, string grayLogSource = null, string grayLogVersion = "1.1", bool disableSplunkSSL = false) @@ -228,7 +228,7 @@ namespace EonaCat.Logger.Managers var messageWithHeader = LogHelper.FormatMessageWithHeader(Settings, logType, message, dateTime, _category); var writeToConsoleValue = writeToConsole.GetValueOrDefault(Settings.EnableConsole); - // Send message without header to the fileProvider + // Send message to the fileProvider LogHelper.SendToFile(Logger, Settings, logType, message); if (writeToConsoleValue) @@ -238,7 +238,7 @@ namespace EonaCat.Logger.Managers var tasks = new List { - LogHelper.SendToSysLogServersAsync(Settings, message, logType, dateTime, _category), + LogHelper.SendToSysLogServersAsync(Settings, messageWithHeader, logType, dateTime, _category), LogHelper.SendToSplunkServersAsync(Settings, customSplunkSourceType ?? logType.ToString(), messageWithHeader, disableSplunkSSL), LogHelper.SendToGrayLogServersAsync(Settings, messageWithHeader, logType, grayLogFacility, grayLogSource, grayLogVersion), LogHelper.SendToTcpLogServersAsync(Settings, messageWithHeader, logType),