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/

相关推荐
百锦再5 小时前
Vue Scoped样式混淆问题详解与解决方案
java·前端·javascript·数据库·vue.js·学习·.net
CodeCraft Studio6 小时前
【能源与流程工业案例】KBC借助TeeChart 打造工业级数据可视化平台
java·信息可视化·.net·能源·teechart·工业可视化·工业图表
一个帅气昵称啊6 小时前
使用微软Agent Framework .NET构建智能代理应用
microsoft·flask·.net
一个天蝎座 白勺 程序猿7 小时前
深度解析:通过ADO.NET驱动Kdbndp高效连接与操作Kingbase数据库
数据库·.net·wpf·kingbase·金仓数据库
时光追逐者9 小时前
一个使用 WPF 开发的 Diagram 画板工具(包含流程图FlowChart,思维导图MindEditor)
c#·.net·wpf·流程图
我是唐青枫9 小时前
C#.NET FluentValidation 全面解析:优雅实现对象验证
c#·.net
VB.Net9 小时前
VB.Net循序渐进(第二版)
开发语言·.net·vb.net
小丫头呀9 小时前
.NET8 通过自定义类映射appsettings.json 文件某个节点的配置
json·.net·.net8