You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NLog中实现Serilog的子日志(Sublog)过滤功能?

在NLog中实现Serilog子日志的过滤功能

你之前用Serilog时通过子日志实现了基于日志源的过滤输出,现在需要在NLog中复刻同样的逻辑:针对ExceptionMiddleware和SomeProjectName分别配置独立的日志目标(邮件/文件),同时保留全局的日志输出。

原Serilog配置回顾

Log.Logger = new LoggerConfiguration()
                .Enrich.FromLogContext()
                .WriteTo.File(...filapath...)
                .WriteTo.Logger(l => l
                    .Filter.ByIncludingOnly(Matching.FromSource<ExceptionMiddleware>())
                    .WriteTo.Email(new EmailConnectionInfo()
                    {
                        FromEmail = fromEmail,
                        ToEmail = toEmail,
                        EmailSubject = subject,
                        NetworkCredentials = credentials,
                        Port = port,
                        MailServer = mailServer,
                    }))
                .WriteTo.Logger(l => l
                    .Filter.ByIncludingOnly(Matching.FromSource("SomeProjectName"))
                    .WriteTo.File(anotherFilePath)
                    .WriteTo.Email(new EmailConnectionInfo()
                    {
                        FromEmail = fromEmail,
                        ToEmail = toEmail,
                        EmailSubject = subject,
                        NetworkCredentials = credentials,
                        Port = port,
                        MailServer = mailServer,
                    }, restrictedToMinimumLevel: LogEventLevel.Error,
                        outputTemplate:
                        "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{NewLine}{Exception}"))
                .CreateLogger();

修改后的NLog配置

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <extensions>
        <add assembly="NLog.Extended" />
        <add assembly="NLog.MailKit" />
        <add assembly="NLog.Web" />
        <add assembly="NLog.Web.AspNetCore" />
    </extensions>

    <variable name="smtp-server" value="smtp-server" />
    <variable name="smtp-port" value="port" />
    <variable name="smtp-password" value="password" />
    <variable name="smtp-authentication" value="Basic" />
    <variable name="smtp-ssl" value="ssl" />
    <variable name="smtp-username" value="username" />
    <variable name="smtp-from" value="from" />
    <variable name="smtp-to" value="to" />
    <variable name="logTimestampFormat" value="${date:format=yyyy-MM-dd HH:mm:ss.fff zzz}" />

    <targets>
        <!-- 全局文件日志 -->
        <target name="fileLogs"
                xsi:type="File"
                fileName="${currentdir}/Logs/log.txt"
                createDirs="True" />
        
        <!-- ExceptionMiddleware专属邮件日志 -->
        <target name="exceptionMiddlewareMailLogs" xsi:type="Mail"
                subject="ExceptionMiddleware 异常通知"
                body="${logTimestampFormat} [${level}] ${message}${newline}${exception}"
                from="${smtp-from}"
                to="${smtp-to}"
                smtpUsername="${smtp-username}"
                secureSocketOption="sslOnConnect"
                enableSsl="${smtp-ssl}"
                smtpPassword="${smtp-password}"
                smtpAuthentication="${smtp-authentication}"
                smtpServer="${smtp-server}"
                smtpPort="${smtp-port}" />
        
        <!-- SomeProjectName专属文件日志 -->
        <target name="someProjectFileLogs"
                xsi:type="File"
                fileName="${currentdir}/Logs/SomeProjectName/log.txt"
                createDirs="True"
                layout="${logTimestampFormat} [${level}] ${message}${newline}${exception}" />
        
        <!-- SomeProjectName专属错误邮件日志 -->
        <target name="someProjectErrorMailLogs" xsi:type="Mail"
                subject="SomeProjectName 错误通知"
                body="${logTimestampFormat} [${level}] ${message}${newline}${newline}${exception}"
                from="${smtp-from}"
                to="${smtp-to}"
                smtpUsername="${smtp-username}"
                secureSocketOption="sslOnConnect"
                enableSsl="${smtp-ssl}"
                smtpPassword="${smtp-password}"
                smtpAuthentication="${smtp-authentication}"
                smtpServer="${smtp-server}"
                smtpPort="${smtp-port}" />
    </targets>

    <rules>
        <!-- 全局日志规则 -->
        <logger name="*" levels="Info,Debug,Error" writeTo="fileLogs" />
        <!-- 注意:原配置里的consoleLogs目标未定义,若不需要可删除 -->
        <logger name="*" levels="Info,Error" writeTo="consoleLogs" />
        
        <!-- ExceptionMiddleware的日志规则:仅匹配该类的日志,发送到专属邮件 -->
        <logger name="YourNamespace.ExceptionMiddleware" minlevel="Info" writeTo="exceptionMiddlewareMailLogs" final="true" />
        
        <!-- SomeProjectName的日志规则:匹配该项目下的所有日志 -->
        <!-- 1. 输出到专属文件 -->
        <logger name="SomeProjectName*" levels="Info,Debug,Error" writeTo="someProjectFileLogs" />
        <!-- 2. 仅Error级别输出到专属邮件 -->
        <logger name="SomeProjectName*" minlevel="Error" writeTo="someProjectErrorMailLogs" final="true" />
        
        <!-- 全局错误邮件(如需保留原全局错误通知可保留,否则删除) -->
        <!-- <logger name="*" minlevel="Error" writeTo="mailLogs" /> -->
    </rules>
</nlog>

关键配置说明

  • 日志源匹配:NLog通过<logger>的name属性实现过滤,对应Serilog的Matching.FromSource:
    • 针对类:使用完整命名空间+类名(如YourNamespace.ExceptionMiddleware)实现精准匹配
    • 针对项目:用SomeProjectName*通配符,匹配所有以该前缀命名的日志器
  • 专属目标:为每个过滤规则创建独立的<target>,对应Serilog子日志里的WriteTo逻辑
  • final="true":标记该规则处理后不再向下传递,避免日志被重复输出(不需要阻止后续规则可去掉)
  • 输出格式:通过layout(文件目标)和body(邮件目标)配置,对应Serilog的outputTemplate,用统一变量保证格式一致性

内容的提问来源于stack exchange,提问作者saibel203

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 16:13:09