Updated
This commit is contained in:
@@ -25,9 +25,11 @@
|
|||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="EonaCat.Logger" Version="1.5.9" />
|
|
||||||
<PackageReference Include="System.Net.Http.Json" Version="10.0.1" />
|
<PackageReference Include="System.Net.Http.Json" Version="10.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\EonaCat.Logger\EonaCat.Logger.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Update="readme.md">
|
<None Update="readme.md">
|
||||||
<Pack>True</Pack>
|
<Pack>True</Pack>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using EonaCat.Logger.EonaCatCoreLogger.Internal;
|
using EonaCat.Logger.EonaCatCoreLogger.Internal;
|
||||||
|
using EonaCat.Logger.Managers;
|
||||||
|
|
||||||
namespace EonaCat.Logger.EonaCatCoreLogger;
|
namespace EonaCat.Logger.EonaCatCoreLogger;
|
||||||
// This file is part of the EonaCat project(s) which is released under the Apache License.
|
// This file is part of the EonaCat project(s) which is released under the Apache License.
|
||||||
@@ -144,4 +145,6 @@ public class FileLoggerOptions : BatchingLoggerOptions
|
|||||||
/// Determines if we need to include the correlation ID in the log (default: false)
|
/// Determines if we need to include the correlation ID in the log (default: false)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IncludeCorrelationId { get; set; }
|
public bool IncludeCorrelationId { get; set; }
|
||||||
|
public LoggerSettings Settings { get; internal set; }
|
||||||
|
public LoggerSettings LoggerSettings { get; internal set; }
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,6 @@ public class FileLoggerProvider : BatchingLoggerProvider
|
|||||||
foreach (var group in messages.GroupBy(GetGrouping))
|
foreach (var group in messages.GroupBy(GetGrouping))
|
||||||
{
|
{
|
||||||
LogFile = GetFullName(group.Key);
|
LogFile = GetFullName(group.Key);
|
||||||
|
|
||||||
var currentMessages = string.Join(string.Empty, group.Select(item =>
|
var currentMessages = string.Join(string.Empty, group.Select(item =>
|
||||||
{
|
{
|
||||||
if (IncludeCorrelationId)
|
if (IncludeCorrelationId)
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ namespace EonaCat.Logger.EonaCatCoreLogger.Internal
|
|||||||
{
|
{
|
||||||
private readonly string _category;
|
private readonly string _category;
|
||||||
private readonly BatchingLoggerProvider _provider;
|
private readonly BatchingLoggerProvider _provider;
|
||||||
private readonly LoggerSettings _loggerSettings;
|
private LoggerSettings _loggerSettings;
|
||||||
|
|
||||||
public BatchingLogger(BatchingLoggerProvider loggerProvider, string categoryName, LoggerSettings loggerSettings)
|
public BatchingLogger(BatchingLoggerProvider loggerProvider, string categoryName, LoggerSettings loggerSettings)
|
||||||
{
|
{
|
||||||
|
_loggerSettings = loggerSettings ?? throw new ArgumentNullException(nameof(loggerSettings));
|
||||||
_provider = loggerProvider ?? throw new ArgumentNullException(nameof(loggerProvider));
|
_provider = loggerProvider ?? throw new ArgumentNullException(nameof(loggerProvider));
|
||||||
_category = categoryName ?? throw new ArgumentNullException(nameof(categoryName));
|
_category = categoryName ?? throw new ArgumentNullException(nameof(categoryName));
|
||||||
_loggerSettings = loggerSettings ?? throw new ArgumentNullException(nameof(loggerSettings));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private DateTimeOffset CurrentDateTimeOffset => CurrentDateTime;
|
private DateTimeOffset CurrentDateTimeOffset => CurrentDateTime;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ public abstract class BatchingLoggerProvider : ILoggerProvider, IDisposable
|
|||||||
private CancellationTokenSource _cancellationTokenSource;
|
private CancellationTokenSource _cancellationTokenSource;
|
||||||
private Task _outputTask;
|
private Task _outputTask;
|
||||||
private bool _isDisposed;
|
private bool _isDisposed;
|
||||||
|
private LoggerSettings _loggerSettings;
|
||||||
|
|
||||||
protected BatchingLoggerProvider(IOptions<BatchingLoggerOptions> options)
|
protected BatchingLoggerProvider(IOptions<BatchingLoggerOptions> options)
|
||||||
{
|
{
|
||||||
@@ -40,6 +41,7 @@ public abstract class BatchingLoggerProvider : ILoggerProvider, IDisposable
|
|||||||
{
|
{
|
||||||
UseLocalTime = fileLoggerOptions.UseLocalTime;
|
UseLocalTime = fileLoggerOptions.UseLocalTime;
|
||||||
UseMask = fileLoggerOptions.UseMask;
|
UseMask = fileLoggerOptions.UseMask;
|
||||||
|
LoggerSettings = fileLoggerOptions.LoggerSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
_batchSize = loggerOptions.BatchSize > 0 ? loggerOptions.BatchSize : 100;
|
_batchSize = loggerOptions.BatchSize > 0 ? loggerOptions.BatchSize : 100;
|
||||||
@@ -51,30 +53,27 @@ public abstract class BatchingLoggerProvider : ILoggerProvider, IDisposable
|
|||||||
|
|
||||||
protected bool UseLocalTime { get; set; }
|
protected bool UseLocalTime { get; set; }
|
||||||
|
|
||||||
|
public bool IsStarted { get; set; }
|
||||||
|
public bool UseMask { get; set; }
|
||||||
|
public string Category { get; set; } = "General";
|
||||||
|
|
||||||
protected LoggerSettings LoggerSettings
|
protected LoggerSettings LoggerSettings
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_loggerSettings != null)
|
if (_loggerSettings == null)
|
||||||
{
|
{
|
||||||
return _loggerSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
_loggerSettings = new LoggerSettings();
|
_loggerSettings = new LoggerSettings();
|
||||||
_loggerSettings.UseLocalTime = UseLocalTime;
|
_loggerSettings.UseLocalTime = UseLocalTime;
|
||||||
_loggerSettings.UseMask = UseMask;
|
_loggerSettings.UseMask = UseMask;
|
||||||
|
//TODO: Add the tokens and custom tokens
|
||||||
|
}
|
||||||
return _loggerSettings;
|
return _loggerSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
set => _loggerSettings = value;
|
set => _loggerSettings = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsStarted { get; set; }
|
|
||||||
public bool UseMask { get; set; }
|
|
||||||
public string Category { get; set; } = "General";
|
|
||||||
|
|
||||||
private LoggerSettings _loggerSettings;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new logger instance for the specified category name.
|
/// Creates a new logger instance for the specified category name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -48,9 +48,6 @@ namespace EonaCat.Logger
|
|||||||
IsEnabled = true,
|
IsEnabled = true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
_logManager = new LogManager(LoggerSettings);
|
|
||||||
_logManager.Settings.TypesToLog.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -87,9 +84,20 @@ namespace EonaCat.Logger
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InitLogger();
|
||||||
await _logManager.WriteAsync(message, logType, writeToConsole).ConfigureAwait(false);
|
await _logManager.WriteAsync(message, logType, writeToConsole).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void InitLogger()
|
||||||
|
{
|
||||||
|
if (_logManager == null)
|
||||||
|
{
|
||||||
|
// Initialize LogManager
|
||||||
|
_logManager = new LogManager(LoggerSettings);
|
||||||
|
_logManager.Settings.TypesToLog.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Asynchronously logs the specified exception and an optional message, with the option to also write the log
|
/// Asynchronously logs the specified exception and an optional message, with the option to also write the log
|
||||||
/// entry to the console.
|
/// entry to the console.
|
||||||
@@ -108,6 +116,7 @@ namespace EonaCat.Logger
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InitLogger();
|
||||||
if (LoggerSettings.TypesToLog.Contains(ELogType.ERROR))
|
if (LoggerSettings.TypesToLog.Contains(ELogType.ERROR))
|
||||||
{
|
{
|
||||||
await _logManager.WriteAsync(exception, message, writeToConsole: writeToConsole).ConfigureAwait(false);
|
await _logManager.WriteAsync(exception, message, writeToConsole: writeToConsole).ConfigureAwait(false);
|
||||||
|
|||||||
128
EonaCat.Logger/Managers/HeaderTokens.cs
Normal file
128
EonaCat.Logger/Managers/HeaderTokens.cs
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static EonaCat.Logger.Managers.LogHelper;
|
||||||
|
|
||||||
|
// This file is part of the EonaCat project(s) which is released under the Apache License.
|
||||||
|
// See the LICENSE file or go to https://EonaCat.com/License for full license details.
|
||||||
|
|
||||||
|
namespace EonaCat.Logger.Managers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides a collection of predefined and customizable header token resolvers for formatting log or message headers.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>HeaderTokens exposes a set of standard tokens that can be used to insert runtime, environment, and
|
||||||
|
/// contextual information into header strings, such as timestamps, process details, thread information, and more.
|
||||||
|
/// Custom tokens can be added or overridden to support application-specific formatting needs. All token keys are
|
||||||
|
/// case-insensitive. This class is thread-safe for read operations, but adding or overriding tokens is not guaranteed
|
||||||
|
/// to be thread-safe and should be synchronized if used concurrently.</remarks>
|
||||||
|
public class HeaderTokens
|
||||||
|
{
|
||||||
|
private readonly Dictionary<string, Func<HeaderContext, string>> _tokenResolvers =
|
||||||
|
new(StringComparer.OrdinalIgnoreCase)
|
||||||
|
{
|
||||||
|
["date"] = ctx => $"[Date: {ctx.Timestamp:yyyy-MM-dd}]",
|
||||||
|
|
||||||
|
["time"] = ctx => $"[Time: {ctx.Timestamp:HH:mm:ss.fff}]",
|
||||||
|
|
||||||
|
["ticks"] = ctx => $"[Ticks: {ctx.Timestamp.Ticks}]",
|
||||||
|
|
||||||
|
["ts"] = ctx => $"[{ctx.Timestamp.ToString(ctx.TimestampFormat)}]",
|
||||||
|
|
||||||
|
["tz"] = ctx => $"[{(ctx.Timestamp.Kind == DateTimeKind.Utc ? "UTC" : "LOCAL")}]",
|
||||||
|
|
||||||
|
["unix"] = ctx => $"[Unix: {new DateTimeOffset(ctx.Timestamp).ToUnixTimeSeconds()}]",
|
||||||
|
|
||||||
|
["procstart"] = _ =>
|
||||||
|
{
|
||||||
|
var p = Process.GetCurrentProcess();
|
||||||
|
return $"[ProcStart: {p.StartTime:O}]";
|
||||||
|
},
|
||||||
|
|
||||||
|
["uptime"] = _ =>
|
||||||
|
{
|
||||||
|
var p = Process.GetCurrentProcess();
|
||||||
|
return $"[Uptime: {(DateTime.Now - p.StartTime).TotalSeconds:F0}s]";
|
||||||
|
},
|
||||||
|
|
||||||
|
["framework"] = _ =>
|
||||||
|
$"[Runtime: {RuntimeInformation.FrameworkDescription}]",
|
||||||
|
|
||||||
|
["os"] = _ =>
|
||||||
|
$"[OS: {RuntimeInformation.OSDescription}]",
|
||||||
|
|
||||||
|
["arch"] = _ =>
|
||||||
|
$"[Arch: {RuntimeInformation.ProcessArchitecture}]",
|
||||||
|
|
||||||
|
["mem"] = _ => $"[Memory: {GC.GetTotalMemory(false) / 1024 / 1024}MB]",
|
||||||
|
|
||||||
|
["gc"] = _ => $"[GC: {GC.CollectionCount(0)}/{GC.CollectionCount(1)}/{GC.CollectionCount(2)}]",
|
||||||
|
|
||||||
|
["cwd"] = _ => $"[CWD: {Environment.CurrentDirectory}]",
|
||||||
|
|
||||||
|
["app"] = _ => $"[App: {AppDomain.CurrentDomain.FriendlyName}]",
|
||||||
|
|
||||||
|
["appbase"] = _ => $"[AppBase: {AppDomain.CurrentDomain.BaseDirectory}]",
|
||||||
|
|
||||||
|
["domain"] = _ => $"[Domain: {AppDomain.CurrentDomain.Id}]",
|
||||||
|
|
||||||
|
["threadname"] = _ => $"[ThreadName: {Thread.CurrentThread.Name ?? "n/a"}]",
|
||||||
|
|
||||||
|
["task"] = _ => $"[TaskId: {Task.CurrentId?.ToString() ?? "n/a"}]",
|
||||||
|
|
||||||
|
["host"] = ctx => $"[Host: {ctx.HostName}]",
|
||||||
|
|
||||||
|
["machine"] = _ => $"[Machine: {Environment.MachineName}]",
|
||||||
|
|
||||||
|
["category"] = ctx => $"[Category: {ctx.Category}]",
|
||||||
|
|
||||||
|
["thread"] = _ => $"[Thread: {Environment.CurrentManagedThreadId}]",
|
||||||
|
|
||||||
|
["process"] = _ =>
|
||||||
|
{
|
||||||
|
var p = Process.GetCurrentProcess();
|
||||||
|
return $"[Process: {p.ProcessName}]";
|
||||||
|
},
|
||||||
|
|
||||||
|
["pid"] = _ => $"[PID: {Process.GetCurrentProcess().Id}]",
|
||||||
|
|
||||||
|
["sev"] = ctx => $"[Severity: {ctx.LogType}]",
|
||||||
|
|
||||||
|
["LogType"] = ctx => $"[{ctx.LogType}]",
|
||||||
|
|
||||||
|
["user"] = _ => $"[User: {Environment.UserName}]",
|
||||||
|
|
||||||
|
["env"] = ctx => $"[Env: {ctx.EnvironmentName}]",
|
||||||
|
|
||||||
|
["newline"] = _ => Environment.NewLine
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a read-only dictionary of token resolver functions used to generate header values based on a token name and
|
||||||
|
/// header context.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Each entry maps a token name to a function that produces the corresponding header value for a
|
||||||
|
/// given <see cref="HeaderContext"/>. The dictionary is static and cannot be modified at runtime.</remarks>
|
||||||
|
public IReadOnlyDictionary<string, Func<HeaderContext, string>> TokenResolvers => _tokenResolvers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds or overrides a custom token.
|
||||||
|
/// </summary>
|
||||||
|
public void AddCustomToken(string key, Func<HeaderContext, string> resolver)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(key))
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Token key cannot be null or whitespace.", nameof(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resolver == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(resolver));
|
||||||
|
}
|
||||||
|
|
||||||
|
_tokenResolvers[key] = resolver;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
using EonaCat.Json;
|
using EonaCat.Json;
|
||||||
|
using EonaCat.Logger.EonaCatCoreLogger;
|
||||||
|
using EonaCat.Logger.EonaCatCoreLogger.Internal;
|
||||||
using EonaCat.Logger.Extensions;
|
using EonaCat.Logger.Extensions;
|
||||||
using EonaCat.Logger.Servers.GrayLog;
|
using EonaCat.Logger.Servers.GrayLog;
|
||||||
using EonaCat.Logger.Servers.Splunk.Models;
|
using EonaCat.Logger.Servers.Splunk.Models;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -20,120 +23,6 @@ using static EonaCat.Logger.Managers.LogHelper;
|
|||||||
|
|
||||||
namespace EonaCat.Logger.Managers;
|
namespace EonaCat.Logger.Managers;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Provides a collection of predefined and customizable header token resolvers for formatting log or message headers.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>HeaderTokens exposes a set of standard tokens that can be used to insert runtime, environment, and
|
|
||||||
/// contextual information into header strings, such as timestamps, process details, thread information, and more.
|
|
||||||
/// Custom tokens can be added or overridden to support application-specific formatting needs. All token keys are
|
|
||||||
/// case-insensitive. This class is thread-safe for read operations, but adding or overriding tokens is not guaranteed
|
|
||||||
/// to be thread-safe and should be synchronized if used concurrently.</remarks>
|
|
||||||
public class HeaderTokens
|
|
||||||
{
|
|
||||||
private readonly Dictionary<string, Func<HeaderContext, string>> _tokenResolvers =
|
|
||||||
new(StringComparer.OrdinalIgnoreCase)
|
|
||||||
{
|
|
||||||
["date"] = ctx => $"[Date: {ctx.Timestamp:yyyy-MM-dd}]",
|
|
||||||
|
|
||||||
["time"] = ctx => $"[Time: {ctx.Timestamp:HH:mm:ss.fff}]",
|
|
||||||
|
|
||||||
["ticks"] = ctx => $"[Ticks: {ctx.Timestamp.Ticks}]",
|
|
||||||
|
|
||||||
["ts"] = ctx => $"[{ctx.Timestamp.ToString(ctx.TimestampFormat)}]",
|
|
||||||
|
|
||||||
["tz"] = ctx => $"[{(ctx.Timestamp.Kind == DateTimeKind.Utc ? "UTC" : "LOCAL")}]",
|
|
||||||
|
|
||||||
["unix"] = ctx => $"[Unix: {new DateTimeOffset(ctx.Timestamp).ToUnixTimeSeconds()}]",
|
|
||||||
|
|
||||||
["procstart"] = _ =>
|
|
||||||
{
|
|
||||||
var p = Process.GetCurrentProcess();
|
|
||||||
return $"[ProcStart: {p.StartTime:O}]";
|
|
||||||
},
|
|
||||||
|
|
||||||
["uptime"] = _ =>
|
|
||||||
{
|
|
||||||
var p = Process.GetCurrentProcess();
|
|
||||||
return $"[Uptime: {(DateTime.Now - p.StartTime).TotalSeconds:F0}s]";
|
|
||||||
},
|
|
||||||
|
|
||||||
["framework"] = _ =>
|
|
||||||
$"[Runtime: {RuntimeInformation.FrameworkDescription}]",
|
|
||||||
|
|
||||||
["os"] = _ =>
|
|
||||||
$"[OS: {RuntimeInformation.OSDescription}]",
|
|
||||||
|
|
||||||
["arch"] = _ =>
|
|
||||||
$"[Arch: {RuntimeInformation.ProcessArchitecture}]",
|
|
||||||
|
|
||||||
["mem"] = _ => $"[Memory: {GC.GetTotalMemory(false) / 1024 / 1024}MB]",
|
|
||||||
|
|
||||||
["gc"] = _ => $"[GC: {GC.CollectionCount(0)}/{GC.CollectionCount(1)}/{GC.CollectionCount(2)}]",
|
|
||||||
|
|
||||||
["cwd"] = _ => $"[CWD: {Environment.CurrentDirectory}]",
|
|
||||||
|
|
||||||
["app"] = _ => $"[App: {AppDomain.CurrentDomain.FriendlyName}]",
|
|
||||||
|
|
||||||
["appbase"] = _ => $"[AppBase: {AppDomain.CurrentDomain.BaseDirectory}]",
|
|
||||||
|
|
||||||
["domain"] = _ => $"[Domain: {AppDomain.CurrentDomain.Id}]",
|
|
||||||
|
|
||||||
["threadname"] = _ => $"[ThreadName: {Thread.CurrentThread.Name ?? "n/a"}]",
|
|
||||||
|
|
||||||
["task"] = _ => $"[TaskId: {Task.CurrentId?.ToString() ?? "n/a"}]",
|
|
||||||
|
|
||||||
["host"] = ctx => $"[Host: {ctx.HostName}]",
|
|
||||||
|
|
||||||
["machine"] = _ => $"[Machine: {Environment.MachineName}]",
|
|
||||||
|
|
||||||
["category"] = ctx => $"[Category: {ctx.Category}]",
|
|
||||||
|
|
||||||
["thread"] = _ => $"[Thread: {Environment.CurrentManagedThreadId}]",
|
|
||||||
|
|
||||||
["process"] = _ =>
|
|
||||||
{
|
|
||||||
var p = Process.GetCurrentProcess();
|
|
||||||
return $"[Process: {p.ProcessName}]";
|
|
||||||
},
|
|
||||||
|
|
||||||
["pid"] = _ => $"[PID: {Process.GetCurrentProcess().Id}]",
|
|
||||||
|
|
||||||
["sev"] = ctx => $"[Severity: {ctx.LogType}]",
|
|
||||||
|
|
||||||
["user"] = _ => $"[User: {Environment.UserName}]",
|
|
||||||
|
|
||||||
["env"] = ctx => $"[Env: {ctx.EnvironmentName}]",
|
|
||||||
|
|
||||||
["newline"] = _ => Environment.NewLine
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a read-only dictionary of token resolver functions used to generate header values based on a token name and
|
|
||||||
/// header context.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>Each entry maps a token name to a function that produces the corresponding header value for a
|
|
||||||
/// given <see cref="HeaderContext"/>. The dictionary is static and cannot be modified at runtime.</remarks>
|
|
||||||
public IReadOnlyDictionary<string, Func<HeaderContext, string>> TokenResolvers => _tokenResolvers;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds or overrides a custom token.
|
|
||||||
/// </summary>
|
|
||||||
public void AddCustomToken(string key, Func<HeaderContext, string> resolver)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(key))
|
|
||||||
{
|
|
||||||
throw new ArgumentException("Token key cannot be null or whitespace.", nameof(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resolver == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(resolver));
|
|
||||||
}
|
|
||||||
|
|
||||||
_tokenResolvers[key] = resolver;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ErrorMessage
|
public class ErrorMessage
|
||||||
{
|
{
|
||||||
public Exception Exception { get; set; }
|
public Exception Exception { get; set; }
|
||||||
@@ -160,10 +49,15 @@ public static class LogHelper
|
|||||||
private static readonly string MachineName = Environment.MachineName;
|
private static readonly string MachineName = Environment.MachineName;
|
||||||
private static readonly string HostName = Dns.GetHostName();
|
private static readonly string HostName = Dns.GetHostName();
|
||||||
|
|
||||||
|
private static readonly object _settingsLock = new object();
|
||||||
|
|
||||||
|
private static readonly object _consoleLock = new object();
|
||||||
|
|
||||||
|
private static readonly ConcurrentDictionary<string, Regex> _regexCache = new ConcurrentDictionary<string, Regex>();
|
||||||
|
|
||||||
internal static string ConvertToSyslogRfc5424(LoggerSettings settings, ELogType logType, string currentMessage, DateTime dateTime, string category = null)
|
internal static string ConvertToSyslogRfc5424(LoggerSettings settings, ELogType logType, string currentMessage, DateTime dateTime, string category = null)
|
||||||
{
|
{
|
||||||
string formattedMessage = FormatMessageWithHeader(settings, logType, currentMessage, dateTime, category);
|
string formattedMessage = FormatMessageWithHeader(settings, logType, currentMessage, dateTime, category);
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(formattedMessage))
|
if (string.IsNullOrWhiteSpace(formattedMessage))
|
||||||
{
|
{
|
||||||
return formattedMessage;
|
return formattedMessage;
|
||||||
@@ -188,7 +82,6 @@ public static class LogHelper
|
|||||||
internal static string ConvertToSyslogRfc3164(LoggerSettings settings, ELogType logType, string currentMessage, DateTime dateTime, string category = null)
|
internal static string ConvertToSyslogRfc3164(LoggerSettings settings, ELogType logType, string currentMessage, DateTime dateTime, string category = null)
|
||||||
{
|
{
|
||||||
string formattedMessage = FormatMessageWithHeader(settings, logType, currentMessage, dateTime, category);
|
string formattedMessage = FormatMessageWithHeader(settings, logType, currentMessage, dateTime, category);
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(formattedMessage))
|
if (string.IsNullOrWhiteSpace(formattedMessage))
|
||||||
{
|
{
|
||||||
return formattedMessage;
|
return formattedMessage;
|
||||||
@@ -210,7 +103,9 @@ public static class LogHelper
|
|||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Regex.Replace(format, @"\{([^}]+)\}", match =>
|
var regex = _regexCache.GetOrAdd(@"\{([^}]+)\}", pattern => new Regex(pattern, RegexOptions.Compiled));
|
||||||
|
|
||||||
|
return regex.Replace(format, match =>
|
||||||
{
|
{
|
||||||
var tokenText = match.Groups[1].Value;
|
var tokenText = match.Groups[1].Value;
|
||||||
|
|
||||||
@@ -230,15 +125,15 @@ public static class LogHelper
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static string FormatMessageWithHeader(
|
||||||
|
LoggerSettings settings,
|
||||||
|
ELogType logType,
|
||||||
internal static string FormatMessageWithHeader(LoggerSettings settings, ELogType logType, string message, DateTime dateTime, string category = null)
|
string message,
|
||||||
|
DateTime dateTime,
|
||||||
|
string category = null)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(message))
|
if (string.IsNullOrWhiteSpace(message))
|
||||||
{
|
|
||||||
return message;
|
return message;
|
||||||
}
|
|
||||||
|
|
||||||
var ctx = new HeaderContext
|
var ctx = new HeaderContext
|
||||||
{
|
{
|
||||||
@@ -251,12 +146,20 @@ public static class LogHelper
|
|||||||
EnvironmentName = settings?.EnvironmentName
|
EnvironmentName = settings?.EnvironmentName
|
||||||
};
|
};
|
||||||
|
|
||||||
string header = settings?.CustomHeaderFormatter != null
|
string header = string.Empty;
|
||||||
? settings.CustomHeaderFormatter(ctx)
|
|
||||||
: ResolveHeader(settings?.HeaderFormat, ctx);
|
if (!string.IsNullOrWhiteSpace(settings?.HeaderFormat) || settings?.CustomHeaderFormatter != null)
|
||||||
|
{
|
||||||
|
if (settings.CustomHeaderFormatter != null)
|
||||||
|
{
|
||||||
|
header = settings.CustomHeaderFormatter(ctx) ?? string.Empty;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
header = ResolveHeader(settings.HeaderFormat, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(header))
|
if (!string.IsNullOrEmpty(header))
|
||||||
{
|
|
||||||
header += " ";
|
header += " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,6 +167,7 @@ public static class LogHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
internal static void SendToConsole(LoggerSettings settings, ELogType logType, string message)
|
internal static void SendToConsole(LoggerSettings settings, ELogType logType, string message)
|
||||||
{
|
{
|
||||||
if (settings == null || string.IsNullOrWhiteSpace(message))
|
if (settings == null || string.IsNullOrWhiteSpace(message))
|
||||||
@@ -271,6 +175,8 @@ public static class LogHelper
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock (_consoleLock)
|
||||||
|
{
|
||||||
if (settings.EnableColors && settings.Colors != null)
|
if (settings.EnableColors && settings.Colors != null)
|
||||||
{
|
{
|
||||||
var prevForeground = Console.ForegroundColor;
|
var prevForeground = Console.ForegroundColor;
|
||||||
@@ -291,6 +197,7 @@ public static class LogHelper
|
|||||||
Console.WriteLine(message);
|
Console.WriteLine(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static bool TryGetLogColor(ColorSchema colors, ELogType logType, out ConsoleColor foreground, out ConsoleColor background)
|
private static bool TryGetLogColor(ColorSchema colors, ELogType logType, out ConsoleColor foreground, out ConsoleColor background)
|
||||||
{
|
{
|
||||||
@@ -338,7 +245,9 @@ public static class LogHelper
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var isEnabled = loggerSettings?.TypesToLog == null || loggerSettings.TypesToLog.Count == 0 || loggerSettings.TypesToLog.Contains(logType);
|
var typesToLog = loggerSettings?.TypesToLog;
|
||||||
|
var isEnabled = typesToLog == null || typesToLog.Count == 0 || typesToLog.Contains(logType);
|
||||||
|
|
||||||
if (!isEnabled)
|
if (!isEnabled)
|
||||||
{
|
{
|
||||||
OnLogLevelDisabled?.Invoke(null, new ErrorMessage { Message = $"Logtype '{logType}' is not enabled." });
|
OnLogLevelDisabled?.Invoke(null, new ErrorMessage { Message = $"Logtype '{logType}' is not enabled." });
|
||||||
@@ -351,12 +260,14 @@ public static class LogHelper
|
|||||||
|
|
||||||
public static void AddLogLevel(LoggerSettings settings, ELogType logType)
|
public static void AddLogLevel(LoggerSettings settings, ELogType logType)
|
||||||
{
|
{
|
||||||
if (logType == ELogType.NONE)
|
if (logType == ELogType.NONE || settings == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.TypesToLog == null || settings.TypesToLog.Count == 0)
|
lock (_settingsLock)
|
||||||
|
{
|
||||||
|
if (settings.TypesToLog == null)
|
||||||
{
|
{
|
||||||
settings.TypesToLog = new List<ELogType>();
|
settings.TypesToLog = new List<ELogType>();
|
||||||
}
|
}
|
||||||
@@ -366,25 +277,28 @@ public static class LogHelper
|
|||||||
settings.TypesToLog.Add(logType);
|
settings.TypesToLog.Add(logType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void RemoveLogLevel(LoggerSettings settings, ELogType logType)
|
public static void RemoveLogLevel(LoggerSettings settings, ELogType logType)
|
||||||
{
|
{
|
||||||
if (logType == ELogType.NONE)
|
if (logType == ELogType.NONE || settings == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.TypesToLog == null || settings.TypesToLog.Count == 0)
|
lock (_settingsLock)
|
||||||
|
{
|
||||||
|
if (settings.TypesToLog == null)
|
||||||
{
|
{
|
||||||
settings.TypesToLog = new List<ELogType>();
|
settings.TypesToLog = new List<ELogType>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!settings.TypesToLog.Contains(logType))
|
if (settings.TypesToLog.Contains(logType))
|
||||||
{
|
{
|
||||||
return;
|
|
||||||
}
|
|
||||||
settings.TypesToLog.Remove(logType);
|
settings.TypesToLog.Remove(logType);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void Log(ILogger logger, LogLevel logLevel, string message)
|
private static void Log(ILogger logger, LogLevel logLevel, string message)
|
||||||
{
|
{
|
||||||
@@ -403,12 +317,13 @@ public static class LogHelper
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.SplunkServers == null || settings.SplunkServers.Count() == 0)
|
var servers = settings.SplunkServers?.ToList();
|
||||||
|
if (servers == null || servers.Count == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tasks = settings.SplunkServers?
|
var tasks = servers
|
||||||
.Where(splunkServer => splunkServer.HasHecUrl && splunkServer.HasHecToken)
|
.Where(splunkServer => splunkServer.HasHecUrl && splunkServer.HasHecToken)
|
||||||
.Select(async splunkServer =>
|
.Select(async splunkServer =>
|
||||||
{
|
{
|
||||||
@@ -422,7 +337,8 @@ public static class LogHelper
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var isEnabled = (splunkServer?.TypesToLog == null || splunkServer?.TypesToLog.Count == 0 || splunkServer.TypesToLog.Contains(currentLogType));
|
var serverTypesToLog = splunkServer?.TypesToLog;
|
||||||
|
var isEnabled = (serverTypesToLog == null || serverTypesToLog.Count == 0 || serverTypesToLog.Contains(currentLogType));
|
||||||
if (!isEnabled)
|
if (!isEnabled)
|
||||||
{
|
{
|
||||||
splunkServer?.DisposeHttpClient();
|
splunkServer?.DisposeHttpClient();
|
||||||
@@ -431,7 +347,7 @@ public static class LogHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
var response = await splunkServer?.SendAsync(splunkPayload, disableSplunkSSL);
|
var response = await splunkServer?.SendAsync(splunkPayload, disableSplunkSSL);
|
||||||
if (!response.IsSuccessStatusCode)
|
if (response != null && !response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
LogError($"Failed to send log to Splunk '{splunkServer?.SplunkHecUrl}'. Status code: {response.StatusCode}");
|
LogError($"Failed to send log to Splunk '{splunkServer?.SplunkHecUrl}'. Status code: {response.StatusCode}");
|
||||||
}
|
}
|
||||||
@@ -440,7 +356,7 @@ public static class LogHelper
|
|||||||
{
|
{
|
||||||
LogError($"Error logging to Splunk '{splunkServer?.SplunkHecUrl}': {ex.Message}", ex);
|
LogError($"Error logging to Splunk '{splunkServer?.SplunkHecUrl}': {ex.Message}", ex);
|
||||||
}
|
}
|
||||||
}) ?? new List<Task>();
|
});
|
||||||
|
|
||||||
await Task.WhenAll(tasks);
|
await Task.WhenAll(tasks);
|
||||||
}
|
}
|
||||||
@@ -455,7 +371,8 @@ public static class LogHelper
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.SplunkServers == null || settings.SplunkServers.Count() == 0)
|
var servers = settings.SplunkServers?.ToList();
|
||||||
|
if (servers == null || servers.Count == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -487,7 +404,8 @@ public static class LogHelper
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.GrayLogServers == null || settings.GrayLogServers.Count() == 0)
|
var servers = settings.GrayLogServers?.ToList();
|
||||||
|
if (servers == null || servers.Count == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -507,7 +425,7 @@ public static class LogHelper
|
|||||||
|
|
||||||
var messageBytes = Encoding.UTF8.GetBytes(JsonHelper.ToJson(gelfMessage));
|
var messageBytes = Encoding.UTF8.GetBytes(JsonHelper.ToJson(gelfMessage));
|
||||||
|
|
||||||
var tasks = settings.GrayLogServers?
|
var tasks = servers
|
||||||
.Where(server => !string.IsNullOrWhiteSpace(server.Hostname) && server.Port >= 0)
|
.Where(server => !string.IsNullOrWhiteSpace(server.Hostname) && server.Port >= 0)
|
||||||
.Select(async grayLogServer =>
|
.Select(async grayLogServer =>
|
||||||
{
|
{
|
||||||
@@ -519,7 +437,8 @@ public static class LogHelper
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var isEnabled = (grayLogServer?.TypesToLog == null || grayLogServer.TypesToLog.Count == 0 || grayLogServer.TypesToLog.Contains(logType));
|
var serverTypesToLog = grayLogServer?.TypesToLog;
|
||||||
|
var isEnabled = (serverTypesToLog == null || serverTypesToLog.Count == 0 || serverTypesToLog.Contains(logType));
|
||||||
if (!isEnabled)
|
if (!isEnabled)
|
||||||
{
|
{
|
||||||
grayLogServer?.DisposeUdp();
|
grayLogServer?.DisposeUdp();
|
||||||
@@ -555,7 +474,7 @@ public static class LogHelper
|
|||||||
Message = $"Error logging to GrayLog Server '{grayLogServer.Hostname}': {ex.Message}"
|
Message = $"Error logging to GrayLog Server '{grayLogServer.Hostname}': {ex.Message}"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}) ?? new List<Task>();
|
});
|
||||||
|
|
||||||
await Task.WhenAll(tasks);
|
await Task.WhenAll(tasks);
|
||||||
}
|
}
|
||||||
@@ -599,12 +518,13 @@ public static class LogHelper
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.SysLogServers == null || settings.SysLogServers.Count() == 0)
|
var servers = settings.SysLogServers?.ToList();
|
||||||
|
if (servers == null || servers.Count == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tasks = settings.SysLogServers?
|
var tasks = servers
|
||||||
.Where(server => !string.IsNullOrWhiteSpace(server.Hostname) && server.Port >= 0)
|
.Where(server => !string.IsNullOrWhiteSpace(server.Hostname) && server.Port >= 0)
|
||||||
.Select(async server =>
|
.Select(async server =>
|
||||||
{
|
{
|
||||||
@@ -616,27 +536,30 @@ public static class LogHelper
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var isEnabled = (server?.TypesToLog == null || server.TypesToLog.Count == 0 || server.TypesToLog.Contains(logType));
|
var serverTypesToLog = server?.TypesToLog;
|
||||||
|
var isEnabled = (serverTypesToLog == null || serverTypesToLog.Count == 0 || serverTypesToLog.Contains(logType));
|
||||||
if (!isEnabled)
|
if (!isEnabled)
|
||||||
{
|
{
|
||||||
server?.DisposeUdp();
|
server?.DisposeUdp();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string serverMessage = message;
|
||||||
|
|
||||||
if (server.ConvertToRfc5424)
|
if (server.ConvertToRfc5424)
|
||||||
{
|
{
|
||||||
message = ConvertToSyslogRfc5424(settings, logType, message, dateTime, category);
|
serverMessage = ConvertToSyslogRfc5424(settings, logType, serverMessage, dateTime, category);
|
||||||
}
|
}
|
||||||
else if (server.ConvertToRfc3164)
|
else if (server.ConvertToRfc3164)
|
||||||
{
|
{
|
||||||
message = ConvertToSyslogRfc3164(settings, logType, message, dateTime, category);
|
serverMessage = ConvertToSyslogRfc3164(settings, logType, serverMessage, dateTime, category);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!server.IsConnected)
|
if (!server.IsConnected)
|
||||||
{
|
{
|
||||||
server.SetUdp();
|
server.SetUdp();
|
||||||
}
|
}
|
||||||
await server.WriteAsync(message);
|
await server.WriteAsync(serverMessage);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -646,7 +569,7 @@ public static class LogHelper
|
|||||||
Message = $"Error logging to SysLog Server '{server.Hostname}': {ex.Message}"
|
Message = $"Error logging to SysLog Server '{server.Hostname}': {ex.Message}"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}) ?? new List<Task>();
|
});
|
||||||
|
|
||||||
await Task.WhenAll(tasks);
|
await Task.WhenAll(tasks);
|
||||||
}
|
}
|
||||||
@@ -658,12 +581,13 @@ public static class LogHelper
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.TcpServers == null || settings.TcpServers.Count() == 0)
|
var servers = settings.TcpServers?.ToList();
|
||||||
|
if (servers == null || servers.Count == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tasks = settings.TcpServers?
|
var tasks = servers
|
||||||
.Where(server => !string.IsNullOrWhiteSpace(server.Hostname) && server.Port >= 0)
|
.Where(server => !string.IsNullOrWhiteSpace(server.Hostname) && server.Port >= 0)
|
||||||
.Select(async server =>
|
.Select(async server =>
|
||||||
{
|
{
|
||||||
@@ -675,7 +599,8 @@ public static class LogHelper
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var isEnabled = (server?.TypesToLog == null || server.TypesToLog.Count == 0 || server.TypesToLog.Contains(logType));
|
var serverTypesToLog = server?.TypesToLog;
|
||||||
|
var isEnabled = (serverTypesToLog == null || serverTypesToLog.Count == 0 || serverTypesToLog.Contains(logType));
|
||||||
if (!isEnabled)
|
if (!isEnabled)
|
||||||
{
|
{
|
||||||
server?.DisposeTcp();
|
server?.DisposeTcp();
|
||||||
@@ -698,7 +623,7 @@ public static class LogHelper
|
|||||||
Message = $"Error logging to Tcp Server '{server.Hostname}': {ex.Message}"
|
Message = $"Error logging to Tcp Server '{server.Hostname}': {ex.Message}"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}) ?? new List<Task>();
|
});
|
||||||
|
|
||||||
await Task.WhenAll(tasks);
|
await Task.WhenAll(tasks);
|
||||||
}
|
}
|
||||||
@@ -710,12 +635,13 @@ public static class LogHelper
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.UdpServers == null || settings.UdpServers.Count() == 0)
|
var servers = settings.UdpServers?.ToList();
|
||||||
|
if (servers == null || servers.Count == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tasks = settings.UdpServers?
|
var tasks = servers
|
||||||
.Where(server => !string.IsNullOrWhiteSpace(server.Hostname) && server.Port >= 0)
|
.Where(server => !string.IsNullOrWhiteSpace(server.Hostname) && server.Port >= 0)
|
||||||
.Select(async server =>
|
.Select(async server =>
|
||||||
{
|
{
|
||||||
@@ -727,7 +653,8 @@ public static class LogHelper
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var isEnabled = (server?.TypesToLog == null || server.TypesToLog.Count == 0 || server.TypesToLog.Contains(logType));
|
var serverTypesToLog = server?.TypesToLog;
|
||||||
|
var isEnabled = (serverTypesToLog == null || serverTypesToLog.Count == 0 || serverTypesToLog.Contains(logType));
|
||||||
if (!isEnabled)
|
if (!isEnabled)
|
||||||
{
|
{
|
||||||
server?.DisposeUdp();
|
server?.DisposeUdp();
|
||||||
@@ -750,10 +677,11 @@ public static class LogHelper
|
|||||||
Message = $"Error logging to Udp Server '{server.Hostname}': {ex.Message}"
|
Message = $"Error logging to Udp Server '{server.Hostname}': {ex.Message}"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}) ?? new List<Task>();
|
});
|
||||||
|
|
||||||
await Task.WhenAll(tasks);
|
await Task.WhenAll(tasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static string GetStartupMessage()
|
internal static string GetStartupMessage()
|
||||||
{
|
{
|
||||||
return $"{DllInfo.ApplicationName} started.";
|
return $"{DllInfo.ApplicationName} started.";
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
using System;
|
using EonaCat.Logger.EonaCatCoreLogger;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using EonaCat.Logger.EonaCatCoreLogger;
|
|
||||||
using EonaCat.Logger.EonaCatCoreLogger.Extensions;
|
using EonaCat.Logger.EonaCatCoreLogger.Extensions;
|
||||||
|
using EonaCat.Logger.EonaCatCoreLogger.Internal;
|
||||||
using EonaCat.Logger.EonaCatCoreLogger.Models;
|
using EonaCat.Logger.EonaCatCoreLogger.Models;
|
||||||
using EonaCat.Logger.Extensions;
|
using EonaCat.Logger.Extensions;
|
||||||
using EonaCat.Logger.Servers.GrayLog;
|
using EonaCat.Logger.Servers.GrayLog;
|
||||||
@@ -16,6 +10,13 @@ using EonaCat.Logger.Servers.Tcp;
|
|||||||
using EonaCat.Logger.Servers.Udp;
|
using EonaCat.Logger.Servers.Udp;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
// This file is part of the EonaCat project(s) which is released under the Apache License.
|
// This file is part of the EonaCat project(s) which is released under the Apache License.
|
||||||
// See the LICENSE file or go to https://EonaCat.com/License for full license details.
|
// See the LICENSE file or go to https://EonaCat.com/License for full license details.
|
||||||
@@ -171,6 +172,7 @@ namespace EonaCat.Logger.Managers
|
|||||||
.AddEonaCatFileLogger(config =>
|
.AddEonaCatFileLogger(config =>
|
||||||
{
|
{
|
||||||
var options = Settings.FileLoggerOptions;
|
var options = Settings.FileLoggerOptions;
|
||||||
|
config.LoggerSettings = Settings;
|
||||||
config.MaxWriteTries = options.MaxWriteTries;
|
config.MaxWriteTries = options.MaxWriteTries;
|
||||||
config.RetainedFileCountLimit = options.RetainedFileCountLimit;
|
config.RetainedFileCountLimit = options.RetainedFileCountLimit;
|
||||||
config.FlushPeriod = options.FlushPeriod;
|
config.FlushPeriod = options.FlushPeriod;
|
||||||
@@ -185,13 +187,13 @@ namespace EonaCat.Logger.Managers
|
|||||||
config.Mask = options.Mask;
|
config.Mask = options.Mask;
|
||||||
config.UseDefaultMasking = Settings.UseDefaultMasking;
|
config.UseDefaultMasking = Settings.UseDefaultMasking;
|
||||||
config.MaskedKeywords = options.MaskedKeywords;
|
config.MaskedKeywords = options.MaskedKeywords;
|
||||||
|
config.Settings = Settings;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
var serviceProvider = serviceCollection.BuildServiceProvider();
|
var serviceProvider = serviceCollection.BuildServiceProvider();
|
||||||
LoggerProvider = serviceProvider.GetService<ILoggerProvider>();
|
LoggerProvider = serviceProvider.GetService<ILoggerProvider>();
|
||||||
LoggerFactory = serviceProvider.GetService<ILoggerFactory>();
|
LoggerFactory = serviceProvider.GetService<ILoggerFactory>();
|
||||||
Logger = LoggerFactory.CreateLogger(Settings.Id);
|
Logger = LoggerFactory.CreateLogger(Settings.Id);
|
||||||
|
|
||||||
LogHelper.SendToFile(Logger, Settings, ELogType.INFO, LogHelper.GetStartupMessage());
|
LogHelper.SendToFile(Logger, Settings, ELogType.INFO, LogHelper.GetStartupMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,6 +214,7 @@ namespace EonaCat.Logger.Managers
|
|||||||
var messageWithHeader = LogHelper.FormatMessageWithHeader(Settings, logType, message, dateTime, _category);
|
var messageWithHeader = LogHelper.FormatMessageWithHeader(Settings, logType, message, dateTime, _category);
|
||||||
var writeToConsoleValue = writeToConsole.GetValueOrDefault(Settings.EnableConsole);
|
var writeToConsoleValue = writeToConsole.GetValueOrDefault(Settings.EnableConsole);
|
||||||
|
|
||||||
|
// Send message without header to the fileProvider
|
||||||
LogHelper.SendToFile(Logger, Settings, logType, message);
|
LogHelper.SendToFile(Logger, Settings, logType, message);
|
||||||
|
|
||||||
if (writeToConsoleValue)
|
if (writeToConsoleValue)
|
||||||
@@ -240,7 +243,7 @@ namespace EonaCat.Logger.Managers
|
|||||||
Settings.OnLogEvent(new EonaCatLogMessage
|
Settings.OnLogEvent(new EonaCatLogMessage
|
||||||
{
|
{
|
||||||
DateTime = dateTime,
|
DateTime = dateTime,
|
||||||
Message = message,
|
Message = messageWithHeader,
|
||||||
LogType = logType,
|
LogType = logType,
|
||||||
Origin = string.IsNullOrEmpty(Settings.LogOrigin) ? "LogManager" : Settings.LogOrigin,
|
Origin = string.IsNullOrEmpty(Settings.LogOrigin) ? "LogManager" : Settings.LogOrigin,
|
||||||
Category = _category
|
Category = _category
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class LoggerSettings
|
|||||||
|
|
||||||
private FileLoggerOptions _fileLoggerOptions;
|
private FileLoggerOptions _fileLoggerOptions;
|
||||||
|
|
||||||
private string _headerFormat = "{ts} {tz} {host} {category} {thread} {sev}";
|
private string _headerFormat = "{ts} {tz} {host} {category} {thread} {LogType}";
|
||||||
private string _timestampFormat = "yyyy-MM-dd HH:mm:ss";
|
private string _timestampFormat = "yyyy-MM-dd HH:mm:ss";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -51,8 +51,8 @@ public class LoggerSettings
|
|||||||
/// {host}: Hostname
|
/// {host}: Hostname
|
||||||
/// {category}: Category
|
/// {category}: Category
|
||||||
/// {thread}: Thread ID
|
/// {thread}: Thread ID
|
||||||
/// {sev}: Severity
|
/// {LogType}: LogType
|
||||||
/// Default: {ts} {tz} {host} {category} {thread} {sev}
|
/// Default: {ts} {tz} {host} {category} {thread} {LogType}
|
||||||
/// A space will be inserted between the header and the message.
|
/// A space will be inserted between the header and the message.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string HeaderFormat
|
public string HeaderFormat
|
||||||
|
|||||||
@@ -37,22 +37,6 @@ public class Logger
|
|||||||
UseLocalTime = UseLocalTime,
|
UseLocalTime = UseLocalTime,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
LoggerSettings.CustomHeaderFormatter = ctx =>
|
|
||||||
{
|
|
||||||
if (ctx.LogType == ELogType.ERROR)
|
|
||||||
{
|
|
||||||
return $"{ctx.Timestamp:HH:mm:ss} [{ctx.LogType}]";
|
|
||||||
}
|
|
||||||
|
|
||||||
return $"{ctx.Timestamp:HH:mm:ss} [{ctx.LogType}]";
|
|
||||||
};
|
|
||||||
|
|
||||||
LoggerSettings.Toke
|
|
||||||
|
|
||||||
_logManager = new LogManager(LoggerSettings);
|
|
||||||
_logManager.Settings.TypesToLog.Clear();
|
|
||||||
_logManager.Settings.LogInfo();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteCurrentLogFile()
|
public void DeleteCurrentLogFile()
|
||||||
@@ -139,9 +123,20 @@ public class Logger
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InitLogger();
|
||||||
await _logManager.WriteAsync(message, logType, writeToConsole).ConfigureAwait(false);
|
await _logManager.WriteAsync(message, logType, writeToConsole).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void InitLogger()
|
||||||
|
{
|
||||||
|
if (_logManager == null)
|
||||||
|
{
|
||||||
|
// Initialize LogManager
|
||||||
|
_logManager = new LogManager(LoggerSettings);
|
||||||
|
_logManager.Settings.TypesToLog.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task LogAsync(Exception exception, string message = "", bool writeToConsole = true)
|
public async Task LogAsync(Exception exception, string message = "", bool writeToConsole = true)
|
||||||
{
|
{
|
||||||
if (IsDisabled)
|
if (IsDisabled)
|
||||||
@@ -149,6 +144,7 @@ public class Logger
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InitLogger();
|
||||||
if (LoggerSettings.TypesToLog.Contains(ELogType.ERROR))
|
if (LoggerSettings.TypesToLog.Contains(ELogType.ERROR))
|
||||||
{
|
{
|
||||||
await _logManager.WriteAsync(exception, message, writeToConsole: writeToConsole).ConfigureAwait(false);
|
await _logManager.WriteAsync(exception, message, writeToConsole: writeToConsole).ConfigureAwait(false);
|
||||||
|
|||||||
@@ -39,16 +39,16 @@
|
|||||||
int onLogCounter = 0;
|
int onLogCounter = 0;
|
||||||
var defaultColor = Console.ForegroundColor;
|
var defaultColor = Console.ForegroundColor;
|
||||||
|
|
||||||
_ = Task.Run(() =>
|
//_ = Task.Run(() =>
|
||||||
{
|
//{
|
||||||
var logman = LogManager.Instance;
|
// var logman = LogManager.Instance;
|
||||||
var i = 0;
|
// var i = 0;
|
||||||
while (true)
|
// while (true)
|
||||||
{
|
// {
|
||||||
logman.WriteAsync($"Logman test {++i}", ELogType.TRACE).ConfigureAwait(false);
|
// logman.WriteAsync($"Logman test {++i}", ELogType.TRACE).ConfigureAwait(false);
|
||||||
Task.Delay(10).ConfigureAwait(false);
|
// Task.Delay(10).ConfigureAwait(false);
|
||||||
}
|
// }
|
||||||
}).ConfigureAwait(false);
|
//}).ConfigureAwait(false);
|
||||||
|
|
||||||
// Add services to the container.
|
// Add services to the container.
|
||||||
Logger logger = new Logger();
|
Logger logger = new Logger();
|
||||||
@@ -64,6 +64,20 @@
|
|||||||
logger.LoggerSettings.OnLog += LoggerSettings_OnLog;
|
logger.LoggerSettings.OnLog += LoggerSettings_OnLog;
|
||||||
logger.LoggerSettings.UseMask = true;
|
logger.LoggerSettings.UseMask = true;
|
||||||
|
|
||||||
|
//LoggerSettings.CustomHeaderFormatter = ctx =>
|
||||||
|
//{
|
||||||
|
// if (ctx.LogType == ELogType.ERROR)
|
||||||
|
// {
|
||||||
|
// return $"{ctx.Timestamp:HH:mm:ss} [{ctx.LogType}]";
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return $"{ctx.Timestamp:HH:mm:ss} [{ctx.LogType}]";
|
||||||
|
//};
|
||||||
|
|
||||||
|
logger.LoggerSettings.CustomHeaderFormatter = null; // remove the lambda
|
||||||
|
logger.LoggerSettings.HeaderTokens.AddCustomToken("AppName", x => "[JIJ BENT EEN BRASSER!]");
|
||||||
|
logger.LoggerSettings.HeaderFormat = "{AppName} {LogType} {ts}";
|
||||||
|
|
||||||
// Configure the client
|
// Configure the client
|
||||||
var centralOptions = new LogCentralOptions
|
var centralOptions = new LogCentralOptions
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user