Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
Laura Hausmann
daa2f4cddf
wip 2024-07-20 03:24:31 +02:00
7 changed files with 115 additions and 3 deletions

View file

@ -1,11 +1,13 @@
using Iceshrimp.Backend.Core.Services;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Logging.Console; using Microsoft.Extensions.Logging.Console;
using Serilog;
namespace Iceshrimp.Backend.Core.Extensions; namespace Iceshrimp.Backend.Core.Extensions;
public static class ConsoleLoggerExtensions public static class LoggingExtensions
{ {
public static ILoggingBuilder AddCustomConsoleFormatter(this ILoggingBuilder builder) public static ILoggingBuilder AddCustomConsoleLogger(this ILoggingBuilder builder)
{ {
if (Environment.GetEnvironmentVariable("INVOCATION_ID") is not null) if (Environment.GetEnvironmentVariable("INVOCATION_ID") is not null)
{ {
@ -20,6 +22,22 @@ public static class ConsoleLoggerExtensions
return builder; return builder;
} }
public static IServiceCollection AddLoggingProviders(this IServiceCollection services)
{
var logStorageProvider = new InMemoryLogStorageProvider();
var logService = new LogService(logStorageProvider);
services.AddSingleton<LogService>(_ => logService);
var logger = new LoggerConfiguration()
.WriteTo.Sink(logService)
.CreateLogger();
services.AddLogging(logging => logging.AddCustomConsoleLogger().AddSerilog(logger));
return services;
}
} }
/* /*

View file

@ -53,4 +53,11 @@ public class WriteLockingList<T>(IEnumerable<T>? sourceCollection = null) : ICol
{ {
lock (_list) return _list.RemoveAll(predicate); lock (_list) return _list.RemoveAll(predicate);
} }
public void Trim(int maxEntries)
{
var count = _list.Count - maxEntries;
if (count <= 0) return;
lock (_list) _list.RemoveRange(0, count);
}
} }

View file

@ -0,0 +1,50 @@
using Iceshrimp.Backend.Core.Helpers;
using Serilog.Core;
using Serilog.Events;
namespace Iceshrimp.Backend.Core.Services;
public class LogService(ILogStorageProvider logStorage) : ILogEventSink
{
public IQueryable<LogEntry> Logs => logStorage.Logs;
public void Emit(LogEvent logEvent)
{
logStorage.Append(new LogEntry(logEvent));
}
}
public interface ILogStorageProvider
{
public IQueryable<LogEntry> Logs { get; }
public void Append(LogEntry entry);
}
public class InMemoryLogStorageProvider : ILogStorageProvider
{
private readonly WriteLockingList<LogEntry> _logs = [];
//private readonly IReadOnlyDictionary<LogLevel, int> _maxEntries =
// Enum.GetValues<LogLevel>()
// .ToDictionary(p => p, _ => 100)
// .AsReadOnly();
public void Append(LogEntry entry)
{
_logs.Add(entry);
_logs.Trim(100);
//_logs.Trim(_maxEntries[entry.Level]);
}
public IQueryable<LogEntry> Logs => _logs.AsQueryable().Reverse();
}
public class LogEntry(LogEvent logEvent)
{
public DateTime Timestamp => logEvent.Timestamp.LocalDateTime;
public LogEventLevel Level => logEvent.Level;
public string Category => logEvent.Properties["SourceContext"].ToString().Trim('"');
public string Message => logEvent.RenderMessage();
public string Template => logEvent.MessageTemplate.Text;
}

View file

@ -36,6 +36,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.7" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="8.0.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" />
<PackageReference Include="Serilog.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.3" /> <PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.3" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.5-iceshrimp" /> <PackageReference Include="SixLabors.ImageSharp" Version="3.1.5-iceshrimp" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />

View file

@ -0,0 +1,25 @@
@page "/logs"
@using Iceshrimp.Backend.Core.Extensions
@model LogModel
<table>
<thead>
<th>Timestamp</th>
<th>Level</th>
<th>Category</th>
<th>Message</th>
<th>Template</th>
</thead>
<tbody>
@foreach (var message in Model.Messages)
{
<tr>
<td>@message.Timestamp.ToDisplayStringTz()</td>
<td>@message.Level</td>
<td>@message.Category</td>
<td>@message.Message</td>
<td>@message.Template</td>
</tr>
}
</tbody>
</table>

View file

@ -0,0 +1,11 @@
using Iceshrimp.Backend.Core.Services;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Iceshrimp.Backend.Pages;
public class LogModel(LogService logService) : PageModel
{
public IEnumerable<LogEntry> Messages = logService.Logs.Take(100);
public void OnGet() { }
}

View file

@ -22,7 +22,7 @@ builder.Services.AddControllers()
.AddPlugins(PluginLoader.Assemblies); .AddPlugins(PluginLoader.Assemblies);
builder.Services.AddSwaggerGenWithOptions(); builder.Services.AddSwaggerGenWithOptions();
builder.Services.AddLogging(logging => logging.AddCustomConsoleFormatter()); builder.Services.AddLoggingProviders();
builder.Services.AddDatabaseContext(builder.Configuration); builder.Services.AddDatabaseContext(builder.Configuration);
builder.Services.AddSlidingWindowRateLimiter(); builder.Services.AddSlidingWindowRateLimiter();
builder.Services.AddCorsPolicies(); builder.Services.AddCorsPolicies();