1

I have an nlog config file set to file output and this code to set the output to RichTextBox

public void SetupFormLogger()
    {            
        NLog.Windows.Forms.RichTextBoxTarget target = new NLog.Windows.Forms.RichTextBoxTarget();
        target.Name = "control"; 
        target.Layout = "${longdate} ${level:uppercase=true} ${logger} ${message}";
        target.ControlName = richtextLog.Name;
        target.FormName = this.Name;
        target.TargetForm = this;
        target.AutoScroll = true;
        target.MaxLines = 10000;
        target.UseDefaultRowColoringRules = false;
        target.RowColoringRules.Add(
            new RichTextBoxRowColoringRule(
                "level == LogLevel.Trace", // condition
                "WhiteSmoke", // font color
                "Black", // background color
                FontStyle.Regular
            )
        );            
        target.RowColoringRules.Add(new RichTextBoxRowColoringRule("level == LogLevel.Debug", "Gray", "Black"));
        target.RowColoringRules.Add(new RichTextBoxRowColoringRule("level == LogLevel.Info", "WhiteSmoke", "Black"));
        target.RowColoringRules.Add(new RichTextBoxRowColoringRule("level == LogLevel.Warn", "Yellow", "Black"));
        target.RowColoringRules.Add(new RichTextBoxRowColoringRule("level == LogLevel.Error", "White", "DarkRed", FontStyle.Bold));
        target.RowColoringRules.Add(new RichTextBoxRowColoringRule("level == LogLevel.Fatal", "Yellow", "DarkRed", FontStyle.Bold));

        AsyncTargetWrapper asyncWrapper = new AsyncTargetWrapper();
        asyncWrapper.Name = "AsyncRichTextBox";
        asyncWrapper.WrappedTarget = target;

        SimpleConfigurator.ConfigureForTargetLogging(asyncWrapper, LogLevel.Debug);
    }

If I call this function it won't log anymore to file and if I don't call this function it logs to file. How can I make NLog to log both to file and RichTextBox at the same time?

And this is my nlog config file

<?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"
      xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
      autoReload="true"
      throwExceptions="false"
      internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">

  <variable name="myvar" value="myvalue"/>

  <targets>

      <target name="f" xsi:type="File" layout="${longdate} | ${module} | ${logger} | ${level} | ${message}" fileName="${basedir}/logs/${shortdate}.log" />      

   </targets>

  <rules>   
      <logger name="*" minlevel="Debug" writeTo="f" />      
  </rules>
</nlog>
Mario
  • 13,941
  • 20
  • 54
  • 110

2 Answers2

2
    LoggingRule richTextBoxRule = new LoggingRule("*",  asyncWrapper);
    richTextBoxRule.EnableLoggingForLevel(LogLevel.Debug);
    richTextBoxRule.EnableLoggingForLevel(LogLevel.Error);
    richTextBoxRule.EnableLoggingForLevel(LogLevel.Fatal);
    richTextBoxRule.EnableLoggingForLevel(LogLevel.Info);
    richTextBoxRule.EnableLoggingForLevel(LogLevel.Trace);
    richTextBoxRule.EnableLoggingForLevel(LogLevel.Warn);

    LogManager.Configuration.AddTarget(asyncWrapper.Name, asyncWrapper);
    LogManager.Configuration.LoggingRules.Add(richTextBoxRule);
    LogManager.ReconfigExistingLoggers();

Sadly enough, then it is not easy to dynamically close/remove the target again (Until https://github.com/NLog/NLog/pull/2259 is complete). So you should not close the window again, but just hide it and unhide afterwards (avoid creating multiple target registrations).

Rolf Kristensen
  • 17,785
  • 1
  • 51
  • 70
  • I have added this and removed this line SimpleConfigurator.ConfigureForTargetLogging(asyncWrapper, LogLevel.Debug);, but the log goes only to richtextbox – Mario Oct 28 '17 at 09:10
  • Guess you have to use the debugger to see what logging-rules and targets you have configured in the LogManager.Configuration-object. Else you have to turn to the InternalLogger https://github.com/NLog/NLog/wiki/Internal-Logging – Rolf Kristensen Oct 28 '17 at 10:24
  • The internal logging also does not work if I don't remove the richtextbox function – Mario Oct 28 '17 at 10:29
  • Then you just have to look at the LogManager.Configuration-object to see if you some how remove all other targets and logging-rules. And maybe the internal logger up to the logging stop working will show why it stops working (Maybe in combination with debugger, so you can see what statement that makes the logging stop working). – Rolf Kristensen Oct 28 '17 at 10:37
  • Now if I remove the richtextbox setup it does not log to file at all, very strange. And internal logging does not work – Mario Oct 28 '17 at 10:56
  • Think you have to step back to a simple working configuration, and continue from there. (P.S. internalLogLevel="Off" in your nlog.config). Maybe the issue is just that you have forgot to configure copy-always on the nlog.config file in Visual Studio. – Rolf Kristensen Oct 28 '17 at 10:58
  • copy always is set, also I have tried internalLogToConsole="true" and nlog does not write anything to console – Mario Oct 28 '17 at 11:03
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/157703/discussion-between-mario-m-and-rolf-kristensen). – Mario Oct 28 '17 at 11:03
1

You can configure a second target for NLog by calling

LogManager.Configuration.AddTarget(asyncWrapper);

More information: https://github.com/nlog/NLog/wiki/Configuration-API

This is assuming that you've already set up your file target somewhere else. You would want to call that code after the file target is set up. It could be helpful to see how you configure file logging also though.

Edit: here's a related question: How to log to multiple targets using NLog?

Kevin Secrist
  • 821
  • 10
  • 23