Compare commits

...
Author SHA1 Message Date
Jason Dove d0d1186b92 attempt to fix release on windows 2021-02-12 16:33:42 -06:00
Jason Dove 04ab4ee60f add version information (#15) 2021-02-12 22:26:05 +00:00
Jason Dove e62074cc26 add basic logging ui (#14) 2021-02-12 22:18:44 +00:00
19 changed files with 191 additions and 5 deletions
+2 -2
View File
@@ -42,8 +42,8 @@ jobs:
release_name_cli="ErsatzTV.CommandLine-$tag-${{ matrix.target }}"
# Build everything
dotnet publish ErsatzTV/ErsatzTV.csproj --framework net5.0 --runtime "${{ matrix.target }}" -c Release -o "$release_name"
dotnet publish ErsatzTV.CommandLine/ErsatzTV.CommandLine.csproj --framework net5.0 --runtime "${{ matrix.target }}" -c Release -o "$release_name_cli"
dotnet publish ErsatzTV/ErsatzTV.csproj --framework net5.0 --runtime "${{ matrix.target }}" -c Release -o "$release_name" /property:InformationalVersion="${tag:1}-${{ matrix.target }}"
dotnet publish ErsatzTV.CommandLine/ErsatzTV.CommandLine.csproj --framework net5.0 --runtime "${{ matrix.target }}" -c Release -o "$release_name_cli" /property:InformationalVersion="${tag:1}-${{ matrix.target }}"
# Pack files
if [ "${{ matrix.target }}" == "win-x64" ]; then
+5
View File
@@ -0,0 +1,5 @@
<Project>
<PropertyGroup>
<InformationalVersion>develop</InformationalVersion>
</PropertyGroup>
</Project>
+2 -1
View File
@@ -26,7 +26,8 @@ COPY ErsatzTV.Core/. ./ErsatzTV.Core/
COPY ErsatzTV.Core.Tests/. ./ErsatzTV.Core.Tests/
COPY ErsatzTV.Infrastructure/. ./ErsatzTV.Infrastructure/
WORKDIR /source/ErsatzTV
RUN dotnet publish -c release -o /app -r linux-x64 --self-contained false --no-restore
ARG INFO_VERSION="unknown"
RUN dotnet publish -c release -o /app -r linux-x64 --self-contained false --no-restore /p:InformationalVersion=${INFO_VERSION}
# final stage/image
FROM runtime-base
@@ -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);
}
+16
View File
@@ -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 @@
using System.Collections.Generic;
using MediatR;
namespace ErsatzTV.Application.Logs.Queries
{
public record GetRecentLogEntries : IRequest<List<LogEntryViewModel>>;
}
@@ -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());
}
}
+12
View File
@@ -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);
}
+2
View File
@@ -13,6 +13,8 @@ namespace ErsatzTV.Core
public static readonly string DatabasePath = Path.Combine(AppDataFolder, "ersatztv.sqlite3");
public static readonly string LogDatabasePath = Path.Combine(AppDataFolder, "logs.sqlite3");
public static readonly string ImageCacheFolder = Path.Combine(AppDataFolder, "cache", "images");
public static readonly string PlexSecretsPath = Path.Combine(AppDataFolder, "plex-secrets.json");
@@ -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 @@
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 @@
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 @@
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();
}
}
+1
View File
@@ -25,6 +25,7 @@
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" />
<PackageReference Include="Serilog.Sinks.SQLite" Version="5.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.0.2" />
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="6.0.2" />
</ItemGroup>
+29
View File
@@ -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());
}
+2
View File
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Threading.Tasks;
using ErsatzTV.Core;
using ErsatzTV.Extensions;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
@@ -25,6 +26,7 @@ namespace ErsatzTV
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(Configuration)
.Enrich.FromLogContext()
.WriteTo.SQLite(FileSystemLayout.LogDatabasePath, retentionPeriod: TimeSpan.FromDays(1))
.CreateLogger();
try
+11 -2
View File
@@ -1,4 +1,5 @@
@inherits LayoutComponentBase
@using System.Reflection
@inherits LayoutComponentBase
<MudThemeProvider Theme="_ersatzTvTheme"/>
<MudDialogProvider DisableBackdropClick="true"/>
@@ -32,6 +33,12 @@
</MudNavGroup>
<MudNavLink Href="/schedules">Schedules</MudNavLink>
<MudNavLink Href="/playouts">Playouts</MudNavLink>
<MudNavLink Href="/system/logs">Logs</MudNavLink>
<MudDivider Class="my-6" DividerType="DividerType.Middle" />
<MudContainer Style="text-align: right" Class="mr-6">
<MudText Typo="Typo.body2">ErsatzTV Version</MudText>
<MudText Typo="Typo.body2" Color="Color.Info">@InfoVersion</MudText>
</MudContainer>
</MudNavMenu>
</MudDrawer>
<MudMainContent>
@@ -42,7 +49,9 @@
</MudLayout>
@code {
bool _drawerOpen = true;
private static readonly string InfoVersion = Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion ?? "unknown";
private bool _drawerOpen = true;
private void DrawerToggle() => _drawerOpen = !_drawerOpen;
+4
View File
@@ -108,6 +108,9 @@ namespace ErsatzTV
o.MigrationsAssembly("ErsatzTV.Infrastructure");
}));
services.AddDbContext<LogContext>(
options => options.UseSqlite($"Data Source={FileSystemLayout.LogDatabasePath}"));
services.AddMediatR(typeof(GetAllChannels).Assembly);
services.AddRefitClient<IPlexTvApi>()
@@ -156,6 +159,7 @@ namespace ErsatzTV
services.AddScoped<IConfigElementRepository, ConfigElementRepository>();
services.AddScoped<IProgramScheduleRepository, ProgramScheduleRepository>();
services.AddScoped<IPlayoutRepository, PlayoutRepository>();
services.AddScoped<ILogRepository, LogRepository>();
services.AddScoped<IFFmpegLocator, FFmpegLocator>();
services.AddScoped<ISmartCollectionBuilder, SmartCollectionBuilder>();
services.AddScoped<ILocalMetadataProvider, LocalMetadataProvider>();
+2
View File
@@ -4,6 +4,8 @@ services:
ersatztv:
build:
context: .
args:
INFO_VERSION: "docker-compose-develop"
ports:
- "8409:8409"
volumes: