Skip to content

Make PatternLayout's tokens more flexible #1340

@Mumeii

Description

@Mumeii

Hi

I've recently tried to code something looking much like the following :

    const log4js = require('log4js');
    const httpContext = require("express-http-context");

    const tokenToHttpContextHandler = {
        get( obj, prop ) {
             return httpContext.get( prop )
        }
    }

    const tokenToHttpContexProxy = new Proxy( {}, tokenToHttpContextHandler );

    const log4jsConf = {
        appenders: {
            console: {
                type: 'console',
                layout: {
                    type: "pattern",
                    pattern: "[%d] [%p] %c %m%x{correlation-id}%n",
                    tokens: tokenToHttpContexProxy
                }
            }
        },
        categories: {
            default: {
                appenders: [ 'console' ],
                level: process.env.LOG_LEVEL || DEFAULT_LOG_LEVEL
            }
        }
    }

    log4js.configure( log4jsConf );
    
    const logger = log4js.getLogger( 'default' );

    logger.log( "without a correlation-id placed in httpContext" )
    // log something like : 
    // [2022-11-10T22:41:14.108] [INFO] default without a correlation-id placed in httpContext

    httpContext.set( "correlation-id", "aDummyCorrelationId" )

    logger.log( "WITH a correlation-id placed in httpContext :" )
    // expected to log something like : 
    // [2022-11-10T22:41:14.108] [INFO] default WITH a correlation-id placed in httpContext : aDummyCorrelationId
    // but it's not ... right now (log4js v6.7.0) it's logging : 
    // [2022-11-10T22:41:14.108] [INFO] default WITH a correlation-id placed in httpContext :

It's not working as expected because the lib used to clone the log4jsConf in log4js.configure( log4jsConf ); fails to clone the proxy used as a token provider ...

Here are the solutions I can imagine in order to overcome this trouble :

  • stop cloning the configuration object (or make it optional at least)
  • use another clone technique that support cloning proxies
  • enable users to pass a two parameters function in the tokens fields, such as :
    const log4jsConf = {
        appenders: {
            console: {
                type: 'console',
                layout: {
                    type: "pattern",
                    pattern: "[%d] [%p] %c %m%x{correlation-id}%n",
                    tokens: function( searchedToken, logEvent ) {
                        return httpContext.get( searchedToken )
                    }
                }
            }
        },
        categories: {
            default: {
                appenders: [ 'console' ],
                level: process.env.LOG_LEVEL || DEFAULT_LOG_LEVEL
            }
        }
    }

Any of the three previously mentioned technics would enable to have a much more flexible token based system, where we're not forced anymore to restrict token usage to a finit list of cases, casted in code stone.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions