Nlog: Unable to register custom layout renderer

Created on 24 Jul 2019  路  10Comments  路  Source: NLog/NLog

Config Version: 4.6.6
Platform: Windows

I am relatively new to using NLog and I have been trying to figure this out for days and I'm beginning to lose my mind. I am trying to implement a custom layout renderer from : https://stackoverflow.com/questions/5951102/nlog-custom-layoutrenderer-for-scope-indentation

    [LayoutRenderer("IndentationLayout")]

    public sealed class IndentationLayoutRenderer : LayoutRenderer
    {

    // Value to substract from stack count
    private uint _ignore = 12;

    // Value to pad with.
    private string _ipadding = "| ";

    /// <summary>Set the number of (top) stackframes to ignore</summary>
    public uint Ignore
    {
        get { return _ignore; }
        set { _ignore = value; }
    }

    /// <summary>Set the padding value</summary>
    public string IndentationPadding
    {
        get { return _ipadding; }
        set { _ipadding = value; }
    }

    protected override void Append(StringBuilder builder, LogEventInfo ev)
    {
        // Get current stack depth, insert padding chars.
        StackTrace st = new StackTrace();
        long indent = st.FrameCount;
        indent = indent > _ignore ? indent - _ignore : 0;
        for (int i = 0; i < indent; ++i)
        {
            builder.Append(_ipadding);
        }
    }}

I have this code in my project currently in another class and I am registering it like this

LayoutRenderer.Register("IndentationLayout", typeof(IndentationLayoutRenderer));

However, internal logging is not even acknowledging that a custom layout has been added and it goes straight to default. Anyone have any recommendations?

question

All 10 comments

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

Your custom layout renderer looks good.

I think there is an issue in your config, our your config is loaded too soon. (quick fix: LogManager, Configuration.Reload)

Could you please share your config and please check the internal log

PS What is "straight to default. "

public static void SetupLoggingConfiguration()
{

    // Intialize Config Object
    LoggingConfiguration config = new LoggingConfiguration();

    LayoutRenderer.Register("Indentation Layout", typeof(IndentationLayoutRenderer));

    // Initialize File Target
    var fileTarget = new FileTarget("File Target")
    {
        FileName = "${basedir}/logs/logTest.xml",
        DeleteOldFileOnStartup = true, // Deletes old log file every time log is called. Set to true simply for testing purposes
        KeepFileOpen = true, // Keeps file open regardless of logger status. (Increases performance)
        OpenFileCacheTimeout = 30 // Max number of seconds file is kept open. (Increases performance, but the value will scale with the scope of logger implementation)
    };



    // Initialize the AsyncWrapper for the fileTarget
    AsyncTargetWrapper fileWrapper = new AsyncTargetWrapper();
    fileWrapper.WrappedTarget = fileTarget;
    fileWrapper.QueueLimit = 5000;  // Limits number of requests in the request queue (Improves performance)
    fileWrapper.OverflowAction = AsyncTargetWrapperOverflowAction.Block; // Blocks incoming requests until request queue if has space

    // Initialize the AsyncFlushTargetWrapper for the FileWrapper
    AutoFlushTargetWrapper fileFlushWrapper = new AutoFlushTargetWrapper();
    fileFlushWrapper.WrappedTarget = fileWrapper;

    // This condition controls when the log is flushed. Set the LogLevel to be equivalent to the maximum level specified in the targetRule
    fileFlushWrapper.Condition = "level >= LogLevel.Info";

    // Adding the target to the config
    config.AddTarget("file", fileFlushWrapper);



    // Creating the Log Level rules for each target and adding them to the config
    var fileRule = new LoggingRule("*", fileTarget);
    fileRule.EnableLoggingForLevel(exceptionLevel);
    fileRule.EnableLoggingForLevels(minLevel, maxLevel);
    config.LoggingRules.Add(fileRule);


    // Assigning the configuration to the logger
    LogManager.Configuration = config;
}

This is my config method that I am calling first from main to initialize the logging config. By "straight to default" I mean't that it is using the default layout I would assume since the custom layout isn't being used and no other layout was registered.

P.S. If you see any other issues with the config setup feel free to let me know. :)

Thanks for sharing. You're registering the IndentationLayout with a space (I even don't know if that works), but more important, you're not using it ;)

proposal:

 LayoutRenderer.Register("IndentationLayout", typeof(IndentationLayoutRenderer)); //no space

and

// Initialize File Target
var fileTarget = new FileTarget("File Target")
{
    FileName = "${basedir}/logs/logTest.xml",
    DeleteOldFileOnStartup = true, // Deletes old log file every time log is called. Set to true simply for testing purposes
    KeepFileOpen = true, // Keeps file open regardless of logger status. (Increases performance)
    OpenFileCacheTimeout = 30, // Max number of seconds file is kept open. (Increases performance, but the value will scale with the scope of logger implementation)
    Layout = "${IndentationLayout}${longdate}|${level:uppercase=true}|${logger}|${message}" //use IndentationLayout

};

THANK YOU. That finally worked and yes that is also my issue. I've been trying to fix this all day at work and this saved me.

馃憤 no problem 馃憤

(PS your stackoverflow issue is a bit difficult (missing details), I would recommend to change it or just remove it.
PS2 "Julian" on stackoverflow is also me ;))

I think I'll just remove it because this thread will be much more informative for those that need help. Thanks again Julian

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Jerefeny picture Jerefeny  路  3Comments

ErcinDedeoglu picture ErcinDedeoglu  路  3Comments

vasumsit picture vasumsit  路  3Comments

JustArchi picture JustArchi  路  3Comments

BobSeu picture BobSeu  路  3Comments