Nlog: How to create logging entities dynamically

Created on 16 Aug 2020  路  8Comments  路  Source: NLog/NLog

Hi!

I am using NLogviewer WPF panel to show logs with NLog 4.0.3 in a .NET 4.6.2 framework application.
The user can create dynamically "Servers" that are inserted into a controller/listview. Severs can go from "0 ... N".

How can I create and isolate logs from each of these items inserted in the controller and logs trace separately?

In this picture you can see the use case ... each time that the user select an item form the list the NLogviewer should show only the log of the selected item.

Any help or example about how to consume logs dynamically/programmatically for at least 2 entities would be appreciated.

image

question

Most helpful comment

I don't know if your used (NLogViewer) library supports multi targeting, but mine does. Here is the link to the readme how you can configure it https://github.com/dojo90/NLogViewer#multi-targeting

All 8 comments

Hi! Thanks for opening your first issue here! Please make sure to follow the issue template - so we could help you better!

I would recommend to read this:

https://github.com/NLog/NLog/wiki/Configuration-file#rules

The same applies for configuration / creating log events from code.

I would recommend to read this:

https://github.com/NLog/NLog/wiki/Configuration-file#rules

The same applies for configuration / creating log events from code.

Hi, would you be so kind as to be a little bit more specific please? How can I, for example, register targets programmatically? I assume that what I have to do is to create targets dynamically? Could you provide any example?. Thanks in advance.

Your question is too broad. I would recommend to read the tutorials, all those topics are described there.

See

https://github.com/NLog/NLog/wiki/Configuration-file and
https://github.com/NLog/NLog/wiki/Configure-from-code

If you have a more specific question, feel free to open a new issue and fill in the template

Your question is too broad. I would recommend to read the tutorials, all those topics are described there.

See

https://github.com/NLog/NLog/wiki/Configuration-file and
https://github.com/NLog/NLog/wiki/Configure-from-code

If you have a more specific question, feel free to open a new issue and fill in the template

Hi,

thanks for reply I have read your link but still I can not get it working. Let me show my idea/code ... probably I am wrong in some concepts:

1.- My NLog.config does not define any rule/target, I need to do it programmatically since I don麓t know how many "Instruments" the user will create.

       <extensions>
          <add assembly="NlogViewer" />
        </extensions\>
        <targets>  
        </target>
        <rules>    
        </rules>     

2.- The main application creates at start up one "General" target and one "General" rule associated to this general defined target (Notice that I do not want to target to a file, I just want to target to the NLogViewer panels):

```c#
private Logger log;
private NLog.Config.LoggingConfiguration loggingConfig = new NLog.Config.LoggingConfiguration();

    public MainWindow()
    {      
        // Target where to log "General" "NlogViewerTarget"
        var logNviewerTarget = new NlogViewerTarget();
        logNviewerTarget.Name = "logCtrl";

        // Rule for mapping loggers to target                        
        loggingConfig.AddTarget(logNviewerTarget);
        loggingConfig.AddRule(LogLevel.Info, LogLevel.Fatal, logNviewerTarget);

        // Apply config           
        NLog.LogManager.Configuration = loggingConfig;

        //Get logger
        log = NLog.LogManager.GetLogger("logCtrl");

3.- Additionally, I need to create dynamically "N" others targets each time that I create a new "Instrument" that I insert into a controller. I pass as argument the "loggingConfig" and "log" parameters. 

```c#
          public NewInstrument(LoggingConfiguration loggingConfiguration, Logger log)
          {          
               // Creates a new isolate target with another name, for isolate/particular logs
               var logNviewerTarget = new NlogViewerTarget();
               logNviewerTarget.Name = "logCtrlInstrument";

               //Add new target to the current target list
               loggingConfiguration.AddTarget(logNviewerTarget);`

              // Add a new rule to existing rules
              loggingConfiguration.AddRule(LogLevel.Info, LogLevel.Fatal, logNviewerTarget);

              // Apply config           
              NLog.LogManager.Configuration = loggingConfiguration;
````

4.- This is how I much the target with the panel:

GENERAL
```xml
<nlog:NlogViewer x:Name="logCtrl" MaxRowCount="0" TimeWidth="AUTO" LoggerNameWidth="0" LevelWidth="auto" ExceptionWidth="auto" MessageWidth="450" />

PARTICULAR INSTRUMENT

<nlog:NlogViewer x:Name="logCtrlInstrument" MaxRowCount="0" TimeWidth="AUTO" LoggerNameWidth="0" LevelWidth="auto" ExceptionWidth="auto" MessageWidth="auto" />

5.- If a try to log something in one instrument ... it is showed in both log panel, not only in the reference target:

c# log.Info("Test", logNviewerTarget);

I am not able to get it woks. I am not able about that each new instrument logs their owns traces in his own panel, does it this mechanics the correct way to perform this action?

Thanks in advance.

There are many ways to route logs but this is the most simple way:

```c#
NLog.Config.LoggingConfiguration loggingConfig = new NLog.Config.LoggingConfiguration();

// target 1 with rule
{
var logNviewerTarget = new NlogViewerTarget();
logNviewerTarget.Name = "target1"; // make sure this has an unique name

// Rule for mapping loggers to target                        
loggingConfig.AddTarget(logNviewerTarget);
loggingConfig.AddRule(LogLevel.Info, LogLevel.Fatal, logNviewerTarget, loggerNamePattern: "logger1"); // filter on logger name

}

// target 2 with rule
{
var logNviewerTarget = new NlogViewerTarget();
logNviewerTarget.Name = "target2"; // make sure this has an unique name

// Rule for mapping loggers to target                        
loggingConfig.AddTarget(logNviewerTarget);
loggingConfig.AddRule(LogLevel.Info, LogLevel.Fatal, logNviewerTarget, loggerNamePattern: "logger2"); // filter on logger name

}

// Apply config
NLog.LogManager.Configuration = loggingConfig;

LogManager.GetLogger("logger1").Info("I'm going to target1");
LogManager.GetLogger("logger2").Info("I'm going to target2");
```

PS: Please note that changing the NLog config isn't thread-safe

I don't know if your used (NLogViewer) library supports multi targeting, but mine does. Here is the link to the readme how you can configure it https://github.com/dojo90/NLogViewer#multi-targeting

@304NotModified PS: Please note that changing the NLog config isn't thread-safe

Pretty sure new NLog-config can be assigned without any issues with thread-safety. But one might notice the logging that occurs while closing one NLog-config and changing to new NLog-config will be lost.

But instead of assigning a new NLog-config, then one can also consider calling LogManager.Configuration.AddRule(..) followed by calling LogManager.ReconfigExistingLoggers().

But yes the issue here seems that @FMoralesLdG is missing proper configuration of Logging Rules routing: https://github.com/NLog/NLog/wiki/Filtering-log-messages#routing (Example shown by @304NotModified will work).

Was this page helpful?
0 / 5 - 0 ratings