【问题标题】:How to change the NLog layout at run time?如何在运行时更改 NLog 布局?
【发布时间】:2018-03-17 13:59:50
【问题描述】:

我创建了 NLog.config:

<?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"
      throwExceptions="false"
      throwConfigExceptions="true"> <!--make NLog complain, when something is wrong with the configuration-->


  <targets>
    <target name="logfile" xsi:type="File" 
            fileName="${basedir}/Logs/Log_${shortdate}.txt" 
            layout="[${longdate}] [${uppercase:${level}}] ${message} ${exception:format=tostring}"
            />
    <target name="logconsole" xsi:type="ColoredConsole" 
            layout="[${longdate}] ${uppercase:${level}}: ${message} ${exception:format=tostring}"
            />    
  </targets>

  <rules>
    <logger name="*" minlevel="Info" writeTo="logconsole" />
    <logger name="*" minlevel="Debug" writeTo="logfile" />

  </rules>
</nlog>

当我调用logger.Info("Hello World"); 时,我在控制台和文件中都得到了输出:

[2018-03-17 15:34:24.2843] INFO: Hello World

这很好。 现在在某些情况下我不想显示日期时间部分,我只想在控制台中显示它。

我将如何使用 NLog 做到这一点?

我想要的解决方案是:

logger.Info("Hello World", writeTo: "logconsole", layout: "[${uppercase:${level}}] ${message}");

我尝试添加一个新的taget

<target name="logconsole_simple" xsi:type="ColoredConsole"
            layout="${uppercase:${level}}: ${message} ${exception:format=tostring}"/>

和新规则:

<logger name="logconsole_simple"  level="Info" writeTo="logconsole_simple" />

然后这样称呼它:

logger.Log(LogEventInfo.Create(LogLevel.Info, "logconsole_simple", "simple message!"));

但它仍然显示日期时间部分并将其记录到文件中(我不想要)。 如何解决这个问题?

【问题讨论】:

    标签: c# logging nlog


    【解决方案1】:

    为您的特殊情况添加目标和规则,并按名称引用您的记录器。

    配置:

    <?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"
          throwExceptions="false"
          throwConfigExceptions="true"><!--make NLog complain, when something is wrong with the configuration-->
    
      <targets>
        <target name="logfile" xsi:type="File"
                fileName="${basedir}/Logs/Log_${shortdate}.txt"
                layout="[${longdate}] [${uppercase:${level}}] ${message} ${exception:format=tostring}"
        />
        <target name="logconsole_default" xsi:type="Console"
                layout="[${longdate}] ${uppercase:${level}}: ${message} ${exception:format=tostring}"
        />
        <target name="logconsole_other" xsi:type="Console"
                layout="${uppercase:${level}}: ${message} ${exception:format=tostring}"
        />
      </targets>
    
      <rules>
        <logger name="default" minlevel="Debug" writeTo="logfile" />
        <logger name="default" minlevel="Info" writeTo="logconsole_default" />
        <logger name="other" minlevel="Info" writeTo="logconsole_other" />
      </rules>
    </nlog>
    

    用法:

    internal class Program
    {
        private static readonly Logger DefaultLogger = LogManager.GetLogger("default");
    
        private static readonly Logger OtherLogger = LogManager.GetLogger("other");
    
        private static void Main(string[] args)
        {
            for (var i = 0; i < 2; i++)
            {
                if (i % 2 == 0)
                {
                    DefaultLogger.Info("normal log message");
                }
                else
                {
                    OtherLogger.Info("special case");
                }
            }
        }
    }
    

    编辑:如果您真的想通过修改现有目标和规则在代码中执行此操作,您可以(这将与您原始帖子中的配置一起使用):

    using System.Linq;
    using NLog;
    using NLog.Layouts;
    using NLog.Targets;
    
    internal class Program
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
    
        private static void Main(string[] args)
        {
            for (var i = 0; i < 2; i++)
            {                
                if (i % 2 == 0)
                {
                    Logger.Info("normal log message");
                }
                else
                {
                    // reconfigure
                    var consoleTarget = LogManager.Configuration.FindTargetByName<ColoredConsoleTarget>("logconsole");
                    var oldLayout = consoleTarget.Layout;
                    consoleTarget.Layout = new SimpleLayout { Text = "${uppercase:${level}}: ${message} ${exception:format=tostring}" };
                    var fileRule = LogManager.Configuration.LoggingRules.Single(r => r.Targets.Any(t => t.Name == "logfile"));
                    LogManager.Configuration.LoggingRules.Remove(fileRule);
                    LogManager.Configuration.Reload();
    
                    Logger.Info("special case");
    
                    // replace originals
                    consoleTarget.Layout = oldLayout;
                    LogManager.Configuration.LoggingRules.Add(fileRule);
                    LogManager.Configuration.Reload();
                }
            }
        }
    }
    

    【讨论】:

    • 您知道这是否是添加OtherLogger 的唯一方法吗?这不能在运行时为DefaultLogger 更改以用于特定 案例使用吗?
    猜你喜欢
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    • 1970-01-01
    • 2011-04-13
    • 2013-09-17
    • 1970-01-01
    • 1970-01-01
    • 2015-04-20
    相关资源
    最近更新 更多