Removing serilog from server
This commit is contained in:
parent
e236927f54
commit
52642ccb25
15 changed files with 176 additions and 130 deletions
|
|
@ -4,7 +4,6 @@ using LANCommander.Server.Data.Models;
|
|||
using LANCommander.Server.Extensions;
|
||||
using LANCommander.Server.Services;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Serilog;
|
||||
using System.DirectoryServices.AccountManagement;
|
||||
using System.Security.Claims;
|
||||
using File = System.IO.File;
|
||||
|
|
@ -30,6 +29,7 @@ public static class SaveEndpoints
|
|||
|
||||
public static async Task<IResult> GetAsync(
|
||||
ClaimsPrincipal userPrincipal,
|
||||
[FromServices] ILogger<Program> logger,
|
||||
[FromServices] UserService userService,
|
||||
[FromServices] GameSaveService saveService)
|
||||
{
|
||||
|
|
@ -37,7 +37,7 @@ public static class SaveEndpoints
|
|||
|
||||
if (user == null)
|
||||
{
|
||||
Log.Error("Could not find user from claim principal: {UserName}", userPrincipal?.Identity?.Name);
|
||||
logger.LogError("Could not find user from claim principal: {UserName}", userPrincipal?.Identity?.Name);
|
||||
|
||||
return TypedResults.Unauthorized();
|
||||
}
|
||||
|
|
@ -50,6 +50,7 @@ public static class SaveEndpoints
|
|||
public static async Task<IResult> GetByIdAsync(
|
||||
Guid id,
|
||||
ClaimsPrincipal userPrincipal,
|
||||
[FromServices] ILogger<Program> logger,
|
||||
[FromServices] UserService userService,
|
||||
[FromServices] GameSaveService saveService)
|
||||
{
|
||||
|
|
@ -57,7 +58,7 @@ public static class SaveEndpoints
|
|||
|
||||
if (user == null)
|
||||
{
|
||||
Log.Error("Could not find user from claim principal: {UserName}", userPrincipal?.Identity?.Name);
|
||||
logger.LogError("Could not find user from claim principal: {UserName}", userPrincipal?.Identity?.Name);
|
||||
|
||||
return TypedResults.Unauthorized();
|
||||
}
|
||||
|
|
@ -73,6 +74,7 @@ public static class SaveEndpoints
|
|||
public static async Task<IResult> DeleteByIdAsync(
|
||||
Guid id,
|
||||
ClaimsPrincipal userPrincipal,
|
||||
[FromServices] ILogger<Program> logger,
|
||||
[FromServices] UserService userService,
|
||||
[FromServices] GameSaveService saveService)
|
||||
{
|
||||
|
|
@ -80,7 +82,7 @@ public static class SaveEndpoints
|
|||
|
||||
if (user == null)
|
||||
{
|
||||
Log.Error("Could not find user from claim principal: {UserName}", userPrincipal?.Identity?.Name);
|
||||
logger.LogError("Could not find user from claim principal: {UserName}", userPrincipal?.Identity?.Name);
|
||||
|
||||
return TypedResults.Unauthorized();
|
||||
}
|
||||
|
|
@ -98,6 +100,7 @@ public static class SaveEndpoints
|
|||
public static async Task<IResult> GetSavesByGameAsync(
|
||||
Guid gameId,
|
||||
ClaimsPrincipal userPrincipal,
|
||||
[FromServices] ILogger<Program> logger,
|
||||
[FromServices] UserService userService,
|
||||
[FromServices] GameSaveService saveService)
|
||||
{
|
||||
|
|
@ -105,7 +108,7 @@ public static class SaveEndpoints
|
|||
|
||||
if (user == null)
|
||||
{
|
||||
Log.Error("Could not find user from claim principal: {UserName}", userPrincipal?.Identity?.Name);
|
||||
logger.LogError("Could not find user from claim principal: {UserName}", userPrincipal?.Identity?.Name);
|
||||
|
||||
return TypedResults.Unauthorized();
|
||||
}
|
||||
|
|
@ -118,6 +121,7 @@ public static class SaveEndpoints
|
|||
public static async Task<IResult> GetLatestSaveByGameAsync(
|
||||
Guid gameId,
|
||||
ClaimsPrincipal userPrincipal,
|
||||
[FromServices] ILogger<Program> logger,
|
||||
[FromServices] IMapper mapper,
|
||||
[FromServices] UserService userService,
|
||||
[FromServices] GameSaveService saveService)
|
||||
|
|
@ -126,7 +130,7 @@ public static class SaveEndpoints
|
|||
|
||||
if (user == null)
|
||||
{
|
||||
Log.Error("Could not find user from claim principal: {UserName}", userPrincipal?.Identity?.Name);
|
||||
logger.LogError("Could not find user from claim principal: {UserName}", userPrincipal?.Identity?.Name);
|
||||
|
||||
return TypedResults.Unauthorized();
|
||||
}
|
||||
|
|
@ -144,6 +148,7 @@ public static class SaveEndpoints
|
|||
public static async Task<IResult> DownloadLatestSaveByGameAsync(
|
||||
Guid gameId,
|
||||
ClaimsPrincipal userPrincipal,
|
||||
[FromServices] ILogger<Program> logger,
|
||||
[FromServices] UserService userService,
|
||||
[FromServices] GameSaveService saveService)
|
||||
{
|
||||
|
|
@ -151,7 +156,7 @@ public static class SaveEndpoints
|
|||
|
||||
if (user == null)
|
||||
{
|
||||
Log.Error("Could not find user from claim principal: {UserName}", userPrincipal?.Identity?.Name);
|
||||
logger.LogError("Could not find user from claim principal: {UserName}", userPrincipal?.Identity?.Name);
|
||||
|
||||
return TypedResults.Unauthorized();
|
||||
}
|
||||
|
|
@ -178,6 +183,7 @@ public static class SaveEndpoints
|
|||
public static async Task<IResult> DownloadSaveByIdAsync(
|
||||
Guid id,
|
||||
ClaimsPrincipal userPrincipal,
|
||||
[FromServices] ILogger<Program> logger,
|
||||
[FromServices] UserService userService,
|
||||
[FromServices] GameSaveService saveService)
|
||||
{
|
||||
|
|
@ -185,7 +191,7 @@ public static class SaveEndpoints
|
|||
|
||||
if (user == null)
|
||||
{
|
||||
Log.Error("Could not find user from claim principal: {UserName}", userPrincipal?.Identity?.Name);
|
||||
logger.LogError("Could not find user from claim principal: {UserName}", userPrincipal?.Identity?.Name);
|
||||
|
||||
return TypedResults.Unauthorized();
|
||||
}
|
||||
|
|
@ -209,6 +215,7 @@ public static class SaveEndpoints
|
|||
Guid gameId,
|
||||
ClaimsPrincipal userPrincipal,
|
||||
HttpContext httpContext,
|
||||
[FromServices] ILogger<Program> logger,
|
||||
[FromServices] SettingsProvider<Settings.Settings> settingsProvider,
|
||||
[FromServices] IMapper mapper,
|
||||
[FromServices] UserService userService,
|
||||
|
|
@ -220,7 +227,7 @@ public static class SaveEndpoints
|
|||
|
||||
if (user == null)
|
||||
{
|
||||
Log.Error("Could not find user from claim principal: {UserName}", userPrincipal?.Identity?.Name);
|
||||
logger.LogError("Could not find user from claim principal: {UserName}", userPrincipal?.Identity?.Name);
|
||||
|
||||
return TypedResults.Unauthorized();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
using LANCommander.SDK;
|
||||
using LANCommander.Server.Services;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Serilog.Events;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
|
||||
namespace LANCommander.Server.Hubs
|
||||
{
|
||||
|
|
@ -9,14 +6,13 @@ namespace LANCommander.Server.Hubs
|
|||
{
|
||||
public override async Task OnConnectedAsync()
|
||||
{
|
||||
Clients.Caller.SendAsync("Log", "Connected to server logging provider!", LogEventLevel.Information, DateTime.Now);
|
||||
await Clients.Caller.SendAsync("Log", "Connected to server logging provider!", LogLevel.Information, DateTime.Now);
|
||||
await base.OnConnectedAsync();
|
||||
}
|
||||
|
||||
public static async Task Log(IHubContext<LoggingHub> context, string message, LogEvent logEvent)
|
||||
public static async Task Log(IHubContext<LoggingHub> context, string message, LogLevel logLevel, DateTime timestamp)
|
||||
{
|
||||
|
||||
await context.Clients.All.SendAsync("Log", message, logEvent.Level, logEvent.Timestamp.DateTime);
|
||||
await context.Clients.All.SendAsync("Log", message, logLevel, timestamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -85,7 +85,6 @@
|
|||
<PackageReference Include="AntDesign.Charts" />
|
||||
<PackageReference Include="CaseConverter" />
|
||||
<PackageReference Include="CoreRCON" />
|
||||
<PackageReference Include="Elastic.Serilog.Sinks" />
|
||||
<PackageReference Include="Hangfire.AspNetCore" />
|
||||
<PackageReference Include="Hangfire.Core" />
|
||||
<PackageReference Include="Hangfire.InMemory" />
|
||||
|
|
@ -113,12 +112,6 @@
|
|||
<PackageReference Include="Razor.Templating.Core" />
|
||||
<PackageReference Include="RegParserDotNet" />
|
||||
<PackageReference Include="Scalar.AspNetCore" />
|
||||
<PackageReference Include="Serilog" />
|
||||
<PackageReference Include="Serilog.AspNetCore" />
|
||||
<PackageReference Include="Serilog.Extensions.Logging" />
|
||||
<PackageReference Include="Serilog.Sinks.AspNetCore.App.SignalR" />
|
||||
<PackageReference Include="Serilog.Sinks.File" />
|
||||
<PackageReference Include="Serilog.Sinks.Seq" />
|
||||
<PackageReference Include="System.Diagnostics.PerformanceCounter" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
55
LANCommander.Server/Logging/SignalRLoggerProvider.cs
Normal file
55
LANCommander.Server/Logging/SignalRLoggerProvider.cs
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
using LANCommander.Server.Hubs;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
|
||||
namespace LANCommander.Server.Logging;
|
||||
|
||||
public class SignalRLoggerProvider(IServiceProvider serviceProvider, LogLevel minimumLevel = LogLevel.Information) : ILoggerProvider
|
||||
{
|
||||
public ILogger CreateLogger(string categoryName) => new SignalRLogger(serviceProvider, minimumLevel);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
private class SignalRLogger(IServiceProvider serviceProvider, LogLevel minimumLevel) : ILogger
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider = serviceProvider;
|
||||
private readonly LogLevel _minimumLevel = minimumLevel;
|
||||
|
||||
public IDisposable? BeginScope<TState>(TState state) where TState : notnull => null;
|
||||
|
||||
public bool IsEnabled(LogLevel logLevel) => logLevel >= _minimumLevel;
|
||||
|
||||
public void Log<TState>(
|
||||
LogLevel logLevel,
|
||||
EventId eventId,
|
||||
TState state,
|
||||
Exception? exception,
|
||||
Func<TState, Exception?, string> formatter)
|
||||
{
|
||||
if (!IsEnabled(logLevel))
|
||||
return;
|
||||
|
||||
var message = formatter(state, exception);
|
||||
if (exception != null)
|
||||
message += Environment.NewLine + exception;
|
||||
|
||||
// Use a background task to avoid blocking
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var hubContext = _serviceProvider.GetService<IHubContext<LoggingHub>>();
|
||||
if (hubContext != null)
|
||||
{
|
||||
await hubContext.Clients.All.SendAsync("Log", message, logLevel, DateTime.Now);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Silently fail if SignalR is unavailable
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,4 @@
|
|||
using Serilog.Events;
|
||||
using System.Drawing.Text;
|
||||
|
||||
namespace LANCommander.Server.Logging
|
||||
namespace LANCommander.Server.Logging
|
||||
{
|
||||
public static class TerminalColor
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
using Serilog;
|
||||
using LANCommander.Server.UI;
|
||||
using LANCommander.Server.Startup;
|
||||
|
||||
|
|
@ -26,9 +25,11 @@ builder.AddDatabase(args);
|
|||
|
||||
builder.Services.AddHealthChecks();
|
||||
|
||||
Log.Debug("Building Application");
|
||||
var app = builder.Build();
|
||||
|
||||
var logger = app.Services.GetRequiredService<ILogger<Program>>();
|
||||
logger.LogDebug("Building Application");
|
||||
|
||||
app.UseDatabase(args);
|
||||
app.ValidateSettings();
|
||||
|
||||
|
|
@ -42,9 +43,8 @@ app.UseMiddlewares();
|
|||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
Log.Debug("App has been run in a development environment");
|
||||
logger.LogDebug("App has been run in a development environment");
|
||||
app.UseMigrationsEndPoint();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
using LANCommander.SDK;
|
||||
using LANCommander.SDK.Extensions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Serilog;
|
||||
using YamlDotNet.Serialization;
|
||||
using YamlDotNet.Serialization.NamingConventions;
|
||||
|
||||
namespace LANCommander.Server.Startup;
|
||||
|
||||
|
|
@ -25,10 +21,11 @@ public static class ApplicationSettings
|
|||
{
|
||||
var settingsProvider = app.Services.GetRequiredService<SettingsProvider<Settings.Settings>>();
|
||||
var settings = app.Services.GetRequiredService<IOptions<Settings.Settings>>();
|
||||
var logger = app.Services.GetRequiredService<ILogger<Program>>();
|
||||
|
||||
if (settings.Value.Server.Authentication.TokenSecret.Length < 16)
|
||||
{
|
||||
Log.Debug("JWT token secret is too short. Regenerating...");
|
||||
logger.LogDebug("JWT token secret is too short. Regenerating...");
|
||||
settingsProvider.Update(s =>
|
||||
{
|
||||
s.Server.Authentication.TokenSecret = Guid.NewGuid().ToString();
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ using Microsoft.AspNetCore.Authentication;
|
|||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Serilog;
|
||||
|
||||
namespace LANCommander.Server.Startup;
|
||||
|
||||
|
|
@ -47,8 +46,7 @@ public static class Authentication
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Authentication Provider {Name} could not be registered",
|
||||
authenticationProvider.Name);
|
||||
Console.WriteLine($"Error: Authentication Provider {authenticationProvider.Name} could not be registered: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -114,7 +112,7 @@ public static class Authentication
|
|||
{
|
||||
context.Response.Redirect("/Login");
|
||||
|
||||
Log.Error(context.Failure, "OIDC authentication failed");
|
||||
Console.WriteLine($"Error: OIDC authentication failed: {context.Failure?.Message}");
|
||||
|
||||
await context.Response.CompleteAsync();
|
||||
};
|
||||
|
|
@ -163,7 +161,7 @@ public static class Authentication
|
|||
{
|
||||
context.Response.Redirect("/Login");
|
||||
|
||||
Log.Error(context.Failure, "OAuth authentication failed");
|
||||
Console.WriteLine($"Error: OAuth authentication failed: {context.Failure?.Message}");
|
||||
|
||||
await context.Response.CompleteAsync();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ using Microsoft.Data.Sqlite;
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Octokit;
|
||||
using Serilog;
|
||||
|
||||
namespace LANCommander.Server.Startup;
|
||||
|
||||
|
|
@ -65,7 +64,7 @@ public static class Database
|
|||
|
||||
if (File.Exists(dataSource))
|
||||
{
|
||||
Log.Information("Migrations pending, database will be backed up to {BackupName}", backupName);
|
||||
logger.LogInformation("Migrations pending, database will be backed up to {BackupName}", backupName);
|
||||
File.Copy(dataSource, backupName);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using LANCommander.Server.Endpoints;
|
||||
using Serilog;
|
||||
|
||||
namespace LANCommander.Server.Startup;
|
||||
|
||||
|
|
@ -7,8 +6,6 @@ public static class Endpoints
|
|||
{
|
||||
public static void AddControllers(this WebApplicationBuilder builder)
|
||||
{
|
||||
Log.Debug("Initializing Controllers");
|
||||
|
||||
builder.Services.AddControllers().AddJsonOptions(static x =>
|
||||
{
|
||||
x.JsonSerializerOptions.ReferenceHandler = System.Text.Json.Serialization.ReferenceHandler.IgnoreCycles;
|
||||
|
|
@ -17,8 +14,6 @@ public static class Endpoints
|
|||
|
||||
public static WebApplication MapEndpoints(this WebApplication app)
|
||||
{
|
||||
Log.Debug("Registering Endpoints");
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapAuthenticationEndpoints();
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ using LANCommander.Server.Services;
|
|||
using LANCommander.Server.Services.Models;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Serilog;
|
||||
|
||||
namespace LANCommander.Server.Startup;
|
||||
|
||||
|
|
@ -15,7 +14,6 @@ public static class Identity
|
|||
var settings = new Settings.Settings();
|
||||
builder.Configuration.Bind(settings);
|
||||
|
||||
Log.Debug("Initializing Identity");
|
||||
builder.Services.AddIdentityCore<User>((options) =>
|
||||
{
|
||||
options.SignIn.RequireConfirmedAccount = false;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,6 @@
|
|||
using Elastic.Serilog.Sinks;
|
||||
using LANCommander.Server.Configuration;
|
||||
using LANCommander.Server.Hubs;
|
||||
using LANCommander.Server.Parsers;
|
||||
using LANCommander.Server.Services.Models;
|
||||
using LANCommander.Server.Logging;
|
||||
using LANCommander.Server.Settings.Enums;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Serilog;
|
||||
using Serilog.Events;
|
||||
using Serilog.Filters;
|
||||
using Serilog.Sinks.AspNetCore.App.SignalR.Extensions;
|
||||
|
||||
namespace LANCommander.Server.Startup;
|
||||
|
||||
|
|
@ -16,73 +8,49 @@ public static class Logger
|
|||
{
|
||||
public static WebApplicationBuilder AddLogger(this WebApplicationBuilder builder)
|
||||
{
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.MinimumLevel.Verbose()
|
||||
.WriteTo.Console()
|
||||
.CreateBootstrapLogger();
|
||||
|
||||
builder.Services.AddSerilogHub<LoggingHub>();
|
||||
|
||||
builder.Services.AddSerilog((serviceProvider, config) =>
|
||||
builder.Services.AddLogging((loggingBuilder) =>
|
||||
{
|
||||
config.MinimumLevel.Verbose();
|
||||
config.Enrich.FromLogContext();
|
||||
|
||||
var serviceProvider = builder.Services.BuildServiceProvider();
|
||||
var settings = serviceProvider.GetRequiredService<IOptions<Settings.Settings>>();
|
||||
|
||||
|
||||
// Configure filters
|
||||
if (settings.Value.Server.Logs.IgnorePings)
|
||||
config.Filter.ByExcluding(Matching.WithProperty<string>("RequestPath", v => v.StartsWith("/api/Ping", StringComparison.OrdinalIgnoreCase)));
|
||||
{
|
||||
loggingBuilder.AddFilter((category, level) =>
|
||||
{
|
||||
// Filter out ping-related logs if IgnorePings is enabled
|
||||
if (category != null && category.Contains("Ping", StringComparison.OrdinalIgnoreCase))
|
||||
return false;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var provider in settings.Value.Server.Logs.Providers)
|
||||
{
|
||||
LogEventLevel minimumLevel = provider.MinimumLevel switch
|
||||
{
|
||||
LogLevel.Trace => LogEventLevel.Verbose,
|
||||
LogLevel.Debug => LogEventLevel.Debug,
|
||||
LogLevel.Warning => LogEventLevel.Warning,
|
||||
LogLevel.Information => LogEventLevel.Information,
|
||||
LogLevel.Error => LogEventLevel.Error,
|
||||
LogLevel.Critical => LogEventLevel.Fatal,
|
||||
_ => LogEventLevel.Information
|
||||
};
|
||||
|
||||
var minimumLevel = provider.MinimumLevel;
|
||||
|
||||
switch (provider.Type)
|
||||
{
|
||||
case LoggingProviderType.Console:
|
||||
config.WriteTo.Console(restrictedToMinimumLevel: minimumLevel);
|
||||
loggingBuilder.AddConsole();
|
||||
loggingBuilder.SetMinimumLevel(minimumLevel);
|
||||
break;
|
||||
|
||||
case LoggingProviderType.SignalR:
|
||||
config.WriteTo.SignalR<LoggingHub>(
|
||||
serviceProvider,
|
||||
(context, message, logEvent) => LoggingHub.Log(context, message, logEvent));
|
||||
break;
|
||||
|
||||
case LoggingProviderType.File:
|
||||
config.WriteTo.File(
|
||||
Path.Combine(provider.ConnectionString,"log-.txt"),
|
||||
rollingInterval: (RollingInterval)(int)(provider.ArchiveEvery ?? LogInterval.Day),
|
||||
restrictedToMinimumLevel: minimumLevel);
|
||||
break;
|
||||
|
||||
case LoggingProviderType.Seq:
|
||||
try
|
||||
{
|
||||
var options = ConnectionStringBinder.Bind<SeqOptions>(provider.ConnectionString);
|
||||
|
||||
config.WriteTo.Seq(
|
||||
restrictedToMinimumLevel: minimumLevel,
|
||||
serverUrl: options.ServerUrl,
|
||||
apiKey: options.ApiKey);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Could not bind Seq connection string");
|
||||
}
|
||||
case LoggingProviderType.SignalR:
|
||||
loggingBuilder.Services.AddSingleton<ILoggerProvider>(sp =>
|
||||
new SignalRLoggerProvider(sp, minimumLevel));
|
||||
break;
|
||||
|
||||
|
||||
case LoggingProviderType.File:
|
||||
loggingBuilder.AddFile(provider.ConnectionString, minimumLevel);
|
||||
break;
|
||||
|
||||
case LoggingProviderType.Seq:
|
||||
case LoggingProviderType.ElasticSearch:
|
||||
config.WriteTo.Elasticsearch([new Uri(provider.ConnectionString)], restrictedToMinimumLevel: minimumLevel);
|
||||
// Note: Standard .NET logging doesn't have built-in support for Seq or Elasticsearch
|
||||
// Users will need to add these providers manually if needed
|
||||
builder.Logging.AddDebug();
|
||||
Console.WriteLine($"Warning: {provider.Type} logging provider is not supported in standard .NET logging. Consider using a third-party logging library.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -90,4 +58,55 @@ public static class Logger
|
|||
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static ILoggingBuilder AddFile(this ILoggingBuilder builder, string logDirectory, LogLevel minimumLevel)
|
||||
=> builder.AddProvider(new FileLoggerProvider(logDirectory, minimumLevel));
|
||||
|
||||
private class FileLogger(string logDirectory, string categoryName, LogLevel minimumLevel) : ILogger
|
||||
{
|
||||
public IDisposable? BeginScope<TState>(TState state) where TState : notnull => null;
|
||||
|
||||
public bool IsEnabled(LogLevel logLevel) => logLevel >= minimumLevel;
|
||||
|
||||
public void Log<TState>(
|
||||
LogLevel logLevel,
|
||||
EventId eventId,
|
||||
TState state,
|
||||
Exception? exception,
|
||||
Func<TState, Exception?, string> formatter)
|
||||
{
|
||||
if (!IsEnabled(logLevel))
|
||||
return;
|
||||
|
||||
var logFilePath = Path.Combine(
|
||||
logDirectory,
|
||||
$"log-{DateTime.Now:yyyy-MM-dd}.txt");
|
||||
|
||||
var message = formatter(state, exception);
|
||||
var logMessage = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} [{logLevel}] [{categoryName}] {message}";
|
||||
|
||||
if (exception != null)
|
||||
logMessage += Environment.NewLine + exception;
|
||||
|
||||
try
|
||||
{
|
||||
lock (logDirectory)
|
||||
{
|
||||
Directory.CreateDirectory(logDirectory);
|
||||
File.AppendAllText(logFilePath, logMessage + Environment.NewLine);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Silently fail if logging to file fails
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class FileLoggerProvider(string logDirectory, LogLevel minimumLevel) : ILoggerProvider
|
||||
{
|
||||
public ILogger CreateLogger(string categoryName) => new FileLogger(logDirectory, categoryName, minimumLevel);
|
||||
|
||||
public void Dispose() { }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,9 @@
|
|||
using Serilog;
|
||||
|
||||
namespace LANCommander.Server.Startup;
|
||||
|
||||
public static class Razor
|
||||
{
|
||||
public static WebApplicationBuilder AddRazor(this WebApplicationBuilder builder)
|
||||
{
|
||||
Log.Debug("Configuring MVC and Blazor");
|
||||
|
||||
builder.Services
|
||||
.AddMvc(static options => options.EnableEndpointRouting = false)
|
||||
.AddRazorOptions(static options =>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ using LANCommander.Server.Providers;
|
|||
using LANCommander.Server.Services.Abstractions;
|
||||
using LANCommander.Server.Services.Extensions;
|
||||
using LANCommander.UI.Extensions;
|
||||
using Serilog;
|
||||
|
||||
namespace LANCommander.Server.Startup;
|
||||
|
||||
|
|
@ -12,8 +11,6 @@ public static class Services
|
|||
{
|
||||
public static WebApplicationBuilder AddLANCommanderServices(this WebApplicationBuilder builder)
|
||||
{
|
||||
Log.Debug("Registering services");
|
||||
|
||||
builder.Services.AddLANCommanderClient<Settings.Settings>();
|
||||
builder.Services.AddLANCommanderServer();
|
||||
builder.Services.AddLANCommanderImportExport();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
@using LANCommander.Server.Logging
|
||||
@using Microsoft.AspNetCore.SignalR.Client
|
||||
@using Serilog.Events
|
||||
@using XtermBlazor
|
||||
@inject ILogger<LogViewer> Logger
|
||||
@inject MessageService MessageService
|
||||
|
|
@ -52,7 +51,7 @@
|
|||
.WithUrl(NavigationManager.ToAbsoluteUri("/logging"))
|
||||
.Build();
|
||||
|
||||
HubConnection.On<string, LogEventLevel, DateTime>("Log", (message, level, timestamp) =>
|
||||
HubConnection.On<string, Microsoft.Extensions.Logging.LogLevel, DateTime>("Log", (message, level, timestamp) =>
|
||||
{
|
||||
var parts = new string[]
|
||||
{
|
||||
|
|
@ -74,16 +73,16 @@
|
|||
await HubConnection.StartAsync();
|
||||
}
|
||||
|
||||
string GetColorCode(LogEventLevel level)
|
||||
string GetColorCode(Microsoft.Extensions.Logging.LogLevel level)
|
||||
{
|
||||
return level switch
|
||||
{
|
||||
LogEventLevel.Verbose => TerminalColor.BrightBlack,
|
||||
LogEventLevel.Debug => TerminalColor.BrightCyan,
|
||||
LogEventLevel.Information => TerminalColor.BrightGreen,
|
||||
LogEventLevel.Warning => TerminalColor.BrightYellow,
|
||||
LogEventLevel.Error => TerminalColor.BrightRed,
|
||||
LogEventLevel.Fatal => TerminalColor.BrightMagenta,
|
||||
Microsoft.Extensions.Logging.LogLevel.Trace => TerminalColor.BrightBlack,
|
||||
Microsoft.Extensions.Logging.LogLevel.Debug => TerminalColor.BrightCyan,
|
||||
Microsoft.Extensions.Logging.LogLevel.Information => TerminalColor.BrightGreen,
|
||||
Microsoft.Extensions.Logging.LogLevel.Warning => TerminalColor.BrightYellow,
|
||||
Microsoft.Extensions.Logging.LogLevel.Error => TerminalColor.BrightRed,
|
||||
Microsoft.Extensions.Logging.LogLevel.Critical => TerminalColor.BrightMagenta,
|
||||
_ => TerminalColor.Default,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue