Search code examples
perllog4perl

How can I get %x in Log4perl to not show "[undef]"?


When I haven't pushed anything to the Log::Log4perl::NDC stack, %x returns [undef]. I would like it to return an empty string when the stack is empty.

For example, take this code:

use strict;
use Log::Log4perl qw(:easy);
Log::Log4perl->easy_init({ level => $INFO, layout => "%x %m%n" });
Log::Log4perl->get_logger()->info("first message");
Log::Log4perl::NDC->push("prefix");
Log::Log4perl->get_logger()->info("second message");

This prints:

[undef] first message
prefix second message

But I want it to print:

first message
prefix second message

How can I do this?


Solution

  • %x is explicitly documented as returning [undef] if nothing is on the NDC stack. So with standard %x you're out of luck. However, by using a self-defined placeholder and looking into the NDC internals you can format the output like you like, e.g.:

    Log::Log4perl::Layout::PatternLayout::add_global_cspec('U', sub {
        @Log::Log4perl::NDC::NDC_STACK ? join(" ", @Log::Log4perl::NDC::NDC_STACK) . " " : ''
    });
    

    Then simply use

    Log::Log4perl->easy_init({ level => $INFO, layout => "%U%m%n" });
    

    (note the missing space after %U here).

    It would be better if the current NDC_STACK was available by function, or if the existing variables was documented. Maybe ask the log4perl developers if they could do any of both?