为了账号安全,请及时绑定邮箱和手机立即绑定

动态设置每个 Logger 实例的 Nlog 日志级别 ASP.Net Core 2.x

动态设置每个 Logger 实例的 Nlog 日志级别 ASP.Net Core 2.x

C#
拉丁的传说 2021-11-21 10:47:40
目标:动态选择我想要详细记录的 HTTP 请求(不同的日志级别)。概述:我有一个 ASP.Net core 2.1 Web 服务器正在运行,并且一旦投入生产,如果我需要调试问题,我希望能够更改日志级别。我找到了如何全局更改日志级别;但是,更改日志级别是持久的......也就是每次调用我的控制器后都不会重置。    [HttpGet]    public async Task<IEnumerable<string>> Get()    {        this.Logger.LogTrace("This should NOT get logged");        SetMinLogLevel(LogLevel.Trace);        this.Logger.LogTrace("This should be logged");        return new string[] { "value1", "value2" };    }   public static void SetMinLogLevel(LogLevel NewLogLevel)    {        foreach (var rule in LogManager.Configuration.LoggingRules)        {            rule.EnableLoggingForLevel(NewLogLevel);        }        //Call to update existing Loggers created with GetLogger() or         //GetCurrentClassLogger()        LogManager.ReconfigExistingLoggers();    }我希望请求者能够在他们的 HTTP 请求(标头或 cookie)中设置一个标志,以便为每个请求启用更详细的日志记录级别。这样我就不会用来自请求者的详细日志淹没我的日志。问题:如何动态设置每个记录器实例的日志级别?(我相信这是正确的措辞)我目前正在使用 NLog 包 4.5。
查看完整描述

3 回答

?
跃然一笑

TA贡献1826条经验 获得超6个赞

NLog 4.6.7 允许您在日志记录规则过滤器中使用布局minLevel/maxLevel

您可以使用默认日志级别的 NLog-Config-Variable,然后在您的 Web 应用程序上创建一个隐藏方法来修改 NLog-Config-Variable 并调用ReconfigExistingLoggers().

然后设置一个计时器,在 30 秒后将该 NLog-Config-Variable 恢复为其原始值。并且还调用了ReconfigExistingLoggers()

另见:https : //github.com/NLog/NLog/wiki/Filtering-log-messages#semi-dynamic-routing-rules


查看完整回答
反对 回复 2021-11-21
?
30秒到达战场

TA贡献1828条经验 获得超6个赞

与其尝试自定义 NLog 日志记录级别(这会影响整个过程),我认为您应该寻求一种解决方案来修改日志语句本身的日志级别。


要完成这项工作,您需要具备以下条件:


一种机制,用于识别您想要调试日志记录的请求

记录器的包装器,以便您可以动态覆盖日志级别

第一个要求很简单 - 设置 cookie 或自定义 HTTP 标头,并检查两者是否存在。您需要将此检查的结果提供给您的 LogWrapper 实例,以便它知道什么时候应该做一些特殊的事情。


LogWrapper 必须针对每个请求进行实例化,以便实例不会跨请求共享。最简单的方法是在控制器的构造函数中按需创建它(但你也可以将它连接到 DI 容器以进行自动注入)。


这看起来像这样:


public class HomeController : Controller

{

    private readonly LogWrapper _logger;


    public HomeController(ILogger<HomeController> logger)

    {

        var isDebugRequest = ...;

        _logger = new LogWrapper<HomeController>(logger, isDebugRequest);

    }    


    ...

}

此处解释了为 NLog 创建日志包装器的基础知识,但您似乎已经在使用为 Microsoft.Extensions.Logging 创建的包装器,因此您需要改为包装该接口:


public class LogWrapper<T> : Microsoft.Extensions.Logging.ILogger

{

    private readonly ILogger<T> _logger;

    private readonly bool _debug;


    public LogWrapper(ILogger<T> logger, bool isDebug)

    {

        _logger = logger;

        _debug = isDebug;

    }    


    public void Log<TState>(LogLevel logLevel,

                            EventId eventId,

                            TState state,

                            Exception exception,

                            Func<TState, Exception, string> formatter)

    {

        if (_debug) 

        {

            // override log level here

            _logger.Log(LogLevel.Warning, eventId, state, exception, formatter); 

        }

        else 

        {

            _logger.Log(logLevel, eventId, state, exception, formatter);

        }

    }


    // ILogger has two other methods you'll need to implement

}    

这种方法的缺点是日志语句没有其原始日志级别,这对您的用例可能重要也可能不重要。


查看完整回答
反对 回复 2021-11-21
?
POPMUISE

TA贡献1765条经验 获得超5个赞

也许您可以使用 session-cookie 来控制是否启用调试模式:


<targets>

    <target type="file" name="logfile" filename="applog.txt" />

</targets>

<rules>

    <logger name="*" minlevel="Off" writeTo="logfile" ruleName="debugCookieRule">

      <filters defaultAction="Log">

         <when condition="'${aspnet-session:EnableDebugMode}' == ''" action="Ignore" />

      </filters>

    </logger>

</rules>

然后像这样激活会话cookie:


public void SetMinLogLevel(LogLevel NewLogLevel)

{

    var cookieRule = LogManager.Configuration.FindRuleByName("debugCookieRule");

    if (cookieRule != null)

    {

        cookieRule.MinLevel = NewLogLevel;


        // Schedule disabling of logging-rule again in 60 secs.

        Task.Run(async () => { await Task.Delay(60000).ConfigureAwait(false); cookieRule.MinLevel = LogLevel.Off; LogManager.ReconfigExistingLoggers(); });


        // Activate EnableDebugMode for this session

        HttpContext.Session.SetString("EnableDebugMode", "Doctor has arrived");

    }


    LogManager.ReconfigExistingLoggers();  // Refresh loggers

}

如果${aspnet-session}不需要session-cookies ,那么 NLog.Web.AspNetCore 有其他选项来提取 HttpContext-details。另见:https : //nlog-project.org/config/?tab=layout-renderers&search=package : nlog.web.aspnetcore


查看完整回答
反对 回复 2021-11-21
  • 3 回答
  • 0 关注
  • 557 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信