Added new log files and log migrators. Fixed some errors with js invokes
This commit is contained in:
parent
1665d6e537
commit
d19412f4bb
10 changed files with 207 additions and 68 deletions
30
Moonlight/App/Extensions/JSRuntimeExtensions.cs
Normal file
30
Moonlight/App/Extensions/JSRuntimeExtensions.cs
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
71
Moonlight/App/LogMigrator/SentryDiagnosticsLogger.cs
Normal file
71
Moonlight/App/LogMigrator/SentryDiagnosticsLogger.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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")))
|
||||
{
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
40
Moonlight/Shared/Views/Admin/Sys/Sentry.razor
Normal file
40
Moonlight/Shared/Views/Admin/Sys/Sentry.razor
Normal 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;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue