You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-user@logging.apache.org by "Kamatnurkar, Praveen" <pr...@siemens.com> on 2020/04/28 13:08:56 UTC

Creating log file per transfer

Hi
We have an application that sends packages from one s/w to another. Each data package has a unique id.

We have following requirements

  1.  For each package transfer different log files should be created.
  2.  The log file name  should be appended by unique id
  3.  All the logs that are generated in the transfer of each package should be written in that package specific log file.

We are open to customize the logger code-fully. We tried some tricks by creating own appenders, LoggerConfig etc but it's not giving desired output.

Following snippet gives an basic idea what we tried but not successful. All the logs are going in a single file.

/*
     * This method gets the logger for a given exchange. If the logger file already exists then it will just get it otherwise it will
     * create a new logger for that exchange, add the appender for that, and return it.
     */
    public static Logger getExchangeLogger( Class CLASS_NAME )
    {
        try
        {

            if ( !enableExchangeLevelLogging )
            {
                return LogManager.getLogger( CLASS_NAME );
            }

            if ( ThreadContext.getParameterMap() != null )
            {
                String uniqueID = (String) ThreadContext.getParameterMap().get( CommonConstant.EXCHANGE_ID_FOR_LOGGER );

                if ( uniqueID != null && !uniqueID.isEmpty() )
                {
                    Logger exchangeLogger = null;
                    String logDirName = System.getProperty( "user.dir" ) + File.separator + "log";
                    String fileNameWithoutExt = "application_" + uniqueID;
                    String fileName = fileNameWithoutExt + ".log";
                    String fullpath = logDirName + File.separator + fileName;
                    File logFilePath = new File( fullpath );

                    if ( !logFilePath.exists() )
                    {
                        File logFileLoc = new File( logDirName );
                        if ( !logFileLoc.exists() )
                        {
                            logFileLoc.mkdir();
                        }
                    }

                    exchangeLogger = getConfigExchangeLogger( CLASS_NAME, fullpath, fileNameWithoutExt );
                    return exchangeLogger;

                }
                else
                {
                    return LogManager.getLogger( CLASS_NAME );
                }
            }
            else
            {
                return LogManager.getLogger( CLASS_NAME );
            }
        }
        catch ( Exception e )
        {
            log.info( "error occurred while getting exchange logger: " + e.getMessage() );
        }
        return LogManager.getLogger( CLASS_NAME );
    }

    /**
     * Get the logger for specified class.
     * @param cls
     * @param fullpath
     * @param fileName
     * @return
     */
    private static Logger getConfigExchangeLogger( Class cls, String fullpath, String fileName )
    {
        String className = cls.getName();
        final Class<?> clazz = StackLocatorUtil.getCallerClass( cls );
        LoggerContext context = null;
        if ( clazz != null )
        {
            context = (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext( clazz.getClassLoader(), false );
        }
        else
        {
            context = (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext( false );
        }

        Configuration conf = context.getConfiguration();

        Appender appender = conf.getAppender( EXCHANGE_LOGGER_APPENDER_NAME + fileName );

        if ( appender == null )
        {
            appender = getFileAppender( fullpath, fileName, conf );
            conf.addAppender( appender );
        }

        LoggerConfig loggerConfig = conf.getLoggerConfig( className );
        if ( loggerConfig == null )
        {
            System.out.println( "Creating loginConfig for class " + className );
            updateLoggers( className, conf, appender, context );
        }
        else
        {
            // if the appender is different then update the loggers with new appender
            if ( !loggerConfig.getAppenders().containsValue( appender ) )
            {
                // System.out.println( "Appenders are different for classname " + className + " so updating loggers " + fileName );
                updateLoggers( className, conf, appender, context );
            }
            if ( !loggerConfig.getName().equals( className ) )
            {
                updateLoggers( className, conf, appender, context );
            }
        }

        Logger log = LogManager.getLogger( cls );

        return log;
    }

    /**
     * Creates anew logger configuration and set this to logger's appender and appender reference.
     * @param classname
     * @param conf
     * @param appender
     * @param context TODO
     */
    private static void updateLoggers( String classname, Configuration conf, Appender appender, LoggerContext context )
    {
        Logger exchLogger = LogManager.getLogger( EventExchangeLogger.class );
        Level exchangeLogLevel = exchLogger.getLevel();
        AppenderRef ref = AppenderRef.createAppenderRef( "File", exchangeLogLevel, null );
        AppenderRef[] refs = new AppenderRef[] {ref};
        LoggerConfig loggerConfig = LoggerConfig.createLogger( false, exchangeLogLevel, exchLogger.getName(), "true", refs, null, conf,
                null );
        loggerConfig.addAppender( appender, exchangeLogLevel, null );

        conf.addLogger( classname, loggerConfig );

        context.updateLoggers();

    }

    /**
     * Get the Rolling file appender specific to the exchange logger.
     * @param fullpath
     * @param fileName
     * @param conf
     * @return
     */
    private static RollingFileAppender getFileAppender( String fullpath, String fileName, Configuration conf )
    {
        PatternLayout.Builder layoutBuilder = PatternLayout.newBuilder();
        layoutBuilder.withConfiguration( conf );
        layoutBuilder.withPattern( "%d{ISO8601} | %-5p | %c{1}:%L %m%ex%n" );

        RollingFileAppender.Builder rollingFileAppenderBuilder = RollingFileAppender.newBuilder();
        rollingFileAppenderBuilder.setLayout( layoutBuilder.build() );
        rollingFileAppenderBuilder.withFileName( fullpath );
        rollingFileAppenderBuilder.withFilePattern( fileName + "-%i.log" );
        rollingFileAppenderBuilder.setName( EXCHANGE_LOGGER_APPENDER_NAME + fileName );
        rollingFileAppenderBuilder.setConfiguration( conf );
        rollingFileAppenderBuilder.withImmediateFlush( true );
        rollingFileAppenderBuilder.withAppend( true );

        SizeBasedTriggeringPolicy policy = SizeBasedTriggeringPolicy.createPolicy( "10MB" );
        rollingFileAppenderBuilder.withPolicy( policy );

        RollingFileAppender rollAppender = rollingFileAppenderBuilder.build();

        DefaultRolloverStrategy.Builder builder = DefaultRolloverStrategy.newBuilder();
        builder.withMax( "5" );
        builder.withConfig( conf );

        DefaultRolloverStrategy strategy = builder.build();

        rollAppender.getManager().setRolloverStrategy( strategy );

        rollAppender.start();
        return rollAppender;
    }



Any pointer how to achieve this requirement?

Regards
Praveen


Re: Creating log file per transfer

Posted by Ralph Goers <ra...@dslextreme.com>.
Please see https://stackoverflow.com/questions/61270801/slf4j-log4j-how-to-use-a-new-output-file-for-each-logger-where-the-file-name-is/61276705#61276705 <https://stackoverflow.com/questions/61270801/slf4j-log4j-how-to-use-a-new-output-file-for-each-logger-where-the-file-name-is/61276705#61276705> and see if the solution provided there works for you.

Ralph

> On Apr 28, 2020, at 6:08 AM, Kamatnurkar, Praveen <pr...@siemens.com> wrote:
> 
> Hi
> We have an application that sends packages from one s/w to another. Each data package has a unique id.
> 
> We have following requirements
> 
>  1.  For each package transfer different log files should be created.
>  2.  The log file name  should be appended by unique id
>  3.  All the logs that are generated in the transfer of each package should be written in that package specific log file.
> 
> We are open to customize the logger code-fully. We tried some tricks by creating own appenders, LoggerConfig etc but it's not giving desired output.
> 
> Following snippet gives an basic idea what we tried but not successful. All the logs are going in a single file.
> 
> /*
>     * This method gets the logger for a given exchange. If the logger file already exists then it will just get it otherwise it will
>     * create a new logger for that exchange, add the appender for that, and return it.
>     */
>    public static Logger getExchangeLogger( Class CLASS_NAME )
>    {
>        try
>        {
> 
>            if ( !enableExchangeLevelLogging )
>            {
>                return LogManager.getLogger( CLASS_NAME );
>            }
> 
>            if ( ThreadContext.getParameterMap() != null )
>            {
>                String uniqueID = (String) ThreadContext.getParameterMap().get( CommonConstant.EXCHANGE_ID_FOR_LOGGER );
> 
>                if ( uniqueID != null && !uniqueID.isEmpty() )
>                {
>                    Logger exchangeLogger = null;
>                    String logDirName = System.getProperty( "user.dir" ) + File.separator + "log";
>                    String fileNameWithoutExt = "application_" + uniqueID;
>                    String fileName = fileNameWithoutExt + ".log";
>                    String fullpath = logDirName + File.separator + fileName;
>                    File logFilePath = new File( fullpath );
> 
>                    if ( !logFilePath.exists() )
>                    {
>                        File logFileLoc = new File( logDirName );
>                        if ( !logFileLoc.exists() )
>                        {
>                            logFileLoc.mkdir();
>                        }
>                    }
> 
>                    exchangeLogger = getConfigExchangeLogger( CLASS_NAME, fullpath, fileNameWithoutExt );
>                    return exchangeLogger;
> 
>                }
>                else
>                {
>                    return LogManager.getLogger( CLASS_NAME );
>                }
>            }
>            else
>            {
>                return LogManager.getLogger( CLASS_NAME );
>            }
>        }
>        catch ( Exception e )
>        {
>            log.info( "error occurred while getting exchange logger: " + e.getMessage() );
>        }
>        return LogManager.getLogger( CLASS_NAME );
>    }
> 
>    /**
>     * Get the logger for specified class.
>     * @param cls
>     * @param fullpath
>     * @param fileName
>     * @return
>     */
>    private static Logger getConfigExchangeLogger( Class cls, String fullpath, String fileName )
>    {
>        String className = cls.getName();
>        final Class<?> clazz = StackLocatorUtil.getCallerClass( cls );
>        LoggerContext context = null;
>        if ( clazz != null )
>        {
>            context = (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext( clazz.getClassLoader(), false );
>        }
>        else
>        {
>            context = (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext( false );
>        }
> 
>        Configuration conf = context.getConfiguration();
> 
>        Appender appender = conf.getAppender( EXCHANGE_LOGGER_APPENDER_NAME + fileName );
> 
>        if ( appender == null )
>        {
>            appender = getFileAppender( fullpath, fileName, conf );
>            conf.addAppender( appender );
>        }
> 
>        LoggerConfig loggerConfig = conf.getLoggerConfig( className );
>        if ( loggerConfig == null )
>        {
>            System.out.println( "Creating loginConfig for class " + className );
>            updateLoggers( className, conf, appender, context );
>        }
>        else
>        {
>            // if the appender is different then update the loggers with new appender
>            if ( !loggerConfig.getAppenders().containsValue( appender ) )
>            {
>                // System.out.println( "Appenders are different for classname " + className + " so updating loggers " + fileName );
>                updateLoggers( className, conf, appender, context );
>            }
>            if ( !loggerConfig.getName().equals( className ) )
>            {
>                updateLoggers( className, conf, appender, context );
>            }
>        }
> 
>        Logger log = LogManager.getLogger( cls );
> 
>        return log;
>    }
> 
>    /**
>     * Creates anew logger configuration and set this to logger's appender and appender reference.
>     * @param classname
>     * @param conf
>     * @param appender
>     * @param context TODO
>     */
>    private static void updateLoggers( String classname, Configuration conf, Appender appender, LoggerContext context )
>    {
>        Logger exchLogger = LogManager.getLogger( EventExchangeLogger.class );
>        Level exchangeLogLevel = exchLogger.getLevel();
>        AppenderRef ref = AppenderRef.createAppenderRef( "File", exchangeLogLevel, null );
>        AppenderRef[] refs = new AppenderRef[] {ref};
>        LoggerConfig loggerConfig = LoggerConfig.createLogger( false, exchangeLogLevel, exchLogger.getName(), "true", refs, null, conf,
>                null );
>        loggerConfig.addAppender( appender, exchangeLogLevel, null );
> 
>        conf.addLogger( classname, loggerConfig );
> 
>        context.updateLoggers();
> 
>    }
> 
>    /**
>     * Get the Rolling file appender specific to the exchange logger.
>     * @param fullpath
>     * @param fileName
>     * @param conf
>     * @return
>     */
>    private static RollingFileAppender getFileAppender( String fullpath, String fileName, Configuration conf )
>    {
>        PatternLayout.Builder layoutBuilder = PatternLayout.newBuilder();
>        layoutBuilder.withConfiguration( conf );
>        layoutBuilder.withPattern( "%d{ISO8601} | %-5p | %c{1}:%L %m%ex%n" );
> 
>        RollingFileAppender.Builder rollingFileAppenderBuilder = RollingFileAppender.newBuilder();
>        rollingFileAppenderBuilder.setLayout( layoutBuilder.build() );
>        rollingFileAppenderBuilder.withFileName( fullpath );
>        rollingFileAppenderBuilder.withFilePattern( fileName + "-%i.log" );
>        rollingFileAppenderBuilder.setName( EXCHANGE_LOGGER_APPENDER_NAME + fileName );
>        rollingFileAppenderBuilder.setConfiguration( conf );
>        rollingFileAppenderBuilder.withImmediateFlush( true );
>        rollingFileAppenderBuilder.withAppend( true );
> 
>        SizeBasedTriggeringPolicy policy = SizeBasedTriggeringPolicy.createPolicy( "10MB" );
>        rollingFileAppenderBuilder.withPolicy( policy );
> 
>        RollingFileAppender rollAppender = rollingFileAppenderBuilder.build();
> 
>        DefaultRolloverStrategy.Builder builder = DefaultRolloverStrategy.newBuilder();
>        builder.withMax( "5" );
>        builder.withConfig( conf );
> 
>        DefaultRolloverStrategy strategy = builder.build();
> 
>        rollAppender.getManager().setRolloverStrategy( strategy );
> 
>        rollAppender.start();
>        return rollAppender;
>    }
> 
> 
> 
> Any pointer how to achieve this requirement?
> 
> Regards
> Praveen
>