Added new log files and log migrators. Fixed some errors with js invokes

This commit is contained in:
Marcel Baumgartner 2023-07-02 00:21:35 +02:00
parent 1665d6e537
commit d19412f4bb
10 changed files with 207 additions and 68 deletions

View file

@ -0,0 +1,30 @@
using Microsoft.JSInterop;
namespace Moonlight.App.Extensions;
public static class JSRuntimeExtensions
{
public static async Task InvokeVoidSafeAsync(this IJSRuntime jsRuntime, string method, params object[] args)
{
try
{
await jsRuntime.InvokeVoidAsync(method, args);
}
catch (Exception)
{
// ignored
}
}
public static void InvokeVoidSafe(this IJSRuntime jsRuntime, string method, params object[] args)
{
try
{
jsRuntime.InvokeVoidAsync(method, args);
}
catch (Exception)
{
// ignored
}
}
}

View file

@ -27,19 +27,39 @@ public class LogMigrator : ILogger
switch (logLevel)
{
case LogLevel.Critical:
Logger.Fatal($"[{Name}] {formatter(state, exception)}");
Logger.Fatal(formatter(state, exception));
if(exception != null)
Logger.Fatal(exception);
break;
case LogLevel.Warning:
Logger.Warn($"[{Name}] {formatter(state, exception)}");
Logger.Warn(formatter(state, exception));
if(exception != null)
Logger.Warn(exception);
break;
case LogLevel.Debug:
Logger.Debug($"[{Name}] {formatter(state, exception)}");
Logger.Debug(formatter(state, exception));
if(exception != null)
Logger.Debug(exception);
break;
case LogLevel.Error:
Logger.Error($"[{Name}] {formatter(state, exception)}");
Logger.Error(formatter(state, exception));
if(exception != null)
Logger.Error(exception);
break;
case LogLevel.Information:
Logger.Info($"[{Name}] {formatter(state, exception)}");
Logger.Info(formatter(state, exception));
if(exception != null)
Logger.Info(exception);
break;
}
}

View file

@ -0,0 +1,71 @@
using Moonlight.App.Helpers;
using Sentry;
using Sentry.Extensibility;
namespace Moonlight.App.LogMigrator;
public class SentryDiagnosticsLogger : IDiagnosticLogger
{
private readonly SentryLevel Level;
public SentryDiagnosticsLogger(SentryLevel level)
{
Level = level;
}
public bool IsEnabled(SentryLevel level)
{
if ((int)level >= (int)Level)
{
return true;
}
return false;
}
public void Log(SentryLevel logLevel, string message, Exception? exception = null, params object?[] args)
{
switch (logLevel)
{
case SentryLevel.Debug:
Logger.Debug(string.Format(message, args));
if(exception != null)
Logger.Debug(exception);
break;
case SentryLevel.Info:
Logger.Info(string.Format(message, args));
if(exception != null)
Logger.Info(exception);
break;
case SentryLevel.Warning:
Logger.Warn(string.Format(message, args));
if(exception != null)
Logger.Warn(exception);
break;
case SentryLevel.Error:
Logger.Error(string.Format(message, args));
if(exception != null)
Logger.Error(exception);
break;
case SentryLevel.Fatal:
Logger.Fatal(string.Format(message, args));
if(exception != null)
Logger.Fatal(exception);
break;
}
}
}

View file

@ -15,6 +15,7 @@ public class StorageService
Directory.CreateDirectory(PathBuilder.Dir("storage", "configs"));
Directory.CreateDirectory(PathBuilder.Dir("storage", "resources"));
Directory.CreateDirectory(PathBuilder.Dir("storage", "backups"));
Directory.CreateDirectory(PathBuilder.Dir("storage", "logs"));
if(IsEmpty(PathBuilder.Dir("storage", "resources")))
{

View file

@ -49,6 +49,7 @@
<PackageReference Include="Sentry.AspNetCore" Version="3.33.1" />
<PackageReference Include="Sentry.Serilog" Version="3.33.1" />
<PackageReference Include="Serilog" Version="3.0.0" />
<PackageReference Include="Serilog.AspNetCore" Version="7.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.1-dev-00910" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.1-dev-00947" />
<PackageReference Include="SSH.NET" Version="2020.0.2" />

View file

@ -56,6 +56,7 @@ namespace Moonlight
.Enrich.FromLogContext()
.WriteTo.Console(
outputTemplate: "{Timestamp:HH:mm:ss} [{Level:u3}] {SourceContext} {Message:lj}{NewLine}{Exception}")
.WriteTo.File(PathBuilder.File("storage", "logs", $"{DateTime.UtcNow:yyyy-MM-dd}.log"))
.WriteTo.Sentry(options =>
{
options.MinimumBreadcrumbLevel = LogEventLevel.Debug;
@ -70,6 +71,7 @@ namespace Moonlight
.Enrich.FromLogContext()
.WriteTo.Console(
outputTemplate: "{Timestamp:HH:mm:ss} [{Level:u3}] {SourceContext} {Message:lj}{NewLine}{Exception}")
.WriteTo.File(PathBuilder.File("storage", "logs", $"{DateTime.UtcNow:yyyy-MM-dd}.log"))
.CreateLogger();
}
}
@ -87,6 +89,7 @@ namespace Moonlight
options.MinimumBreadcrumbLevel = LogEventLevel.Information;
options.MinimumEventLevel = LogEventLevel.Warning;
})
.WriteTo.File(PathBuilder.File("storage", "logs", $"{DateTime.UtcNow:yyyy-MM-dd}.log"))
.CreateLogger();
}
else
@ -96,6 +99,7 @@ namespace Moonlight
.Enrich.FromLogContext()
.WriteTo.Console(
outputTemplate: "{Timestamp:HH:mm:ss} [{Level:u3}] {SourceContext} {Message:lj}{NewLine}{Exception}")
.WriteTo.File(PathBuilder.File("storage", "logs", $"{DateTime.UtcNow:yyyy-MM-dd}.log"))
.CreateLogger();
}
}
@ -111,8 +115,8 @@ namespace Moonlight
// Switch to logging.net injection
// TODO: Enable in production
//builder.Logging.ClearProviders();
//builder.Logging.AddProvider(new LogMigratorProvider());
builder.Logging.ClearProviders();
builder.Logging.AddProvider(new LogMigratorProvider());
// Add services to the container.
builder.Services.AddRazorPages();
@ -141,6 +145,9 @@ namespace Moonlight
options.Debug = configService.DebugMode;
options.DiagnosticLevel = SentryLevel.Warning;
options.TracesSampleRate = 1.0;
options.DiagnosticLogger = new SentryDiagnosticsLogger(SentryLevel.Warning);
});
}

View file

@ -10,8 +10,8 @@
</a>
</li>
<li class="nav-item mt-2">
<a class="nav-link text-active-primary ms-0 me-10 py-5 @(Index == 1 ? "active" : "")" href="/admin/system/logs">
<TL>Logs</TL>
<a class="nav-link text-active-primary ms-0 me-10 py-5 @(Index == 1 ? "active" : "")" href="/admin/system/sentry">
<TL>Sentry</TL>
</a>
</li>
<li class="nav-item mt-2">

View file

@ -1,4 +1,5 @@
@inherits LayoutComponentBase
@using Moonlight.App.Extensions
@inherits LayoutComponentBase
@inject IJSRuntime JS
@inject NavigationManager NavigationManager
@ -14,23 +15,23 @@ window.emptyBody = function(){
{
protected override void OnAfterRender(bool firstRender)
{
JS.InvokeVoidAsync("KTThemeMode.init");
JS.InvokeVoidAsync("emptyBody");
JS.InvokeVoidSafe("KTThemeMode.init");
JS.InvokeVoidSafe("emptyBody");
if (firstRender)
{
JS.InvokeVoidAsync("scrollTo", 0, 0);
JS.InvokeVoidAsync("KTDialer.init");
JS.InvokeVoidAsync("KTDrawer.init");
JS.InvokeVoidAsync("KTMenu.init");
JS.InvokeVoidAsync("KTImageInput.init");
JS.InvokeVoidAsync("KTPasswordMeter.init");
JS.InvokeVoidAsync("KTScroll.init");
JS.InvokeVoidAsync("KTScrolltop.init");
JS.InvokeVoidAsync("KTSticky.init");
JS.InvokeVoidAsync("KTSwapper.init");
JS.InvokeVoidAsync("KTToggle.init");
JS.InvokeVoidAsync("KTMenu.updateByLinkAttribute", $"/{NavigationManager.ToBaseRelativePath(NavigationManager.Uri)}");
JS.InvokeVoidSafe("scrollTo", 0, 0);
JS.InvokeVoidSafe("KTDialer.init");
JS.InvokeVoidSafe("KTDrawer.init");
JS.InvokeVoidSafe("KTMenu.init");
JS.InvokeVoidSafe("KTImageInput.init");
JS.InvokeVoidSafe("KTPasswordMeter.init");
JS.InvokeVoidSafe("KTScroll.init");
JS.InvokeVoidSafe("KTScrolltop.init");
JS.InvokeVoidSafe("KTSticky.init");
JS.InvokeVoidSafe("KTSwapper.init");
JS.InvokeVoidSafe("KTToggle.init");
JS.InvokeVoidSafe("KTMenu.updateByLinkAttribute", $"/{NavigationManager.ToBaseRelativePath(NavigationManager.Uri)}");
}
JS.InvokeVoidAsync("KTLayoutSearch.init");
@ -45,30 +46,18 @@ window.emptyBody = function(){
private async void OnLocationChanged(object sender, LocationChangedEventArgs args)
{
await InvokeJsSave("scrollTo", 0, 0);
await InvokeJsSave("KTDrawer.createInstances");
await InvokeJsSave("KTMenu.createInstances");
await InvokeJsSave("KTImageInput.createInstances");
await InvokeJsSave("KTPasswordMeter.createInstances");
await InvokeJsSave("KTScroll.createInstances");
await InvokeJsSave("KTScrolltop.createInstances");
await InvokeJsSave("KTSticky.createInstances");
await InvokeJsSave("KTSwapper.createInstances");
await InvokeJsSave("KTToggle.createInstances");
await InvokeJsSave("KTMenu.updateByLinkAttribute", $"/{NavigationManager.ToBaseRelativePath(args.Location)}");
await InvokeJsSave("KTAppSidebar.init");
}
private async Task InvokeJsSave(string method, params object[] args)
{
try
{
await JS.InvokeVoidAsync(method, args);
}
catch (Exception)
{
// ignored
}
await JS.InvokeVoidSafeAsync("scrollTo", 0, 0);
await JS.InvokeVoidSafeAsync("KTDrawer.createInstances");
await JS.InvokeVoidSafeAsync("KTMenu.createInstances");
await JS.InvokeVoidSafeAsync("KTImageInput.createInstances");
await JS.InvokeVoidSafeAsync("KTPasswordMeter.createInstances");
await JS.InvokeVoidSafeAsync("KTScroll.createInstances");
await JS.InvokeVoidSafeAsync("KTScrolltop.createInstances");
await JS.InvokeVoidSafeAsync("KTSticky.createInstances");
await JS.InvokeVoidSafeAsync("KTSwapper.createInstances");
await JS.InvokeVoidSafeAsync("KTToggle.createInstances");
await JS.InvokeVoidSafeAsync("KTMenu.updateByLinkAttribute", $"/{NavigationManager.ToBaseRelativePath(args.Location)}");
await JS.InvokeVoidSafeAsync("KTAppSidebar.init");
}
public void Dispose()

View file

@ -1,20 +0,0 @@
@page "/admin/system/logs"
@using BlazorTable
@using Moonlight.App.Models.Misc
@using Moonlight.App.Services
@using Moonlight.Shared.Components.Navigations
@inject SmartTranslateService SmartTranslateService
<OnlyAdmin>
<AdminSystemNavigation Index="1"/>
</OnlyAdmin>
@code
{
private Task Load(LazyLoader arg)
{
return Task.CompletedTask;
}
}

View file

@ -0,0 +1,40 @@
@page "/admin/system/sentry"
@using Moonlight.Shared.Components.Navigations
@using global::Sentry
<OnlyAdmin>
<AdminSystemNavigation Index="1"/>
<div class="row">
<div class="col-xxl-6 my-3">
<div class="card">
<div class="card-header">
<span class="card-title">
<TL>Status</TL>
</span>
</div>
<div class="card-body">
<span class="fs-5">
@if (SentrySdk.IsEnabled)
{
<TL>Sentry is enabled</TL>
}
else
{
<TL>Sentry is disabled</TL>
}
</span>
</div>
</div>
</div>
</div>
</OnlyAdmin>
@code
{
private Task Load(LazyLoader arg)
{
return Task.CompletedTask;
}
}