Files
live_recorder/src/LiveRecorder.Application/Services/SystemLogService.cs
T

95 lines
3.4 KiB
C#

using LiveRecorder.Application.Abstractions.Logging;
using LiveRecorder.Application.Abstractions.Persistence;
using LiveRecorder.Application.Models.Logs;
using LiveRecorder.Domain.Entities;
using LiveRecorder.Domain.Enums;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace LiveRecorder.Application.Services;
public sealed class SystemLogService : ISystemLogService
{
private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly ISystemLogRepository _systemLogRepository;
private readonly ILogger<SystemLogService> _logger;
public SystemLogService(
IServiceScopeFactory serviceScopeFactory,
ISystemLogRepository systemLogRepository,
ILogger<SystemLogService> logger)
{
_serviceScopeFactory = serviceScopeFactory;
_systemLogRepository = systemLogRepository;
_logger = logger;
}
public async Task WriteAsync(
SystemLogLevel level,
string category,
string message,
string? detail = null,
Guid? liveRoomId = null,
Guid? recordSessionId = null,
Guid? recordTaskId = null,
CancellationToken cancellationToken = default)
{
try
{
var entry = new SystemLogEntry(level, category, message, detail, liveRoomId, recordSessionId, recordTaskId, DateTimeOffset.UtcNow);
using var scope = _serviceScopeFactory.CreateScope();
var repository = scope.ServiceProvider.GetRequiredService<ISystemLogRepository>();
var unitOfWork = scope.ServiceProvider.GetRequiredService<IUnitOfWork>();
await repository.AddAsync(entry, cancellationToken);
await unitOfWork.SaveChangesAsync(cancellationToken);
}
catch (Exception ex) when (!cancellationToken.IsCancellationRequested)
{
// Logging must be best-effort. Throwing from here would turn a log
// persistence hiccup into user-visible scheduling failures and noisy alerts.
_logger.LogWarning(
ex,
"System log write failed. Category={Category}; Message={Message}; LiveRoomId={LiveRoomId}; RecordSessionId={RecordSessionId}; RecordTaskId={RecordTaskId}",
category,
message,
liveRoomId,
recordSessionId,
recordTaskId);
}
}
public async Task<IReadOnlyList<SystemLogDto>> ListAsync(
Guid? liveRoomId = null,
Guid? recordSessionId = null,
Guid? recordTaskId = null,
SystemLogLevel? level = null,
string? content = null,
int take = 200,
CancellationToken cancellationToken = default)
{
var entries = await _systemLogRepository.ListAsync(
liveRoomId,
recordSessionId,
recordTaskId,
level,
content,
take,
cancellationToken);
return entries
.Select(static item => new SystemLogDto
{
Id = item.Id,
Level = item.Level,
Category = item.Category,
Message = item.Message,
Detail = item.Detail,
LiveRoomId = item.LiveRoomId,
RecordSessionId = item.RecordSessionId,
RecordTaskId = item.RecordTaskId,
CreatedAt = item.CreatedAt
})
.ToList();
}
}