运行期动态配置 Nlog 日志打印

需求是这样,客户说在调试阶段需要随时跟踪日志,上线阶段需要关闭一些日志

但是几年前由于客户在开发的时候,没有严格的安装一些日志等级来使用 NLog,所以 log.Info("xxx") 这种随处可见。从今天的角度来说,调试的日志应该使用 log.Debug("xxx"),但是从代码的规模来说,已经不便于再去修改每一处地方。

好在 客户要关掉的日志有一些明显的特征

logger.Info($"Tx: {hex}");

比如像上面这样以 “Tx:” 开头的

在Nlog 初始化之前,可以使用他自己的配置文件来忽略掉这个日志

<nlog>
  <rules>
    <logger name="*" minlevel="Trace" writeTo="file">
      <filters>
        <when condition="starts-with('${message}', 'Tx:')" action="Ignore" />
      </filters>
    </logger>
  </rules>
</nlog>

但是这样一来,我在服务端想要随时的打开和关闭这个设置就尤为麻烦了,尤其是这种配置如果放在 Android App 里面,修改配置还要修改 App 本地的文件,着显然是行不通的。所以目的是放在服务器端的数据库,通过远程的配置来刷新本地 App,这个时候需要从远程的服务器读取配置,在运行时改变 NLog 的行为。

下面写一个帮助类和一个控制台程序来测试这个功能

using Newtonsoft.Json.Linq;
using NLog;
using NLog.Config;
using NLog.Filters;
using NLog.Targets;

namespace Bestrane.Common
{
    public class NLogConfigurator
    {
        public static void ConfigureGlobalLoggingRules(Target target, string loggerName, string jsonConfig)
        {
            // Get NLog configuration
            LoggingConfiguration config = LogManager.Configuration;

            // Parse the JSON configuration text
            JObject configObject = JObject.Parse(jsonConfig);
            string logLevel = configObject["LoggingLevel"].Value<string>();


            LogLevel level = LogLevel.FromString(logLevel);
            bool ignoreSwitch = configObject["LogIgnore"].Value<bool>();
            JArray ignoreConditions = (JArray)configObject["LogIgnoreConditions"];

            // Create a new rule
            var rule = new LoggingRule(loggerName, level, target);

            // Add condition filters based on the IgnoreSwitch value
            if (ignoreSwitch)
            {
                foreach (var condition in ignoreConditions)
                {
                    // Create a new condition filter
                    var conditionFilter = new ConditionBasedFilter
                    {
                        Condition = condition.ToString(),
                        Action = FilterResult.Ignore
                    };

                    rule.Filters.Add(conditionFilter);
                }
            }
            // Add the new rule to the configuration
            config.LoggingRules.Add(rule);


            // Reconfigure NLog
            LogManager.Configuration = config;
        }
    }
}

控制台程序

jsonConfig 是模拟配置文件的 Json字符串,可以从服务端的数据库读取出来

LoggingLevel 为当前使用的日志级别,例如设置为 Info ,那么下面 Debug 的日志就不会打印出来了

LogIgnore 为是否忽略,为True就会开启 LogIgnoreConditions 的条件过滤,那么满足条件的日志就不会打印出来,反正如果设置为 False,那么就不会按条件过滤了

至于 starts-with('${message}', 'Tx:') 这样的写法,不是我实现的解析,而是 NLog 自身支持的,需要时,自行去查阅 NLog 的资料

using System;
using Bestrane.Common;
using NLog.Targets;

namespace Bestrane.LoggingConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            string loggerName = "LcpApi";
            string jsonConfig = @"
            {
                ""LoggingLevel"": ""Info"",
                ""LogIgnore"": true,
                ""LogIgnoreConditions"": [
                    ""starts-with('${message}', 'Tx:')"",
                    ""starts-with('${message}', 'Rx:')"",
                ]
             }";

            var consoleTarget = new ConsoleTarget();
            consoleTarget.Layout = "[${uppercase:${level}}] ${logger} - ${message}";

            // Call the global logging rule configuration method at application startup
            NLogConfigurator.ConfigureGlobalLoggingRules(consoleTarget, loggerName, jsonConfig);
            NLog.Logger logger = NLog.LogManager.GetLogger(loggerName);

            logger.Info("Info: start");
            logger.Info("Tx: Info Sample log message");
            logger.Info("Rx: Info Sample log message");
            logger.Info("Info: end");

            logger.Debug("Debug: start");
            logger.Debug("Tx: Debug Sample log message");
            logger.Debug("Rx: Debug Sample log message");
            logger.Debug("Debug: end");

            Console.ReadKey();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值