initial commit
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="7.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,17 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace Common.Core.Extensions;
|
||||
|
||||
public static class ConfigurationExtension
|
||||
{
|
||||
public static IConfigurationBuilder Initialize(this IConfigurationBuilder builder)
|
||||
{
|
||||
string env = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? "Production";
|
||||
|
||||
return builder
|
||||
.SetBasePath(Directory.GetCurrentDirectory())
|
||||
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||
.AddJsonFile($"appsettings.{env}.json", optional: true, reloadOnChange: true)
|
||||
.AddEnvironmentVariables();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace Common.Core.Extensions;
|
||||
|
||||
public static class ServicesExtension
|
||||
{
|
||||
public static TModel? TryGetService<TModel>(this IServiceProvider serviceProvider) where TModel : class
|
||||
{
|
||||
try
|
||||
{
|
||||
return (TModel?)serviceProvider.GetService(typeof(TModel));
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
// ignore as we do not care...
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace Common.Core;
|
||||
|
||||
public class AppSettings<TOption>
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
public AppSettings(IConfigurationSection configSection, string? key = null)
|
||||
{
|
||||
_configSection = configSection;
|
||||
|
||||
// ReSharper disable once VirtualMemberCallInConstructor
|
||||
GetValue(key);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
|
||||
protected static AppSettings<TOption>? _appSetting;
|
||||
|
||||
// ReSharper disable once StaticMemberInGenericType
|
||||
protected static IConfigurationSection? _configSection;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
public TOption? Value { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public static TOption? Current(string section, string? key = null)
|
||||
{
|
||||
_appSetting = GetCurrentSettings(section, key);
|
||||
return _appSetting.Value;
|
||||
}
|
||||
|
||||
public static AppSettings<TOption> GetCurrentSettings(string section, string? key = null)
|
||||
{
|
||||
string env = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? "Production";
|
||||
|
||||
IConfigurationBuilder builder = new ConfigurationBuilder()
|
||||
.SetBasePath(Directory.GetCurrentDirectory())
|
||||
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||
.AddJsonFile($"appsettings.{env}.json", optional: true, reloadOnChange: true)
|
||||
.AddEnvironmentVariables();
|
||||
|
||||
IConfigurationRoot configuration = builder.Build();
|
||||
|
||||
if (string.IsNullOrEmpty(section))
|
||||
section = "AppSettings"; // default
|
||||
|
||||
AppSettings<TOption> settings = new AppSettings<TOption>(configuration.GetSection(section), key);
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
protected virtual void GetValue(string? key)
|
||||
{
|
||||
if (key is null)
|
||||
{
|
||||
// no key, so must be a class/strut object
|
||||
Value = Activator.CreateInstance<TOption>();
|
||||
_configSection!.Bind(Value);
|
||||
return;
|
||||
}
|
||||
|
||||
Type optionType = typeof(TOption);
|
||||
|
||||
if ((optionType == typeof(string) ||
|
||||
optionType == typeof(int) ||
|
||||
optionType == typeof(long) ||
|
||||
optionType == typeof(decimal) ||
|
||||
optionType == typeof(float) ||
|
||||
optionType == typeof(double))
|
||||
&& _configSection != null)
|
||||
{
|
||||
// we must be retrieving a value
|
||||
Value = _configSection.GetValue<TOption>(key);
|
||||
return;
|
||||
}
|
||||
|
||||
// Could not find a supported type
|
||||
throw new InvalidCastException($"Type {typeof(TOption).Name} is invalid");
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
namespace Microsoft.Extensions.Logging;
|
||||
|
||||
public static class LoggerExtensions
|
||||
{
|
||||
public static void Emit(this ILogger logger, EventId eventId,
|
||||
LogLevel logLevel, string message, Exception? exception = null, params object?[] args)
|
||||
{
|
||||
if (logger is null)
|
||||
return;
|
||||
|
||||
//if (!logger.IsEnabled(logLevel))
|
||||
// return;
|
||||
|
||||
switch (logLevel)
|
||||
{
|
||||
case LogLevel.Trace:
|
||||
logger.LogTrace(eventId, message, args);
|
||||
break;
|
||||
|
||||
case LogLevel.Debug:
|
||||
logger.LogDebug(eventId, message, args);
|
||||
break;
|
||||
|
||||
case LogLevel.Information:
|
||||
logger.LogInformation(eventId, message, args);
|
||||
break;
|
||||
|
||||
case LogLevel.Warning:
|
||||
logger.LogWarning(eventId, exception, message, args);
|
||||
break;
|
||||
|
||||
case LogLevel.Error:
|
||||
logger.LogError(eventId, exception, message, args);
|
||||
break;
|
||||
|
||||
case LogLevel.Critical:
|
||||
logger.LogCritical(eventId, exception, message, args);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void TestPattern(this ILogger logger, EventId eventId)
|
||||
{
|
||||
Exception exception = new Exception("Test Error Message");
|
||||
|
||||
logger.Emit(eventId, LogLevel.Trace, "Trace Test Pattern");
|
||||
logger.Emit(eventId, LogLevel.Debug, "Debug Test Pattern");
|
||||
logger.Emit(eventId, LogLevel.Information, "Information Test Pattern");
|
||||
logger.Emit(eventId, LogLevel.Warning, "Warning Test Pattern");
|
||||
logger.Emit(eventId, LogLevel.Error, "Error Test Pattern", exception);
|
||||
logger.Emit(eventId, LogLevel.Critical, "Critical Test Pattern", exception);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Mvvm.Core\Mvvm.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Drawing;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace LogViewer.Core;
|
||||
|
||||
public class DataStoreLoggerConfiguration
|
||||
{
|
||||
#region Properties
|
||||
|
||||
public EventId EventId { get; set; }
|
||||
|
||||
public Dictionary<LogLevel, LogEntryColor> Colors { get; } = new()
|
||||
{
|
||||
[LogLevel.Trace] = new() { Foreground = Color.DarkGray },
|
||||
[LogLevel.Debug] = new() { Foreground = Color.Gray },
|
||||
[LogLevel.Information] = new(),
|
||||
[LogLevel.Warning] = new() { Foreground = Color.Orange},
|
||||
[LogLevel.Error] = new() { Foreground = Color.White, Background = Color.OrangeRed },
|
||||
[LogLevel.Critical] = new() { Foreground=Color.White, Background = Color.Red },
|
||||
[LogLevel.None] = new(),
|
||||
};
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace LogViewer.Core;
|
||||
|
||||
public interface ILogDataStore
|
||||
{
|
||||
ObservableCollection<LogModel> Entries { get; }
|
||||
void AddEntry(LogModel logModel);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace LogViewer.Core;
|
||||
|
||||
public interface ILogDataStoreImpl
|
||||
{
|
||||
public ILogDataStore DataStore { get; }
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace LogViewer.Core;
|
||||
|
||||
public class LogDataStore : ILogDataStore
|
||||
{
|
||||
#region Fields
|
||||
|
||||
private static readonly SemaphoreSlim _semaphore = new(initialCount: 1);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
public ObservableCollection<LogModel> Entries { get; } = new();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public virtual void AddEntry(LogModel logModel)
|
||||
{
|
||||
// ensure only one operation at time from multiple threads
|
||||
_semaphore.Wait();
|
||||
|
||||
Entries.Add(logModel);
|
||||
|
||||
_semaphore.Release();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using System.Drawing;
|
||||
|
||||
namespace LogViewer.Core;
|
||||
|
||||
public class LogEntryColor
|
||||
{
|
||||
public Color Foreground { get; set; } = Color.Black;
|
||||
public Color Background { get; set; } = Color.Transparent;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace LogViewer.Core;
|
||||
|
||||
public class LogModel
|
||||
{
|
||||
#region Properties
|
||||
|
||||
public DateTime Timestamp { get; set; }
|
||||
|
||||
public LogLevel LogLevel { get; set; }
|
||||
|
||||
public EventId EventId { get; set; }
|
||||
|
||||
public object? State { get; set; }
|
||||
|
||||
public string? Exception { get; set; }
|
||||
|
||||
public LogEntryColor? Color { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using Mvvm.Core;
|
||||
|
||||
namespace LogViewer.Core.ViewModels;
|
||||
|
||||
public class LogViewerControlViewModel : ViewModel, ILogDataStoreImpl
|
||||
{
|
||||
#region Constructor
|
||||
|
||||
public LogViewerControlViewModel(ILogDataStore dataStore)
|
||||
{
|
||||
DataStore = dataStore;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
public ILogDataStore DataStore { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using System.Diagnostics;
|
||||
using LogViewer.Core;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MsLogger.Core;
|
||||
|
||||
public class DataStoreLogger: ILogger
|
||||
{
|
||||
// ref: https://learn.microsoft.com/en-us/dotnet/core/extensions/custom-logging-provider
|
||||
|
||||
#region Constructor
|
||||
|
||||
public DataStoreLogger(string name, Func<DataStoreLoggerConfiguration> getCurrentConfig, ILogDataStore dataStore)
|
||||
{
|
||||
(_name, _getCurrentConfig) = (name, getCurrentConfig);
|
||||
_dataStore = dataStore;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
|
||||
private readonly ILogDataStore _dataStore;
|
||||
private readonly string _name;
|
||||
private readonly Func<DataStoreLoggerConfiguration> _getCurrentConfig;
|
||||
|
||||
#endregion
|
||||
|
||||
#region methods
|
||||
|
||||
public IDisposable BeginScope<TState>(TState state) where TState : notnull => default!;
|
||||
|
||||
public bool IsEnabled(LogLevel logLevel) => true;
|
||||
|
||||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception, string> formatter)
|
||||
{
|
||||
// check if we are logging for passed log level
|
||||
if (!IsEnabled(logLevel))
|
||||
return;
|
||||
|
||||
DataStoreLoggerConfiguration config = _getCurrentConfig();
|
||||
|
||||
_dataStore.AddEntry(new()
|
||||
{
|
||||
Timestamp = DateTime.UtcNow,
|
||||
LogLevel = logLevel,
|
||||
// do we override the default EventId if it exists?
|
||||
EventId = eventId.Id == 0 && config.EventId != 0 ? config.EventId : eventId,
|
||||
State = state,
|
||||
Exception = exception?.Message ?? (logLevel == LogLevel.Error ? state?.ToString() ?? "" : ""),
|
||||
Color = config.Colors[logLevel],
|
||||
});
|
||||
|
||||
Debug.WriteLine($"--- [{logLevel.ToString()[..3]}] {_name} - {formatter(state, exception!)}");
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System.Collections.Concurrent;
|
||||
using LogViewer.Core;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace MsLogger.Core;
|
||||
|
||||
public class DataStoreLoggerProvider: ILoggerProvider
|
||||
{
|
||||
|
||||
#region Constructor
|
||||
|
||||
public DataStoreLoggerProvider(IOptionsMonitor<DataStoreLoggerConfiguration> config, ILogDataStore dataStore)
|
||||
{
|
||||
_dataStore = dataStore;
|
||||
_currentConfig = config.CurrentValue;
|
||||
_onChangeToken = config.OnChange(updatedConfig => _currentConfig = updatedConfig);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region fields
|
||||
|
||||
private DataStoreLoggerConfiguration _currentConfig;
|
||||
|
||||
private readonly IDisposable? _onChangeToken;
|
||||
protected readonly ILogDataStore _dataStore;
|
||||
|
||||
protected readonly ConcurrentDictionary<string, DataStoreLogger> _loggers = new();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public ILogger CreateLogger(string categoryName)
|
||||
=> _loggers.GetOrAdd(categoryName, name => new DataStoreLogger(name, GetCurrentConfig, _dataStore));
|
||||
|
||||
protected DataStoreLoggerConfiguration GetCurrentConfig()
|
||||
=> _currentConfig;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_loggers.Clear();
|
||||
_onChangeToken?.Dispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using LogViewer.Core;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MsLogger.Core;
|
||||
|
||||
public static class ServicesExtension
|
||||
{
|
||||
public static ILoggingBuilder AddDefaultDataStoreLogger(this ILoggingBuilder builder)
|
||||
{
|
||||
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, DataStoreLoggerProvider>());
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static ILoggingBuilder AddDefaultDataStoreLogger(this ILoggingBuilder builder, Action<DataStoreLoggerConfiguration> configure)
|
||||
{
|
||||
builder.AddDefaultDataStoreLogger();
|
||||
builder.Services.Configure(configure);
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LogViewer.Core\LogViewer.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,21 @@
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Mvvm.Core;
|
||||
|
||||
public class ObservableObject : INotifyPropertyChanged
|
||||
{
|
||||
protected bool Set<TValue>(ref TValue field, TValue newValue, [CallerMemberName] string? propertyName = null)
|
||||
{
|
||||
if (EqualityComparer<TValue>.Default.Equals(field, newValue)) return false;
|
||||
field = newValue;
|
||||
OnPropertyChanged(propertyName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
|
||||
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace Mvvm.Core;
|
||||
|
||||
public class ViewModel : ObservableObject { /* skip */ }
|
||||
@@ -0,0 +1,94 @@
|
||||
using Serilog.Events;
|
||||
using LogViewer.Core;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Serilog.Core;
|
||||
|
||||
namespace Serilog.Sinks.LogView.Core;
|
||||
|
||||
public class DataStoreLoggerSink : ILogEventSink
|
||||
{
|
||||
protected readonly Func<ILogDataStore> _dataStoreProvider;
|
||||
|
||||
private readonly IFormatProvider? _formatProvider;
|
||||
private readonly Func<DataStoreLoggerConfiguration>? _getCurrentConfig;
|
||||
|
||||
public DataStoreLoggerSink(Func<ILogDataStore> dataStoreProvider,
|
||||
Func<DataStoreLoggerConfiguration>? getCurrentConfig = null,
|
||||
IFormatProvider? formatProvider = null)
|
||||
{
|
||||
_formatProvider = formatProvider;
|
||||
_dataStoreProvider = dataStoreProvider;
|
||||
_getCurrentConfig = getCurrentConfig;
|
||||
}
|
||||
|
||||
public void Emit(LogEvent logEvent)
|
||||
{
|
||||
LogLevel logLevel = logEvent.Level switch
|
||||
{
|
||||
LogEventLevel.Verbose => LogLevel.Trace,
|
||||
LogEventLevel.Debug => LogLevel.Debug,
|
||||
LogEventLevel.Warning => LogLevel.Warning,
|
||||
LogEventLevel.Error => LogLevel.Error,
|
||||
LogEventLevel.Fatal => LogLevel.Critical,
|
||||
_ => LogLevel.Information
|
||||
};
|
||||
|
||||
DataStoreLoggerConfiguration config = _getCurrentConfig?.Invoke() ?? new DataStoreLoggerConfiguration();
|
||||
|
||||
EventId eventId = EventIdFactory(logEvent);
|
||||
if (eventId.Id == 0 && config.EventId != 0)
|
||||
eventId = config.EventId;
|
||||
|
||||
string message = logEvent.RenderMessage(_formatProvider);
|
||||
|
||||
string exception = logEvent.Exception?.Message ?? (logEvent.Level >= LogEventLevel.Error ? message : string.Empty);
|
||||
|
||||
LogEntryColor color = config.Colors[logLevel];
|
||||
|
||||
AddLogEntry(logLevel, eventId, message, exception, color);
|
||||
}
|
||||
|
||||
protected virtual void AddLogEntry(LogLevel logLevel, EventId eventId, string message, string exception, LogEntryColor color)
|
||||
{
|
||||
ILogDataStore? dataStore = _dataStoreProvider.Invoke();
|
||||
|
||||
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
|
||||
if (dataStore == null)
|
||||
return; // app is shutting down
|
||||
|
||||
dataStore.AddEntry(new()
|
||||
{
|
||||
Timestamp = DateTime.UtcNow,
|
||||
LogLevel = logLevel,
|
||||
EventId = eventId,
|
||||
State = message,
|
||||
Exception = exception,
|
||||
Color = color
|
||||
});
|
||||
}
|
||||
|
||||
private static EventId EventIdFactory(LogEvent logEvent)
|
||||
{
|
||||
EventId eventId;
|
||||
if (!logEvent.Properties.TryGetValue("EventId", out LogEventPropertyValue? src))
|
||||
return new();
|
||||
|
||||
int? id = null;
|
||||
string? eventName = null;
|
||||
|
||||
// ref: https://stackoverflow.com/a/56722516
|
||||
StructureValue? value = src as StructureValue;
|
||||
|
||||
LogEventProperty? idProperty = value!.Properties.FirstOrDefault(x => x.Name.Equals("Id"));
|
||||
if (idProperty is not null)
|
||||
id = int.Parse(idProperty.Value.ToString());
|
||||
|
||||
LogEventProperty? nameProperty = value.Properties.FirstOrDefault(x => x.Name.Equals("Name"));
|
||||
if (nameProperty is not null)
|
||||
eventName = nameProperty.Value.ToString().Trim('"');
|
||||
|
||||
eventId = new EventId(id ?? 0, eventName ?? string.Empty);
|
||||
|
||||
return eventId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using Serilog.Configuration;
|
||||
using LogViewer.Core;
|
||||
|
||||
namespace Serilog.Sinks.LogView.Core;
|
||||
|
||||
public static class DataStoreLoggerSinkExtensions
|
||||
{
|
||||
public static LoggerConfiguration DataStoreLoggerSink
|
||||
(
|
||||
this LoggerSinkConfiguration loggerConfiguration,
|
||||
Func<ILogDataStore> dataStoreProvider,
|
||||
Action<DataStoreLoggerConfiguration>? configuration = null,
|
||||
IFormatProvider formatProvider = null!
|
||||
)
|
||||
=> loggerConfiguration.Sink(new DataStoreLoggerSink(dataStoreProvider, GetConfig(configuration), formatProvider));
|
||||
|
||||
private static Func<DataStoreLoggerConfiguration> GetConfig(Action<DataStoreLoggerConfiguration>? configuration)
|
||||
{
|
||||
// convert from Action to Func delegate to pass data
|
||||
DataStoreLoggerConfiguration data = new();
|
||||
configuration?.Invoke(data);
|
||||
return () => data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Serilog" Version="2.12.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LogViewer.Core\LogViewer.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user