feat: add server logs functionality with role-based access and system channel management

- Introduced a new migration to add the IsSystem column to the Channels table.
- Updated the DbContext model snapshot to reflect the new IsSystem property.
- Enhanced the ChannelService to manage system channels, including creation, visibility control, and protection against deletion.
- Implemented ServerLogsService to handle live server logging, including reading from log files and managing access based on user roles.
- Created ServerLogsSink to queue log events for streaming to the live log room.
- Developed ServerLogsStreamService to stream log events to clients in real-time.
- Added configuration options for server logs in appsettings.
- Implemented comprehensive unit tests for channel service system channel behavior and server logs functionality.
This commit is contained in:
HueByte
2026-07-17 20:44:47 +02:00
parent df1bd0119c
commit 38eca99fb1
22 changed files with 1569 additions and 17 deletions
@@ -0,0 +1,43 @@
using EchoHub.Core.Models;
using Serilog.Events;
namespace EchoHub.Server.Config;
/// <summary>
/// Live server-log room settings, bound from the "ServerLogs" config section (env override:
/// <c>ServerLogs__Enabled</c> etc.). When enabled, a read-only system channel is auto-created
/// and log events are streamed to it live — log lines are never stored as messages in the
/// database; the rolling Serilog log files remain the only persistence.
/// </summary>
public sealed class ServerLogsOptions
{
/// <summary>Master switch for the live log room.</summary>
public bool Enabled { get; set; } = true;
/// <summary>
/// Name of the auto-created system channel. Must satisfy the normal channel-name rules;
/// the name is reserved — users cannot create a channel with it.
/// </summary>
public string RoomName { get; set; } = "server-logs";
/// <summary>Minimum server role allowed to see and join the log room (Member/Mod/Admin/Owner).</summary>
public ServerRole MinRole { get; set; } = ServerRole.Mod;
/// <summary>
/// Minimum level of log events streamed to the room (Verbose/Debug/Information/Warning/
/// Error/Fatal). Only affects the room — file and console sinks keep their own levels.
/// </summary>
public LogEventLevel MinLevel { get; set; } = LogEventLevel.Information;
/// <summary>How many recent log entries are replayed from the log file when someone opens the room.</summary>
public int BacklogLines { get; set; } = 100;
/// <summary>Directory holding the rolling log files. Must match the Serilog file sink's path.</summary>
public string LogDirectory { get; set; } = "logs";
/// <summary>Filename glob for the rolling log files inside <see cref="LogDirectory"/>.</summary>
public string LogFilePattern { get; set; } = "echohub-server-*.log";
/// <summary>Channel names are stored lowercased; compare against this form.</summary>
public string NormalizedRoomName => RoomName.ToLowerInvariant().Trim();
}