Serilog基于Seq开源框架实现日志分析

一、NuGet 包管理器中下载相关包

Serilog
Serilog.Sinks.Console(控制台输出)
Serilog.Sinks.File(输出到文件)
Serilog.Sinks.Seq(输出到Seq服务)

二、搭建 Seq 日志服务

Docker命令行快速启动

点击查看代码

复制代码
// 启动项【存储文件挂载到所宿主机,避免重启丢失数据】
docker run -d --name seq -e ACCEPT_EULA=Y   -v  /data/SeqData:/data -e SEQ_FIRSTRUN_ADMINUSERNAME=admin  -e SEQ_FIRSTRUN_ADMINPASSWORD="123456" -p 5341:5341 -p 8082:80 datalust/seq:2025.2
浏览器输入地址查看是否部署成功(http://localhost:8081/)

三、创建Serilog接口以及实现接口

点击查看代码

复制代码
/// <summary>
/// Serilog 日志接口 ISerilogLogger.cs
/// </summary>
public interface ISerilogLogger
{
    /// <summary>
    /// 配置参数
    /// </summary>
    void ConfigureLogger();

    /// <summary>
    /// 日志实例_Seq服务
    /// </summary> 
    /// <returns></returns>
    ILogger CreateSeqLogger();

    /// <summary>
    /// 日志实例_本地文件 
    /// </summary>
    ILogger CreateDefaultLogger();
}

点击查看代码

复制代码
/// <summary>
/// 实现接口 SerilogLogger.cs
/// </summary>
public class SerilogLogger : ISerilogLogger
{
    /// <summary>
    /// Seq服务 URL地址
    /// </summary>
    private readonly string _connectionString;

    /// <summary>
    /// 启动程序
    /// </summary>
    private readonly string _applicationName;

    /// <summary>
    /// 日志实例
    /// </summary>
    private ILogger _logger;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="connectionString">Seq服务 URL地址</param> 
    public SerilogLogger(string connectionString)
    {
        _connectionString = connectionString ?? string.Empty;
        _applicationName = Assembly.GetEntryAssembly()?.GetName().Name ?? string.Empty;

    }

    /// <summary>
    /// 配置参数
    /// </summary>
    public void ConfigureLogger()
    {
        try
        {
            // 若连接字符串为空,则使用本地日志
            if (string.IsNullOrWhiteSpace(_connectionString))
            {
                _logger = CreateDefaultLogger(); return;
            }
            // 配置 Serilog 日志记录器
            _logger = new LoggerConfiguration()
                .WriteTo.Seq(_connectionString)     // 接入Seq日志服务
                .WriteTo.Console()                  // 输出到控制台  
                .Enrich.WithProperty("ApplicationName", _applicationName)
                .MinimumLevel.Verbose() // 设置最低日志级别为 Verbose
                .CreateLogger();
        }
        catch
        {
            // 若配置失败,创建备用日志
            _logger = CreateDefaultLogger();
        }
    }


    /// <summary>
    /// 日志实例_Seq服务
    /// </summary> 
    /// <returns>ILogger</returns>
    public ILogger CreateSeqLogger()
    {
        if (_logger == null)
        {
            return CreateDefaultLogger();
        }
        return _logger;
    }

    /// <summary>
    /// 日志实例_本地文件
    /// </summary>
    /// <returns>ILogger</returns>
    public ILogger CreateDefaultLogger()
    {
        return new LoggerConfiguration()
            .Enrich.WithProperty("ApplicationName", _applicationName)
            .WriteTo.Console()
            .WriteTo.File(
                path: "logs\\default.log",
                rollingInterval: RollingInterval.Day,
                retainedFileCountLimit: 30,     // 保留30天
                fileSizeLimitBytes: 10_000_000, // 单文件最大10MB
                outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj}{NewLine}{Exception}")
            .CreateLogger();
    }
}

四、创建Logger拓展类以及日志类型枚举类

点击查看代码

复制代码
/// <summary>
/// Serilog 日志扩展方法(可选,若本身以满足则可以拓展)
/// </summary>
public static class LoggerExtensions
{
    #region Debug 方法

    /// <summary>
    /// 记录 Debug 级别日志,带 LogType
    /// </summary>
    public static void Debug(this ILogger logger, LogType logType, string message)
    {
        logger.ForContext("LogType", logType).Debug(message);
    }

    /// <summary>
    /// 记录 Debug 级别日志,带 LogType 和参数
    /// </summary>
    public static void Debug(this ILogger logger, LogType logType, string message, params object[] propertyValues)
    {
        logger.ForContext("LogType", logType).Debug(message, propertyValues);
    }

    /// <summary>
    /// 记录 Debug 级别日志,带 LogType 和 Module
    /// </summary>
    public static void Debug(this ILogger logger, LogType logType, string module, string message)
    {
        logger.ForContext("LogType", logType)
              .ForContext("Module", module)
              .Debug(message);
    }

    /// <summary>
    /// 记录 Debug 级别日志,带 LogType、Module 和参数
    /// </summary>
    public static void Debug(this ILogger logger, LogType logType, string module, string message, params object[] propertyValues)
    {
        logger.ForContext("LogType", logType)
              .ForContext("Module", module)
              .Debug(message, propertyValues);
    }

    #endregion

    #region Information 方法

    /// <summary>
    /// 记录 Information 级别日志,带 LogType
    /// </summary>
    public static void Information(this ILogger logger, LogType logType, string message)
    {
        logger.ForContext("LogType", logType).Information(message);
    }

    /// <summary>
    /// 记录 Information 级别日志,带 LogType 和参数
    /// </summary>
    public static void Information(this ILogger logger, LogType logType, string message, params object[] propertyValues)
    {
        logger.ForContext("LogType", logType).Information(message, propertyValues);
    }

    /// <summary>
    /// 记录 Information 级别日志,带 LogType 和 Module
    /// </summary>
    public static void Information(this ILogger logger, LogType logType, string module, string message)
    {
        logger.ForContext("LogType", logType)
              .ForContext("Module", module)
              .Information(message);
    }

    /// <summary>
    /// 记录 Information 级别日志,带 LogType、Module 和参数
    /// </summary>
    public static void Information(this ILogger logger, LogType logType, string module, string message, params object[] propertyValues)
    {
        logger.ForContext("LogType", logType)
              .ForContext("Module", module)
              .Information(message, propertyValues);
    }

    #endregion

    #region Warning 方法

    /// <summary>
    /// 记录 Warning 级别日志,带 LogType
    /// </summary>
    public static void Warning(this ILogger logger, LogType logType, string message)
    {
        logger.ForContext("LogType", logType).Warning(message);
    }

    /// <summary>
    /// 记录 Warning 级别日志,带 LogType 和参数
    /// </summary>
    public static void Warning(this ILogger logger, LogType logType, string message, params object[] propertyValues)
    {
        logger.ForContext("LogType", logType).Warning(message, propertyValues);
    }

    /// <summary>
    /// 记录 Warning 级别日志,带 LogType 和 Module
    /// </summary>
    public static void Warning(this ILogger logger, LogType logType, string module, string message)
    {
        logger.ForContext("LogType", logType)
              .ForContext("Module", module)
              .Warning(message);
    }

    /// <summary>
    /// 记录 Warning 级别日志,带 LogType、Module 和参数
    /// </summary>
    public static void Warning(this ILogger logger, LogType logType, string module, string message, params object[] propertyValues)
    {
        logger.ForContext("LogType", logType)
              .ForContext("Module", module)
              .Warning(message, propertyValues);
    }

    #endregion

    #region Error 方法

    /// <summary>
    /// 记录 Error 级别日志,带 LogType
    /// </summary>
    public static void Error(this ILogger logger, LogType logType, string message)
    {
        logger.ForContext("LogType", logType).Error(message);
    }

    /// <summary>
    /// 记录 Error 级别日志,带 LogType 和异常
    /// </summary>
    public static void Error(this ILogger logger, LogType logType, Exception exception, string message)
    {
        logger.ForContext("LogType", logType).Error(exception, message);
    }

    /// <summary>
    /// 记录 Error 级别日志,带 LogType 和参数
    /// </summary>
    public static void Error(this ILogger logger, LogType logType, string message, params object[] propertyValues)
    {
        logger.ForContext("LogType", logType).Error(message, propertyValues);
    }

    /// <summary>
    /// 记录 Error 级别日志,带 LogType、异常和参数
    /// </summary>
    public static void Error(this ILogger logger, LogType logType, Exception exception, string message, params object[] propertyValues)
    {
        logger.ForContext("LogType", logType).Error(exception, message, propertyValues);
    }

    /// <summary>
    /// 记录 Error 级别日志,带 LogType 和 Module
    /// </summary>
    public static void Error(this ILogger logger, LogType logType, string module, string message)
    {
        logger.ForContext("LogType", logType)
              .ForContext("Module", module)
              .Error(message);
    }

    /// <summary>
    /// 记录 Error 级别日志,带 LogType、Module 和异常
    /// </summary>
    public static void Error(this ILogger logger, LogType logType, string module, Exception exception, string message)
    {
        logger.ForContext("LogType", logType)
              .ForContext("Module", module)
              .Error(exception, message);
    }

    #endregion

    #region Fatal 方法

    /// <summary>
    /// 记录 Fatal 级别日志,带 LogType
    /// </summary>
    public static void Fatal(this ILogger logger, LogType logType, string message)
    {
        logger.ForContext("LogType", logType).Fatal(message);
    }

    /// <summary>
    /// 记录 Fatal 级别日志,带 LogType 和异常
    /// </summary>
    public static void Fatal(this ILogger logger, LogType logType, Exception exception, string message)
    {
        logger.ForContext("LogType", logType).Fatal(exception, message);
    }

    /// <summary>
    /// 记录 Fatal 级别日志,带 LogType 和参数
    /// </summary>
    public static void Fatal(this ILogger logger, LogType logType, string message, params object[] propertyValues)
    {
        logger.ForContext("LogType", logType).Fatal(message, propertyValues);
    }

    /// <summary>
    /// 记录 Fatal 级别日志,带 LogType、异常和参数
    /// </summary>
    public static void Fatal(this ILogger logger, LogType logType, Exception exception, string message, params object[] propertyValues)
    {
        logger.ForContext("LogType", logType).Fatal(exception, message, propertyValues);
    }

    /// <summary>
    /// 记录 Fatal 级别日志,带 LogType 和 Module
    /// </summary>
    public static void Fatal(this ILogger logger, LogType logType, string module, string message)
    {
        logger.ForContext("LogType", logType)
              .ForContext("Module", module)
              .Fatal(message);
    }

    /// <summary>
    /// 记录 Fatal 级别日志,带 LogType、Module 和异常
    /// </summary>
    public static void Fatal(this ILogger logger, LogType logType, string module, Exception exception, string message)
    {
        logger.ForContext("LogType", logType)
              .ForContext("Module", module)
              .Fatal(exception, message);
    }

    #endregion

    #region Verbose 方法

    /// <summary>
    /// 记录 Verbose 级别日志,带 LogType
    /// </summary>
    public static void Verbose(this ILogger logger, LogType logType, string message)
    {
        logger.ForContext("LogType", logType).Verbose(message);
    }

    /// <summary>
    /// 记录 Verbose 级别日志,带 LogType 和参数
    /// </summary>
    public static void Verbose(this ILogger logger, LogType logType, string message, params object[] propertyValues)
    {
        logger.ForContext("LogType", logType).Verbose(message, propertyValues);
    }

    /// <summary>
    /// 记录 Verbose 级别日志,带 LogType 和 Module
    /// </summary>
    public static void Verbose(this ILogger logger, LogType logType, string module, string message)
    {
        logger.ForContext("LogType", logType)
              .ForContext("Module", module)
              .Verbose(message);
    }

    /// <summary>
    /// 记录 Verbose 级别日志,带 LogType、Module 和参数
    /// </summary>
    public static void Verbose(this ILogger logger, LogType logType, string module, string message, params object[] propertyValues)
    {
        logger.ForContext("LogType", logType)
              .ForContext("Module", module)
              .Verbose(message, propertyValues);
    }

    #endregion
}

点击查看代码

复制代码
/// <summary>
/// 日志类型(可选或自定义)
/// </summary>
public enum LogType
{
    /// <summary>
    /// 系统日志 - 系统启动、关闭、配置变更等系统级操作
    /// </summary>
    System = 1,

    /// <summary>
    /// 操作日志 - 用户业务操作、业务流程记录
    /// </summary>
    Operation = 2,

    /// <summary>
    /// 硬件日志 - 设备状态、硬件交互、传感器等
    /// </summary>
    Hardware = 3,

    /// <summary>
    /// 安全日志 - 登录认证、权限变更、安全事件等
    /// </summary>
    Security = 4,

}

五、写入Prism容器,方便其它地方调用

点击查看代码

复制代码
 // protected override void RegisterTypes(IContainerRegistry containerRegistry) 方法
 #region 注册单例:通过 Prism 容器管理 日志实例   
 // 获取 Seq服务URL 
 string connectionString = ConnectionString["ConnectionString"]?.ToString() ?? string.Empty;
 // 注册时先初始化日志配置
 var loggerInstance = new SerilogLogger(connectionString);
 loggerInstance.ConfigureLogger(); // 默认调用输出到Seq服务
 containerRegistry.RegisterSingleton<ISerilogLogger>(() => loggerInstance);
 #endregion

点击查看代码

c# 复制代码
// 示例:记录调试日志
// 从容器获取日志实例:CreateSeqLogger()输出到Seq服务,MainWindowViewModel调用上下文
ILogger logger = container.Resolve<ISerilogLogger>().CreateSeqLogger().ForContext<MainWindowViewModel>();
// 一、基本用法(等级 + 模块 + 记录文本)
logger.Debug(LogType.System, "系统模块", "巡检系统启动成功。。。");
// 二、参数用法(等级 + 模块 + 消息模板 + 消息参数) 
logger.Information(LogType.Operation, "订单模块", "购买{Product}成功!总计金额:{Amount}美元", "海康工业相机", "$5000.00");

六、Seq日志分析平台

Seq官方地址:https://datalust.co/

相关推荐
请叫我阿杰18 小时前
Ubuntu系统安装.NET SDK 7.0
数据库·ubuntu·.net
追逐时光者20 小时前
小伙伴们学习 C#/.NET 相关技术栈的学习心得和路线
后端·.net
Full Stack Developme21 小时前
java.net.http 包详解
java·http·.net
喵叔哟1 天前
64.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--新增功能--预算报表
微服务·架构·.net
z2014z1 天前
LitJSON 轻量级、高效易用的 .NET JSON 库 深度解析与实战指南
json·.net
生财1 天前
.NET 10发布和它的新增功能
.net
q***56381 天前
深入浅出 SQLSugar:快速掌握高效 .NET ORM 框架
.net
Crazy Struggle1 天前
告别人工干预!C# 轻量级上位机自动联动 MES 与视觉检测
c#·.net·mes
小码编匠1 天前
.NET 10 性能突破:持续优化才是质变关键
后端·c#·.net