0

I try to add some custom fields to NLog using extensibility.

Part of my nlog.config file looks like that : (simplified for exhibit)

<nlog>
    <extensions>
        <add assembly="Logzio.DotNet.NLog"/>
    </extensions>

    <variable name="currentUser" value="test" />

    <targets async="true">
        <target name="logzio" type="Logzio" token="myToken">
          <contextproperty name="currentUser" layout="${currentUser}" />
        </target>
    </targets>

    <rules>
        <logger name="*" minlevel="Debug" writeTo="logzio" />
    </rules>
</nlog>

In every controller, I have something like that (I'm using ASP.NET MVC5)

private static Logger logger = LogManager.GetCurrentClassLogger();

Then I send my logs to logzio using

logger.Fatal("Something bad happens");

Right now, currentUser always have the value test, which is logical.

However, despite of the documentation, I don't understand how to dynamically change currentUser value by the ID of my current logged user.

Should I create a sort of factory ? (if yes, how ? I'm not at ease with factories)
Should I change my logger variable ? If so, how ?

A piece of code would be extremly welcome.

Thank you for pointing my out where I'm wrong

EDIT

After @Rolf's answer, I've created this custom layout renderer

[LayoutRenderer("custom-layout")]
public class CustomLayoutRenderer : LayoutRenderer
{
    public string IdUser { get; set; }


    protected override void Append(StringBuilder builder, LogEventInfo logEvent)
    {
        logEvent.Properties.Add("currentUser", "HowToPassCustomDataHere?");
        builder.Append("test from custom-layout");
    }
}

and I changed the nlog.config accordingly, adding

layout="${message} ${custom-layout}"

to my <target>

However, I still don't understand how to pass custom value to currentUser. In logz.io, I have "HowToPassCustomDataHere?" as a value of currentUser.

(BTW, ${aspnet-user-identity} is great and works fine ; however I'd like to understand how to pass a custom value to my layout renderer. In my case, something like ${aspnet-user-id})

user2687153
  • 427
  • 5
  • 24
  • You should not modify the LogEventInfo.Properties in the LayoutRenderer. The LayoutRenderer should only write the wanted context-info to the StringBuilder. – Rolf Kristensen Dec 15 '18 at 09:03
  • The idea is that you initialize the LayoutRenderer to be able to capture the username from somewhere. For ASP.NET then one can use global HttpContext. Which all of these are doing: https://github.com/NLog/NLog.Web/tree/master/NLog.Web.AspNetCore/LayoutRenderers – Rolf Kristensen Dec 15 '18 at 09:08

1 Answers1

2

You can try one of these NLog layoutrenderers to acquire the current username:

  • ${aspnet-user-identity} Wiki
  • ${windows-identity} Wiki

You can also create your own custom NLog LayoutRenderer: https://github.com/NLog/NLog/wiki/How-to-write-a-custom-layout-renderer

Example of how to provide it as currentUser:

    <target name="logzio" type="Logzio" token="myToken">
      <contextproperty name="currentUser" layout="${aspnet-user-identity}" />
    </target>
Rolf Kristensen
  • 17,785
  • 1
  • 51
  • 70
  • +1 for `${aspnet-user-identity}`, that's great and (almost) what I want. However, I still have an issue with LayoutRenderer, could you please take a look to my edit ? – user2687153 Dec 14 '18 at 22:51
  • Think you need to study NLog Layout Renderers a little more. I don't know what you intend to return in `${aspnet-user-id}` Maybe look at the source-code for the existing layout-renderers to get inspiration for your own. More here https://github.com/NLog/NLog/wiki/AspNetRequest-layout-renderer – Rolf Kristensen Dec 14 '18 at 23:53
  • Maybe create new question for how to customize the output from `${aspnet-user-identity}` to be just like you want. – Rolf Kristensen Dec 15 '18 at 09:13
  • @user2687153 Have now update the answer with example of how to pass the output from `${aspnet-user-identity}` as `currentUser`-property. – Rolf Kristensen Dec 15 '18 at 09:15