mirror of https://github.com/ErsatzTV/ErsatzTV.git
19 changed files with 191 additions and 5 deletions
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
<Project> |
||||
<PropertyGroup> |
||||
<InformationalVersion>develop</InformationalVersion> |
||||
</PropertyGroup> |
||||
</Project> |
||||
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
using System; |
||||
|
||||
namespace ErsatzTV.Application.Logs |
||||
{ |
||||
public record LogEntryViewModel( |
||||
int Id, |
||||
DateTime Timestamp, |
||||
string Level, |
||||
string Exception, |
||||
string RenderedMessage, |
||||
string Properties); |
||||
} |
||||
@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
|
||||
using ErsatzTV.Core.Domain; |
||||
|
||||
namespace ErsatzTV.Application.Logs |
||||
{ |
||||
internal static class Mapper |
||||
{ |
||||
internal static LogEntryViewModel ProjectToViewModel(LogEntry logEntry) => |
||||
new( |
||||
logEntry.Id, |
||||
logEntry.Timestamp, |
||||
logEntry.Level, |
||||
logEntry.Exception, |
||||
logEntry.RenderedMessage, |
||||
logEntry.Properties); |
||||
} |
||||
} |
||||
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
using System.Collections.Generic; |
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.Logs.Queries |
||||
{ |
||||
public record GetRecentLogEntries : IRequest<List<LogEntryViewModel>>; |
||||
} |
||||
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using static ErsatzTV.Application.Logs.Mapper; |
||||
|
||||
namespace ErsatzTV.Application.Logs.Queries |
||||
{ |
||||
public class GetRecentLogEntriesHandler : IRequestHandler<GetRecentLogEntries, List<LogEntryViewModel>> |
||||
{ |
||||
private readonly ILogRepository _logRepository; |
||||
|
||||
public GetRecentLogEntriesHandler(ILogRepository logRepository) => _logRepository = logRepository; |
||||
|
||||
public Task<List<LogEntryViewModel>> Handle(GetRecentLogEntries request, CancellationToken cancellationToken) => |
||||
_logRepository.GetRecentLogEntries().Map(list => list.Map(ProjectToViewModel).ToList()); |
||||
} |
||||
} |
||||
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
using System; |
||||
|
||||
namespace ErsatzTV.Core.Domain |
||||
{ |
||||
public record LogEntry( |
||||
int Id, |
||||
DateTime Timestamp, |
||||
string Level, |
||||
string Exception, |
||||
string RenderedMessage, |
||||
string Properties); |
||||
} |
||||
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core.Domain; |
||||
|
||||
namespace ErsatzTV.Core.Interfaces.Repositories |
||||
{ |
||||
public interface ILogRepository |
||||
{ |
||||
public Task<List<LogEntry>> GetRecentLogEntries(); |
||||
} |
||||
} |
||||
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
using ErsatzTV.Core.Domain; |
||||
using Microsoft.EntityFrameworkCore; |
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders; |
||||
|
||||
namespace ErsatzTV.Infrastructure.Data.Configurations |
||||
{ |
||||
public class LogEntryConfiguration : IEntityTypeConfiguration<LogEntry> |
||||
{ |
||||
public void Configure(EntityTypeBuilder<LogEntry> builder) => |
||||
builder.ToTable("Logs"); |
||||
} |
||||
} |
||||
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
using ErsatzTV.Core.Domain; |
||||
using Microsoft.EntityFrameworkCore; |
||||
|
||||
namespace ErsatzTV.Infrastructure.Data |
||||
{ |
||||
public class LogContext : DbContext |
||||
{ |
||||
public LogContext(DbContextOptions<LogContext> options) |
||||
: base(options) |
||||
{ |
||||
} |
||||
|
||||
public DbSet<LogEntry> LogEntries { get; set; } |
||||
|
||||
protected override void OnModelCreating(ModelBuilder builder) |
||||
{ |
||||
base.OnModelCreating(builder); |
||||
builder.ApplyConfigurationsFromAssembly(typeof(LogContext).Assembly); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core.Domain; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using Microsoft.EntityFrameworkCore; |
||||
|
||||
namespace ErsatzTV.Infrastructure.Data.Repositories |
||||
{ |
||||
public class LogRepository : ILogRepository |
||||
{ |
||||
private readonly LogContext _logContext; |
||||
|
||||
public LogRepository(LogContext logContext) => _logContext = logContext; |
||||
|
||||
public Task<List<LogEntry>> GetRecentLogEntries() => |
||||
_logContext.LogEntries.OrderByDescending(e => e.Id).Take(100).ToListAsync(); |
||||
} |
||||
} |
||||
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
@page "/system/logs" |
||||
@using ErsatzTV.Application.Logs |
||||
@using ErsatzTV.Application.Logs.Queries |
||||
@inject IMediator Mediator |
||||
|
||||
<MudTable FixedHeader="true" Dense="true" Items="_logEntries"> |
||||
<HeaderContent> |
||||
<MudTh>Timestamp</MudTh> |
||||
<MudTh>Level</MudTh> |
||||
<MudTh>Message</MudTh> |
||||
<MudTh>Properties</MudTh> |
||||
</HeaderContent> |
||||
<RowTemplate> |
||||
<MudTd DataLabel="Timestamp">@context.Timestamp</MudTd> |
||||
<MudTd DataLabel="Level">@context.Level</MudTd> |
||||
<MudTd DataLabel="Message">@context.RenderedMessage</MudTd> |
||||
<MudTd DataLabel="Message">@context.Properties</MudTd> |
||||
</RowTemplate> |
||||
<PagerContent> |
||||
<MudTablePager/> |
||||
</PagerContent> |
||||
</MudTable> |
||||
|
||||
@code { |
||||
private List<LogEntryViewModel> _logEntries; |
||||
|
||||
protected override async Task OnInitializedAsync() => _logEntries = await Mediator.Send(new GetRecentLogEntries()); |
||||
|
||||
} |
||||
Loading…
Reference in new issue