Added sysLogServer functionality
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
namespace EonaCat.Logger
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace EonaCat.Logger
|
||||
{
|
||||
// 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.
|
||||
@@ -14,4 +16,84 @@
|
||||
CRITICAL = 6,
|
||||
TRACE = 7
|
||||
}
|
||||
|
||||
public static class LogTypeConverter
|
||||
{
|
||||
public static ELogType FromLogLevel(this LogLevel logLevel)
|
||||
{
|
||||
switch (logLevel)
|
||||
{
|
||||
case LogLevel.None:
|
||||
return ELogType.NONE;
|
||||
case LogLevel.Error:
|
||||
return ELogType.ERROR;
|
||||
case LogLevel.Debug:
|
||||
return ELogType.DEBUG;
|
||||
case LogLevel.Critical:
|
||||
return ELogType.CRITICAL;
|
||||
case LogLevel.Warning:
|
||||
return ELogType.WARNING;
|
||||
case LogLevel.Trace:
|
||||
return ELogType.TRACE;
|
||||
default:
|
||||
return ELogType.INFO;
|
||||
}
|
||||
}
|
||||
|
||||
public static ELogType FromSeverity(this ESeverity logLevel)
|
||||
{
|
||||
switch (logLevel)
|
||||
{
|
||||
case ESeverity.Debug:
|
||||
return ELogType.DEBUG;
|
||||
case ESeverity.Warn:
|
||||
return ELogType.WARNING;
|
||||
case ESeverity.Emergency:
|
||||
return ELogType.CRITICAL;
|
||||
case ESeverity.Critical:
|
||||
return ELogType.CRITICAL;
|
||||
case ESeverity.Alert:
|
||||
return ELogType.ERROR;
|
||||
case ESeverity.Error:
|
||||
return ELogType.ERROR;
|
||||
default:
|
||||
return ELogType.INFO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Message severity.
|
||||
/// </summary>
|
||||
public enum ESeverity
|
||||
{
|
||||
/// <summary>
|
||||
/// Debug messages.
|
||||
/// </summary>
|
||||
Debug = 0,
|
||||
/// <summary>
|
||||
/// Informational messages.
|
||||
/// </summary>
|
||||
Info = 1,
|
||||
/// <summary>
|
||||
/// Warning messages.
|
||||
/// </summary>
|
||||
Warn = 2,
|
||||
/// <summary>
|
||||
/// Error messages.
|
||||
/// </summary>
|
||||
Error = 3,
|
||||
/// <summary>
|
||||
/// Alert messages.
|
||||
/// </summary>
|
||||
Alert = 4,
|
||||
/// <summary>
|
||||
/// Critical messages.
|
||||
/// </summary>
|
||||
Critical = 5,
|
||||
/// <summary>
|
||||
/// Emergency messages.
|
||||
/// </summary>
|
||||
Emergency = 6
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
net6.0;
|
||||
</TargetFrameworks>
|
||||
<ApplicationIcon>icon.ico</ApplicationIcon>
|
||||
<Version>1.0.0</Version>
|
||||
<Version>1.0.1</Version>
|
||||
<Authors>EonaCat (Jeroen Saey)</Authors>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Company>EonaCat (Jeroen Saey)</Company>
|
||||
@@ -23,6 +23,8 @@
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
|
||||
<Title>EonaCat.Logger</Title>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -16,20 +16,20 @@ namespace EonaCat.Logger.Extensions
|
||||
/// Adds a file logger named 'File' to the factory.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="ILoggingBuilder"/> to use.</param>
|
||||
public static ILoggingBuilder AddFile(this ILoggingBuilder builder)
|
||||
public static ILoggingBuilder AddEonaCatFileLogger(this ILoggingBuilder builder)
|
||||
{
|
||||
builder.Services.AddSingleton<ILoggerProvider, FileLoggerProvider>();
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a file logger named 'File' to the factory.
|
||||
/// Adds the EonaCat File Logger named 'EonaCatFileLogger' to the factory.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="ILoggingBuilder"/> to use.</param>
|
||||
/// <param name="filenamePrefix">Sets the filename prefix to use for log files</param>
|
||||
public static ILoggingBuilder AddFile(this ILoggingBuilder builder, string filenamePrefix)
|
||||
public static ILoggingBuilder AddEonaCatFileLogger(this ILoggingBuilder builder, string filenamePrefix)
|
||||
{
|
||||
builder.AddFile(options => options.FileNamePrefix = filenamePrefix);
|
||||
builder.AddEonaCatFileLogger(options => options.FileNamePrefix = filenamePrefix);
|
||||
return builder;
|
||||
}
|
||||
|
||||
@@ -38,13 +38,13 @@ namespace EonaCat.Logger.Extensions
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="ILoggingBuilder"/> to use.</param>
|
||||
/// <param name="configure">Configure an instance of the <see cref="FileLoggerOptions" /> to set logging options</param>
|
||||
public static ILoggingBuilder AddFile(this ILoggingBuilder builder, Action<FileLoggerOptions> configure)
|
||||
public static ILoggingBuilder AddEonaCatFileLogger(this ILoggingBuilder builder, Action<FileLoggerOptions> configure)
|
||||
{
|
||||
if (configure == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(configure));
|
||||
}
|
||||
builder.AddFile();
|
||||
builder.AddEonaCatFileLogger();
|
||||
builder.Services.Configure(configure);
|
||||
|
||||
return builder;
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace EonaCat.Logger
|
||||
private int _fileSizeLimit = 200 * 1024 * 1024;
|
||||
private int _retainedFileCountLimit = 50;
|
||||
private int _maxRolloverFiles = 10;
|
||||
private int _maxTries = 3;
|
||||
|
||||
public static string DefaultPath => AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory;
|
||||
|
||||
@@ -55,6 +56,20 @@ namespace EonaCat.Logger
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the max times to try to write to the file.
|
||||
/// Defaults 3.
|
||||
/// </summary>
|
||||
public int MaxWriteTries
|
||||
{
|
||||
get => _maxTries;
|
||||
|
||||
set
|
||||
{
|
||||
_maxTries = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a strictly positive value representing the maximum retained file rollovers or null for no limit.
|
||||
/// Defaults to <c>10</c>.
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using EonaCat.Logger.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -23,9 +25,37 @@ namespace EonaCat.Logger
|
||||
private readonly int _maxFileSize;
|
||||
private readonly int _maxRetainedFiles;
|
||||
private readonly int _maxRolloverFiles;
|
||||
private readonly int _maxTries;
|
||||
private int _rollOverCount = 0;
|
||||
private static readonly object _writeLock = new object();
|
||||
private string _logFile;
|
||||
|
||||
public string LogFile { get; private set; }
|
||||
/// <summary>
|
||||
/// The file to which log messages should be appended.
|
||||
/// </summary>
|
||||
public string LogFile
|
||||
{
|
||||
get
|
||||
{
|
||||
return _logFile;
|
||||
}
|
||||
set
|
||||
{
|
||||
_logFile = value;
|
||||
|
||||
if (!string.IsNullOrEmpty(_logFile))
|
||||
{
|
||||
string dir = Path.GetDirectoryName(_logFile);
|
||||
if (!string.IsNullOrEmpty(dir))
|
||||
{
|
||||
if (!Directory.Exists(dir))
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="FileLoggerProvider" />
|
||||
@@ -39,6 +69,7 @@ namespace EonaCat.Logger
|
||||
_maxFileSize = loggerOptions.FileSizeLimit;
|
||||
_maxRetainedFiles = loggerOptions.RetainedFileCountLimit;
|
||||
_maxRolloverFiles = loggerOptions.MaxRolloverFiles;
|
||||
_maxTries = loggerOptions.MaxWriteTries;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -77,11 +108,31 @@ namespace EonaCat.Logger
|
||||
}
|
||||
}
|
||||
|
||||
using (StreamWriter streamWriter = File.AppendText(LogFile))
|
||||
lock (_writeLock)
|
||||
{
|
||||
int tries = 0;
|
||||
bool completed = false;
|
||||
|
||||
while (!completed)
|
||||
{
|
||||
try
|
||||
{
|
||||
System.IO.StreamWriter file = new System.IO.StreamWriter(LogFile, true);
|
||||
foreach (LogMessage item in group)
|
||||
{
|
||||
await streamWriter.WriteAsync(item.Message);
|
||||
file.WriteAsync(item.Message);
|
||||
}
|
||||
|
||||
file.Close();
|
||||
completed = true;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
tries++;
|
||||
Task.Delay(100);
|
||||
if (tries >= _maxTries)
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using EonaCat.logger.Managers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
@@ -25,35 +26,21 @@ namespace EonaCat.Logger.Internal
|
||||
|
||||
public bool IsEnabled(LogLevel logLevel)
|
||||
{
|
||||
if (logLevel == LogLevel.None)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return logLevel != LogLevel.None;
|
||||
}
|
||||
|
||||
public void Log<TState>(DateTimeOffset timestamp, LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
|
||||
{
|
||||
if (!IsEnabled(logLevel))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!IsEnabled(logLevel)) return;
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.Append(timestamp.ToString("yyyy-MM-dd HH:mm:ss.fff zzz"));
|
||||
builder.Append(" [");
|
||||
builder.Append(logLevel.ToString());
|
||||
builder.Append("] ");
|
||||
builder.Append(_category);
|
||||
builder.Append(": ");
|
||||
builder.AppendLine(formatter(state, exception));
|
||||
var message = LogHelper.FormatMessageWithHeader(new Managers.LoggerSettings(), logLevel.FromLogLevel(), formatter(state, exception)) + Environment.NewLine;
|
||||
|
||||
if (exception != null)
|
||||
{
|
||||
builder.AppendLine(exception.ToString());
|
||||
message = exception.FormatExceptionToMessage() + Environment.NewLine;
|
||||
}
|
||||
|
||||
_provider.AddMessage(timestamp, builder.ToString());
|
||||
_provider.AddMessage(timestamp, message);
|
||||
}
|
||||
|
||||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace EonaCat.Logger.Internal
|
||||
}
|
||||
catch
|
||||
{
|
||||
//cancellation token canceled or CompleteAdding called
|
||||
// cancellation token canceled or CompleteAdding called
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,6 +128,12 @@ namespace EonaCat.Logger.Internal
|
||||
public void Dispose()
|
||||
{
|
||||
Stop();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
~BatchingLoggerProvider()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
public ILogger CreateLogger(string categoryName)
|
||||
|
||||
@@ -9,13 +9,13 @@ namespace EonaCatLogger.EonaCatCoreLogger.Models
|
||||
|
||||
public class EonaCatLogMessage
|
||||
{
|
||||
public DateTime DateTime { get; internal set; }
|
||||
public string Message { get; internal set; }
|
||||
public ELogType LogType { get; internal set; }
|
||||
public DateTime DateTime { get; set; }
|
||||
public string Message { get; set; }
|
||||
public ELogType LogType { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"[{EnumHelper<ELogType>.ToString(LogType)}] [{DateTime.ToString(Constants.DateTimeFormats.LOGGING)}] {Message}";
|
||||
return $"[{DateTime.ToString(Constants.DateTimeFormats.LOGGING)}] [{EnumHelper<ELogType>.ToString(LogType)}] {Message}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace EonaCat.Logger.Exceptions
|
||||
{
|
||||
public class EonaCatLoggerAssertionException : Exception
|
||||
{
|
||||
public EonaCatLoggerAssertionException(string message) : base(message) { }
|
||||
}
|
||||
}
|
||||
74
EonaCat.Logger/Managers/ColorSchema.cs
Normal file
74
EonaCat.Logger/Managers/ColorSchema.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
|
||||
namespace EonaCat.Logger.Managers
|
||||
{
|
||||
/// <summary>
|
||||
/// Colors to use when writing to the console.
|
||||
/// </summary>
|
||||
public class ColorSchema
|
||||
{
|
||||
private ConsoleColor currentForeground = Console.ForegroundColor;
|
||||
|
||||
/// <summary>
|
||||
/// The color to use for debug messages. Default is dark gray on black.
|
||||
/// </summary>
|
||||
public ColorScheme Debug = new ColorScheme(ConsoleColor.DarkGray, ConsoleColor.Black);
|
||||
|
||||
/// <summary>
|
||||
/// The color to use for informational messages. Default is gray on black.
|
||||
/// </summary>
|
||||
public ColorScheme Info = new ColorScheme(ConsoleColor.Gray, ConsoleColor.Black);
|
||||
|
||||
/// <summary>
|
||||
/// The color to use for warning messages. Default is dark red on black.
|
||||
/// </summary>
|
||||
public ColorScheme Warning = new ColorScheme(ConsoleColor.DarkRed, ConsoleColor.Black);
|
||||
|
||||
/// <summary>
|
||||
/// The color to use for error messages. Default is red on black.
|
||||
/// </summary>
|
||||
public ColorScheme Error = new ColorScheme(ConsoleColor.Red, ConsoleColor.Black);
|
||||
|
||||
/// <summary>
|
||||
/// The color to use for alert messages. Default is dark yellow on black.
|
||||
/// </summary>
|
||||
public ColorScheme Traffic = new ColorScheme(ConsoleColor.DarkYellow, ConsoleColor.Black);
|
||||
|
||||
/// <summary>
|
||||
/// The color to use for critical messages. Default is yellow on black.
|
||||
/// </summary>
|
||||
public ColorScheme Critical = new ColorScheme(ConsoleColor.Yellow, ConsoleColor.Black);
|
||||
|
||||
/// <summary>
|
||||
/// The color to use for emergency messages. Default is white on red.
|
||||
/// </summary>
|
||||
public ColorScheme Trace = new ColorScheme(ConsoleColor.White, ConsoleColor.Red);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Color scheme for logging messages.
|
||||
/// </summary>
|
||||
public class ColorScheme
|
||||
{
|
||||
/// <summary>
|
||||
/// Foreground color.
|
||||
/// </summary>
|
||||
public ConsoleColor Foreground = Console.ForegroundColor;
|
||||
|
||||
/// <summary>
|
||||
/// Background color.
|
||||
/// </summary>
|
||||
public ConsoleColor Background = Console.BackgroundColor;
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates a new color scheme.
|
||||
/// </summary>
|
||||
/// <param name="foreground">Foreground color.</param>
|
||||
/// <param name="background">Background color.</param>
|
||||
public ColorScheme(ConsoleColor foreground, ConsoleColor background)
|
||||
{
|
||||
Foreground = foreground;
|
||||
Background = background;
|
||||
}
|
||||
}
|
||||
}
|
||||
8
EonaCat.Logger/Managers/EFileLoggingMode.cs
Normal file
8
EonaCat.Logger/Managers/EFileLoggingMode.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace EonaCat.Logger.Managers
|
||||
{
|
||||
public enum EFileLoggingMode
|
||||
{
|
||||
Enabled = 0,
|
||||
Disabled = 1,
|
||||
}
|
||||
}
|
||||
7
EonaCat.Logger/Managers/ILogManager.cs
Normal file
7
EonaCat.Logger/Managers/ILogManager.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace EonaCat.Logger.Managers
|
||||
{
|
||||
public interface ILogManager
|
||||
{
|
||||
void Write(string message, ELogType logType = ELogType.INFO, ELogType? logLevel = null);
|
||||
}
|
||||
}
|
||||
292
EonaCat.Logger/Managers/LogHelper.cs
Normal file
292
EonaCat.Logger/Managers/LogHelper.cs
Normal file
@@ -0,0 +1,292 @@
|
||||
using EonaCat.Logger;
|
||||
using EonaCat.Logger.Managers;
|
||||
using EonaCat.Logger.Syslog;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace EonaCat.logger.Managers
|
||||
{
|
||||
public static class LogHelper
|
||||
{
|
||||
private static readonly object _fileLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// Format a message with the specified header
|
||||
/// </summary>
|
||||
/// <param name="settings">Logger settings</param>
|
||||
/// <param name="logType">logtype for the formatted message</param>
|
||||
/// <param name="currentMessage">The actual message to format with the header</param>
|
||||
/// <returns></returns>
|
||||
public static string FormatMessageWithHeader(LoggerSettings settings, ELogType logType, string currentMessage)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(currentMessage))
|
||||
{
|
||||
return currentMessage;
|
||||
}
|
||||
|
||||
if (settings == null)
|
||||
{
|
||||
return "[EonaCatLogger]" + " " + currentMessage;
|
||||
}
|
||||
|
||||
string header = settings.HeaderFormat;
|
||||
if (header.Contains("{ts}"))
|
||||
{
|
||||
header = header.Replace("{ts}", DateTime.Now.ToUniversalTime().ToString(settings.TimestampFormat));
|
||||
}
|
||||
|
||||
if (header.Contains("{host}"))
|
||||
{
|
||||
header = header.Replace("{host}", Dns.GetHostName());
|
||||
}
|
||||
|
||||
if (header.Contains("{thread}"))
|
||||
{
|
||||
header = header.Replace("{thread}", Thread.CurrentThread.ManagedThreadId.ToString());
|
||||
}
|
||||
|
||||
if (header.Contains("{sev}"))
|
||||
{
|
||||
header = header.Replace("{sev}", logType.ToString());
|
||||
}
|
||||
|
||||
string fullMessage = "[EonaCatLogger]" + " " + header + " " + currentMessage;
|
||||
return fullMessage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formats a given exception as a string
|
||||
/// </summary>
|
||||
/// <param name="exception">exception</param>
|
||||
/// <param name="module">The name of the module which called the code (optional)</param>
|
||||
/// <param name="method">The name of the method which waws called in code (optional)</param>
|
||||
/// <returns></returns>
|
||||
public static string FormatExceptionToMessage(this Exception exception, string module = null, string method = null)
|
||||
{
|
||||
if (exception == null) return string.Empty;
|
||||
var st = new StackTrace(exception, true);
|
||||
var frame = st.GetFrame(0);
|
||||
int fileLine = frame.GetFileLineNumber();
|
||||
string filename = frame.GetFileName();
|
||||
|
||||
string message =
|
||||
Environment.NewLine +
|
||||
"--- [EonaCatLogger] Exception details ---" + Environment.NewLine +
|
||||
(!string.IsNullOrEmpty(module) ? " Module : " + module + Environment.NewLine : "") +
|
||||
(!string.IsNullOrEmpty(method) ? " Method : " + method + Environment.NewLine : "") +
|
||||
" Type : " + exception.GetType().ToString() + Environment.NewLine;
|
||||
|
||||
if (exception.Data != null && exception.Data.Count > 0)
|
||||
{
|
||||
message += " Data : " + Environment.NewLine;
|
||||
foreach (DictionaryEntry curr in exception.Data)
|
||||
{
|
||||
message += " | " + curr.Key + ": " + curr.Value + Environment.NewLine;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
message += " Data : (none)" + Environment.NewLine;
|
||||
}
|
||||
|
||||
message +=
|
||||
" Inner : ";
|
||||
|
||||
if (exception.InnerException == null) message += "(null)" + Environment.NewLine;
|
||||
else
|
||||
{
|
||||
message += exception.InnerException.GetType().ToString() + Environment.NewLine;
|
||||
message +=
|
||||
" Message : " + exception.InnerException.Message + Environment.NewLine +
|
||||
" Source : " + exception.InnerException.Source + Environment.NewLine +
|
||||
" StackTrace : " + exception.InnerException.StackTrace + Environment.NewLine +
|
||||
" ToString : " + exception.InnerException.ToString() + Environment.NewLine;
|
||||
|
||||
if (exception.InnerException.Data != null && exception.InnerException.Data.Count > 0)
|
||||
{
|
||||
message += " Data : " + Environment.NewLine;
|
||||
foreach (DictionaryEntry curr in exception.Data)
|
||||
{
|
||||
message += " | " + curr.Key + ": " + curr.Value + Environment.NewLine;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
message += " Data : (none)" + Environment.NewLine;
|
||||
}
|
||||
}
|
||||
|
||||
message +=
|
||||
" Message : " + exception.Message + Environment.NewLine +
|
||||
" Source : " + exception.Source + Environment.NewLine +
|
||||
" StackTrace : " + exception.StackTrace + Environment.NewLine +
|
||||
" Line : " + fileLine + Environment.NewLine +
|
||||
" File : " + filename + Environment.NewLine +
|
||||
" ToString : " + exception.ToString() + Environment.NewLine +
|
||||
"---";
|
||||
return message;
|
||||
}
|
||||
|
||||
internal static void SendConsole(LoggerSettings settings, ELogType logType, string message)
|
||||
{
|
||||
if (settings == null) return;
|
||||
if (!settings.EnableConsole) return;
|
||||
if (string.IsNullOrWhiteSpace(message)) return;
|
||||
|
||||
if (settings.EnableColors)
|
||||
{
|
||||
ConsoleColor prevForeground = Console.ForegroundColor;
|
||||
ConsoleColor prevBackground = Console.BackgroundColor;
|
||||
|
||||
if (settings.Colors != null)
|
||||
{
|
||||
switch (logType)
|
||||
{
|
||||
case ELogType.DEBUG:
|
||||
Console.ForegroundColor = settings.Colors.Debug.Foreground;
|
||||
Console.BackgroundColor = settings.Colors.Debug.Background;
|
||||
break;
|
||||
case ELogType.INFO:
|
||||
Console.ForegroundColor = settings.Colors.Info.Foreground;
|
||||
Console.BackgroundColor = settings.Colors.Info.Background;
|
||||
break;
|
||||
case ELogType.WARNING:
|
||||
Console.ForegroundColor = settings.Colors.Warning.Foreground;
|
||||
Console.BackgroundColor = settings.Colors.Warning.Background;
|
||||
break;
|
||||
case ELogType.ERROR:
|
||||
Console.ForegroundColor = settings.Colors.Error.Foreground;
|
||||
Console.BackgroundColor = settings.Colors.Error.Background;
|
||||
break;
|
||||
case ELogType.TRAFFIC:
|
||||
Console.ForegroundColor = settings.Colors.Traffic.Foreground;
|
||||
Console.BackgroundColor = settings.Colors.Traffic.Background;
|
||||
break;
|
||||
case ELogType.CRITICAL:
|
||||
Console.ForegroundColor = settings.Colors.Critical.Foreground;
|
||||
Console.BackgroundColor = settings.Colors.Critical.Background;
|
||||
break;
|
||||
case ELogType.TRACE:
|
||||
Console.ForegroundColor = settings.Colors.Trace.Foreground;
|
||||
Console.BackgroundColor = settings.Colors.Trace.Background;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine(message);
|
||||
Console.ForegroundColor = prevForeground;
|
||||
Console.BackgroundColor = prevBackground;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(message);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void SendFile(ILogger logger, LoggerSettings settings, ELogType logType, string message, int maxTries = 3)
|
||||
{
|
||||
lock (_fileLock)
|
||||
{
|
||||
if (logger == null) return;
|
||||
if (settings == null) return;
|
||||
if (!settings.EnableFileLogging) return;
|
||||
if (string.IsNullOrWhiteSpace(message)) return;
|
||||
//logger.LogInformation(message);
|
||||
|
||||
int tries = 0;
|
||||
bool completed = false;
|
||||
while (!completed)
|
||||
{
|
||||
try
|
||||
{
|
||||
System.IO.StreamWriter file = new System.IO.StreamWriter($"{settings.FileLoggerOptions.LogDirectory}{Path.DirectorySeparatorChar}{settings.FileLoggerOptions.FileNamePrefix}_{DateTime.Now.ToString("yyyyMMdd")}.log", true);
|
||||
file.Write(message + Environment.NewLine);
|
||||
file.Close();
|
||||
completed = true;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
tries++;
|
||||
Task.Delay(100);
|
||||
if (tries >= maxTries)
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
if (logType == ELogType.CRITICAL)
|
||||
{
|
||||
logger.LogCritical(message);
|
||||
}
|
||||
else if (logType == ELogType.DEBUG)
|
||||
{
|
||||
logger.LogDebug(message);
|
||||
}
|
||||
else if (logType == ELogType.ERROR)
|
||||
{
|
||||
logger.LogError(message);
|
||||
}
|
||||
else if (logType == ELogType.INFO)
|
||||
{
|
||||
logger.LogInformation(message);
|
||||
}
|
||||
else if (logType == ELogType.TRACE)
|
||||
{
|
||||
logger.LogTrace(message);
|
||||
}
|
||||
else if (logType == ELogType.TRAFFIC)
|
||||
{
|
||||
logger.LogTrace($"[TRAFFIC] {message}");
|
||||
}
|
||||
else if (logType == ELogType.WARNING)
|
||||
{
|
||||
logger.LogWarning(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void SendToSysLogServers(LoggerSettings settings, string message)
|
||||
{
|
||||
if (settings == null) return;
|
||||
if (!settings.SendToSyslogServers) return;
|
||||
if (settings.SysLogServers == null) return;
|
||||
if (!settings.SysLogServers.Any()) return;
|
||||
if (string.IsNullOrWhiteSpace(message)) return;
|
||||
|
||||
byte[] data = Encoding.UTF8.GetBytes(message);
|
||||
|
||||
var sysLogServers = settings.SysLogServers.ToList();
|
||||
foreach (SyslogServer server in sysLogServers)
|
||||
{
|
||||
lock (server.SendLock)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(server.Hostname))
|
||||
{
|
||||
Console.WriteLine("Server hostname not specified, skipping syslog server");
|
||||
}
|
||||
if (server.Port < 0)
|
||||
{
|
||||
Console.WriteLine("Server port must be zero or greater, skipping syslog server");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
server.Udp.Send(data, data.Length);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,17 @@
|
||||
using EonaCat.Extensions;
|
||||
using EonaCat.logger.Managers;
|
||||
using EonaCat.Logger.Exceptions;
|
||||
using EonaCat.Logger.Extensions;
|
||||
using EonaCat.Logger.Helpers;
|
||||
using EonaCat.Logger.Syslog;
|
||||
using EonaCatLogger.EonaCatCoreLogger.Models;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -16,11 +20,15 @@ namespace EonaCat.Logger.Managers
|
||||
// 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.
|
||||
|
||||
public class LogManager : IDisposable
|
||||
public partial class LogManager : ILogManager, IDisposable
|
||||
{
|
||||
private readonly object _batton = new object();
|
||||
private DateTime _logDate;
|
||||
public event LogDelegate OnLog;
|
||||
public delegate void LogDelegate(LogManager logger, ELogType logLevel, EonaCatLogMessage message);
|
||||
|
||||
|
||||
public ELogType LogType;
|
||||
private ILoggerProvider LoggerProvider { get; set; }
|
||||
private ILoggerFactory LoggerFactory { get; set; }
|
||||
private ILogger Logger { get; set; }
|
||||
@@ -29,13 +37,50 @@ namespace EonaCat.Logger.Managers
|
||||
public bool IsRunning { get; private set; }
|
||||
|
||||
public StreamWriter Output { get; private set; }
|
||||
public string LogFolderPath { get; set; } = "logs";
|
||||
public FileLoggerOptions FileLoggerOptions { get; private set; }
|
||||
public int FileSizeLimit { get; set; } = 200 * 1024 * 1024;
|
||||
|
||||
public string CategoryName { get; set; }
|
||||
private LogManager Instance { get; set; }
|
||||
|
||||
public readonly string Id;
|
||||
|
||||
private bool _disposed;
|
||||
private static LogManager _instance;
|
||||
private LoggerSettings _settings;
|
||||
private CancellationTokenSource _TokenSource = new CancellationTokenSource();
|
||||
private CancellationToken _Token;
|
||||
|
||||
/// <summary>
|
||||
/// Default Logger Instance with it's default configuration
|
||||
/// </summary>
|
||||
public static LogManager Instance => InstanceInit();
|
||||
|
||||
/// <summary>
|
||||
/// Logging settings.
|
||||
/// </summary>
|
||||
public LoggerSettings Settings
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_settings == null)
|
||||
{
|
||||
_settings = new LoggerSettings();
|
||||
}
|
||||
return _settings;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_settings = value;
|
||||
}
|
||||
}
|
||||
|
||||
private static LogManager InstanceInit()
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = new LogManager(null, id: "EonaCat");
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
@@ -49,47 +94,20 @@ namespace EonaCat.Logger.Managers
|
||||
if (disposing)
|
||||
{
|
||||
StopLogging();
|
||||
_TokenSource.Cancel();
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
public static async Task DownloadLogAsync(HttpResponse response, string logFile, long limit)
|
||||
{
|
||||
using (FileStream fileStream = new FileStream(logFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
response.ContentType = "text/plain";
|
||||
response.Headers.Add("Content-Disposition", "attachment;filename=" + Path.GetFileName(logFile));
|
||||
|
||||
if (limit > fileStream.Length)
|
||||
{
|
||||
limit = fileStream.Length;
|
||||
}
|
||||
|
||||
using (OffsetStream offsetStream = new OffsetStream(fileStream, 0, limit))
|
||||
{
|
||||
using (Stream stream = response.Body)
|
||||
{
|
||||
offsetStream.CopyTo(stream);
|
||||
|
||||
if (fileStream.Length > limit)
|
||||
{
|
||||
byte[] buffer = Encoding.UTF8.GetBytes("####___EonaCatLogger_TRUNCATED___####");
|
||||
await stream.WriteAsync(buffer, 0, buffer.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void StartNewLog()
|
||||
{
|
||||
if (_TokenSource.IsCancellationRequested)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DateTime now = DateTime.Now;
|
||||
|
||||
if (IsRunning && now.Date > _logDate.Date)
|
||||
@@ -99,143 +117,157 @@ namespace EonaCat.Logger.Managers
|
||||
IsRunning = true;
|
||||
|
||||
IServiceCollection serviceCollection = new ServiceCollection();
|
||||
CreateDefaultFileLoggerOptions();
|
||||
|
||||
serviceCollection.AddLogging(builder => builder.AddFile(configuration =>
|
||||
serviceCollection.AddLogging(builder => builder.AddEonaCatFileLogger(configuration =>
|
||||
{
|
||||
configuration.BackgroundQueueSize = FileLoggerOptions.BackgroundQueueSize;
|
||||
configuration.BatchSize = FileLoggerOptions.BatchSize;
|
||||
configuration.FileNamePrefix = FileLoggerOptions.FileNamePrefix;
|
||||
configuration.FileSizeLimit = FileLoggerOptions.FileSizeLimit;
|
||||
configuration.FlushPeriod = FileLoggerOptions.FlushPeriod;
|
||||
configuration.IsEnabled = FileLoggerOptions.IsEnabled;
|
||||
configuration.LogDirectory = FileLoggerOptions.LogDirectory;
|
||||
configuration.RetainedFileCountLimit = FileLoggerOptions.RetainedFileCountLimit;
|
||||
configuration = Settings.FileLoggerOptions;
|
||||
}));
|
||||
|
||||
var serviceProvider = serviceCollection.BuildServiceProvider();
|
||||
LoggerProvider = serviceProvider.GetService<ILoggerProvider>();
|
||||
LoggerFactory = serviceProvider.GetService<ILoggerFactory>();
|
||||
|
||||
CategoryName = CategoryName ?? string.Empty;
|
||||
Logger = LoggerFactory.CreateLogger(CategoryName);
|
||||
|
||||
if (!Directory.Exists(FileLoggerOptions.LogDirectory))
|
||||
if (!Directory.Exists(Settings.FileLoggerOptions.LogDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(FileLoggerOptions.LogDirectory);
|
||||
Directory.CreateDirectory(Settings.FileLoggerOptions.LogDirectory);
|
||||
}
|
||||
|
||||
_logDate = now;
|
||||
|
||||
Write(now, "EonaCatLogger started.");
|
||||
Write(now, $"{DllInfo.ApplicationName} started.");
|
||||
}
|
||||
|
||||
private void CreateDefaultFileLoggerOptions()
|
||||
public void Assert(bool condition, string message)
|
||||
{
|
||||
if (FileLoggerOptions == null)
|
||||
if (!condition)
|
||||
{
|
||||
FileLoggerOptions = new FileLoggerOptions
|
||||
{
|
||||
LogDirectory = LogFolderPath,
|
||||
FileSizeLimit = FileSizeLimit
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteToFile(EonaCatLogMessage EonaCatLogMessage)
|
||||
{
|
||||
if (EonaCatLogMessage.LogType == ELogType.CRITICAL)
|
||||
{
|
||||
Instance.Logger.LogCritical(EonaCatLogMessage.Message);
|
||||
}
|
||||
else if (EonaCatLogMessage.LogType == ELogType.DEBUG)
|
||||
{
|
||||
Instance.Logger.LogDebug(EonaCatLogMessage.Message);
|
||||
}
|
||||
else if (EonaCatLogMessage.LogType == ELogType.ERROR)
|
||||
{
|
||||
Instance.Logger.LogError(EonaCatLogMessage.Message);
|
||||
}
|
||||
else if (EonaCatLogMessage.LogType == ELogType.INFO)
|
||||
{
|
||||
Instance.Logger.LogInformation(EonaCatLogMessage.Message);
|
||||
}
|
||||
else if (EonaCatLogMessage.LogType == ELogType.TRACE)
|
||||
{
|
||||
Instance.Logger.LogTrace(EonaCatLogMessage.Message);
|
||||
}
|
||||
else if (EonaCatLogMessage.LogType == ELogType.TRAFFIC)
|
||||
{
|
||||
Instance.Logger.LogTrace($"[TRAFFIC] {EonaCatLogMessage.Message}");
|
||||
}
|
||||
else if (EonaCatLogMessage.LogType == ELogType.WARNING)
|
||||
{
|
||||
Instance.Logger.LogWarning(EonaCatLogMessage.Message);
|
||||
throw new EonaCatLoggerAssertionException(message);
|
||||
}
|
||||
}
|
||||
|
||||
private void Write(DateTime dateTime, string message, ELogType logType = ELogType.INFO)
|
||||
{
|
||||
var EonaCatMessage = new EonaCatLogMessage { DateTime = dateTime, Message = message, LogType = logType };
|
||||
WriteToFile(EonaCatMessage);
|
||||
if (string.IsNullOrWhiteSpace(message)) return;
|
||||
if (logType < ELogType.INFO) return;
|
||||
|
||||
string remainder = "";
|
||||
string currentMessage;
|
||||
|
||||
if (message.Length > _settings.MaxMessageLength)
|
||||
{
|
||||
currentMessage = message.Substring(0, _settings.MaxMessageLength);
|
||||
remainder = message.Substring(_settings.MaxMessageLength, (message.Length - _settings.MaxMessageLength));
|
||||
}
|
||||
else
|
||||
{
|
||||
currentMessage = message;
|
||||
}
|
||||
|
||||
private LogManager()
|
||||
var fullMessage = LogHelper.FormatMessageWithHeader(_settings, logType, currentMessage);
|
||||
|
||||
LogHelper.SendConsole(_settings, logType, fullMessage);
|
||||
|
||||
LogHelper.SendFile(Logger, _settings, logType, fullMessage);
|
||||
|
||||
LogHelper.SendToSysLogServers(_settings, fullMessage);
|
||||
|
||||
if (!string.IsNullOrEmpty(remainder))
|
||||
{
|
||||
// Do nothing
|
||||
Write(dateTime, remainder, logType);
|
||||
}
|
||||
|
||||
public LogManager(FileLoggerOptions fileLoggerOptions)
|
||||
var EonaCatMessage = new EonaCatLogMessage { DateTime = dateTime, Message = currentMessage, LogType = logType };
|
||||
OnLog?.Invoke(this, logType, EonaCatMessage);
|
||||
}
|
||||
|
||||
public void Reset() => OnLog = null;
|
||||
|
||||
public LogManager(LoggerSettings settings, string serverIp, int serverPort, string id = "EonaCatLogger")
|
||||
{
|
||||
FileLoggerOptions = fileLoggerOptions;
|
||||
if (string.IsNullOrEmpty(serverIp)) throw new ArgumentNullException(nameof(serverIp));
|
||||
if (serverPort < 0) throw new ArgumentException("Server port must be zero or greater.");
|
||||
|
||||
settings.SysLogServers = new List<SyslogServer>();
|
||||
settings.SysLogServers.Add(new SyslogServer(serverIp, serverPort));
|
||||
|
||||
Id = id;
|
||||
Settings = settings;
|
||||
SetupLogManager();
|
||||
}
|
||||
|
||||
private void SetupLogManager()
|
||||
public LogManager(LoggerSettings settings, string id = "EonaCatLogger")
|
||||
{
|
||||
AppDomain.CurrentDomain.ProcessExit += ProcessExit;
|
||||
|
||||
Instance = this;
|
||||
|
||||
_logDate = DateTime.Now;
|
||||
|
||||
StartNewLog();
|
||||
Id = id;
|
||||
Settings = settings;
|
||||
SetupFileLogger(settings, null, true);
|
||||
SetupLogManager();
|
||||
}
|
||||
|
||||
private void ProcessExit(object sender, EventArgs e)
|
||||
private void SetupFileLogger(LoggerSettings settings = null, string logFolder = null, bool defaultPrefix = true)
|
||||
{
|
||||
Instance?.StopLogging();
|
||||
Thread.Sleep(1000);
|
||||
if (settings == null)
|
||||
{
|
||||
// Create default loggingSettings
|
||||
Settings = settings;
|
||||
settings = Settings;
|
||||
}
|
||||
|
||||
private void StopLogging()
|
||||
{
|
||||
Write(DateTime.Now, "EonaCatLogger stopped.");
|
||||
IsRunning = false;
|
||||
}
|
||||
if (!settings.EnableFileLogging) return;
|
||||
|
||||
public LogManager(string logFolder = null, bool defaultPrefix = true)
|
||||
{
|
||||
CreateDefaultFileLoggerOptions();
|
||||
if (logFolder != null)
|
||||
{
|
||||
FileLoggerOptions.LogDirectory = logFolder;
|
||||
Settings.FileLoggerOptions.LogDirectory = logFolder;
|
||||
}
|
||||
|
||||
if (defaultPrefix)
|
||||
{
|
||||
FileLoggerOptions.FileNamePrefix = "EonaCat";
|
||||
Settings.FileLoggerOptions.FileNamePrefix = "EonaCat";
|
||||
}
|
||||
else
|
||||
{
|
||||
FileLoggerOptions.FileNamePrefix = string.Empty;
|
||||
Settings.FileLoggerOptions.FileNamePrefix = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupLogManager()
|
||||
{
|
||||
_Token = _TokenSource.Token;
|
||||
AppDomain.CurrentDomain.ProcessExit += ProcessExit;
|
||||
|
||||
Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);
|
||||
|
||||
_logDate = DateTime.Now;
|
||||
}
|
||||
|
||||
void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
private void ProcessExit(object sender, EventArgs e)
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
private void StopLogging()
|
||||
{
|
||||
IsRunning = false;
|
||||
Write(DateTime.Now, $"{DllInfo.ApplicationName} stopped.");
|
||||
Task.Delay(500);
|
||||
}
|
||||
|
||||
public LogManager(string logFolder = null, bool defaultPrefix = true)
|
||||
{
|
||||
SetupFileLogger(null, logFolder, defaultPrefix);
|
||||
SetupLogManager();
|
||||
}
|
||||
|
||||
public void Write(Exception exception)
|
||||
public void Write(Exception exception, string module = null, string method = null, bool criticalException = false)
|
||||
{
|
||||
Write(exception.ToString());
|
||||
if (exception != null) return;
|
||||
Write(exception.FormatExceptionToMessage(module, method), criticalException ? ELogType.CRITICAL : ELogType.ERROR);
|
||||
}
|
||||
|
||||
public void Write(string message, ELogType logType = ELogType.INFO, ELogType? logLevel = null)
|
||||
@@ -256,7 +288,7 @@ namespace EonaCat.Logger.Managers
|
||||
StartNewLog();
|
||||
}
|
||||
|
||||
Write(now, $"{DllInfo.ApplicationName}: {message}", logType);
|
||||
Write(now, message, logType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -269,8 +301,12 @@ namespace EonaCat.Logger.Managers
|
||||
{
|
||||
File.Delete(CurrentLogFile);
|
||||
}
|
||||
StartNewLog();
|
||||
}
|
||||
}
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
173
EonaCat.Logger/Managers/LoggerSettings.cs
Normal file
173
EonaCat.Logger/Managers/LoggerSettings.cs
Normal file
@@ -0,0 +1,173 @@
|
||||
using System.IO;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using EonaCat.Logger.Syslog;
|
||||
using System.Runtime;
|
||||
|
||||
namespace EonaCat.Logger.Managers
|
||||
{
|
||||
/// <summary>
|
||||
/// Logger settings.
|
||||
/// </summary>
|
||||
public class LoggerSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Header format. Provide a string that specifies how the preamble of each message should be structured. You can use variables including:
|
||||
/// {ts}: UTC timestamp
|
||||
/// {host}: Hostname
|
||||
/// {thread}: Thread ID
|
||||
/// {sev}: Severity
|
||||
/// Default: {ts} {host} {thread} {sev}
|
||||
/// A space will be inserted between the header and the message.
|
||||
/// </summary>
|
||||
public string HeaderFormat
|
||||
{
|
||||
get
|
||||
{
|
||||
return _HeaderFormat;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrEmpty(value)) _HeaderFormat = "";
|
||||
else _HeaderFormat = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Timestamp format.
|
||||
/// </summary>
|
||||
public string TimestampFormat
|
||||
{
|
||||
get
|
||||
{
|
||||
return _TimestampFormat;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(HeaderFormat));
|
||||
_TimestampFormat = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enable or disable console logging.
|
||||
/// Settings this to true will first validate if a console exists.
|
||||
/// If a console is not available, it will be set to false.
|
||||
/// </summary>
|
||||
public bool EnableConsole
|
||||
{
|
||||
get
|
||||
{
|
||||
return _EnableConsole;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value) _EnableConsole = ConsoleExists();
|
||||
else _EnableConsole = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Minimum severity required to send a message.
|
||||
/// </summary>
|
||||
public ESeverity MinimumSeverity { get; set; } = ESeverity.Debug;
|
||||
|
||||
/// <summary>
|
||||
/// Enable or disable use of color for console messages.
|
||||
/// </summary>
|
||||
public bool EnableColors { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Colors to use for console messages based on message severity.
|
||||
/// </summary>
|
||||
public ColorSchema Colors
|
||||
{
|
||||
get
|
||||
{
|
||||
return _colors;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(Colors));
|
||||
}
|
||||
_colors = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool SendToSyslogServers { get; set; }
|
||||
|
||||
public List<SyslogServer> SysLogServers { get; set; } = new List<SyslogServer> { new SyslogServer("127.0.0.1", 514) };
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the fileLogging is enabled
|
||||
/// </summary>
|
||||
public bool EnableFileLogging { get; set; } = true;
|
||||
|
||||
private FileLoggerOptions _fileLoggerOptions;
|
||||
|
||||
/// <summary>
|
||||
/// FileLogger settings.
|
||||
/// </summary>
|
||||
public FileLoggerOptions FileLoggerOptions
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_fileLoggerOptions == null)
|
||||
{
|
||||
_fileLoggerOptions = CreateDefaultFileLoggerOptions();
|
||||
}
|
||||
return _fileLoggerOptions;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_fileLoggerOptions = value;
|
||||
}
|
||||
}
|
||||
|
||||
private FileLoggerOptions CreateDefaultFileLoggerOptions()
|
||||
{
|
||||
return new FileLoggerOptions();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maximum message length. Must be greater than or equal to 32. Default is 1024.
|
||||
/// </summary>
|
||||
public int MaxMessageLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return _MaxMessageLength;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < 32) throw new ArgumentException("Maximum message length must be at least 32.");
|
||||
_MaxMessageLength = value;
|
||||
}
|
||||
}
|
||||
|
||||
private string _HeaderFormat = "{ts} {host} {thread} {sev}";
|
||||
private string _TimestampFormat = "yyyy-MM-dd HH:mm:ss";
|
||||
private bool _EnableConsole = true;
|
||||
private int _MaxMessageLength = 1024;
|
||||
private ColorSchema _colors = new ColorSchema();
|
||||
|
||||
|
||||
private bool ConsoleExists()
|
||||
{
|
||||
try
|
||||
{
|
||||
bool test1 = Environment.UserInteractive;
|
||||
bool test2 = Console.WindowHeight > 0;
|
||||
return test1 && test2;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
89
EonaCat.Logger/Syslog/SyslogServer.cs
Normal file
89
EonaCat.Logger/Syslog/SyslogServer.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
|
||||
namespace EonaCat.Logger.Syslog
|
||||
{
|
||||
/// <summary>
|
||||
/// Syslog server.
|
||||
/// </summary>
|
||||
public class SyslogServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Hostname.
|
||||
/// </summary>
|
||||
public string Hostname
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Hostname;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(Hostname));
|
||||
_Hostname = value;
|
||||
|
||||
SetUdp();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UDP port.
|
||||
/// </summary>
|
||||
public int Port
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Port;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < 0) throw new ArgumentException("Port must be zero or greater.");
|
||||
_Port = value;
|
||||
|
||||
SetUdp();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// IP:port of the server.
|
||||
/// </summary>
|
||||
public string IpPort
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Hostname + ":" + _Port;
|
||||
}
|
||||
}
|
||||
|
||||
internal readonly object SendLock = new object();
|
||||
internal UdpClient Udp = null;
|
||||
private string _Hostname = "127.0.0.1";
|
||||
private int _Port = 514;
|
||||
|
||||
/// <summary>
|
||||
/// Instantiate the object.
|
||||
/// </summary>
|
||||
public SyslogServer()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Instantiate the object.
|
||||
/// </summary>
|
||||
/// <param name="hostname">Hostname.</param>
|
||||
/// <param name="port">Port.</param>
|
||||
public SyslogServer(string hostname = "127.0.0.1", int port = 514)
|
||||
{
|
||||
Hostname = hostname;
|
||||
Port = port;
|
||||
}
|
||||
|
||||
private void SetUdp()
|
||||
{
|
||||
Udp = null;
|
||||
Udp = new UdpClient(_Hostname, _Port);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,3 +3,11 @@
|
||||
EonaCat Logger
|
||||
|
||||
Log application information to log files
|
||||
|
||||
|
||||
Be sure the following dependencies are added:
|
||||
|
||||
Microsoft.Extensions.Logging.Abstractions
|
||||
Microsoft.Extensions.DependencyInjection.Abstractions
|
||||
Microsoft.Extensions.DependencyInjection
|
||||
Microsoft.Extensions.Logging
|
||||
Reference in New Issue
Block a user