3

I have a program, where I would like to be able to separate each single log-message into its own log file.

So if the class generates 10 ERROR logs and 10 DEBUG logs, within a single program execution, then that should create 20 log files , and they're names can ideally be something like :

logoutput1
logoutput2
logoutput3
..etc

And each log file just has a single line .

I'm working on an project where I'd like to implement some autonomic ability - the idea is that we can have a third , externally running program which can read in those log files(and then react based on them)

Is this possible with Log4j ? how can this be done ? thanks !

Remko Popma
  • 35,130
  • 11
  • 92
  • 114
Caffeinated
  • 11,982
  • 40
  • 122
  • 216
  • 2
    There is no way of creating new log file on log basis but you can do it by file size basis. Why do you need per log files? – Eranda Jun 01 '15 at 02:13
  • 1
    May be you should use the RollingFileAppender and set the MaxFileSize property to a small value and MaxBackupIndex to a very high value !! . But why do you need this? – Nipun Talukdar Jun 01 '15 at 02:18
  • You may wish to read [What is the XY problem?](http://meta.stackexchange.com/q/66377) to clarify the purpose here…. – Nathan Tuggy Jun 01 '15 at 02:20
  • @NipunTalukdar - I aiming for some kind of "autonomic" ability, whereby we can keep track of a program dynamically – Caffeinated Jun 01 '15 at 02:28
  • @Eranda - I'm working on an project where I'd like to implement some autonomic ability - the idea is that we can have a third , externally running program which can read in those log files(and then react based on them). So imagine that we might say "If the log says 'FATAL' then email user1234" , or something similar – Caffeinated Jun 01 '15 at 02:30
  • @NipunTalukdar - Please see note above to Eranda – Caffeinated Jun 01 '15 at 02:31
  • @NipunTalukdar - Ah, Ok! I see what you mean with RollingFileAppender and MaxFileSize - thanks !!!! – Caffeinated Jun 01 '15 at 02:32
  • 1
    You can change your log4j properties in your program. change the file name each time before invoking the logger . http://www.avajava.com/tutorials/lessons/how-do-i-change-my-log4j-settings-while-my-web-application-is-running.html – Jishnu Prathap Jul 01 '15 at 12:29
  • @JishnuPrathap- May you elaborate little more please ? not sure what you mean – Caffeinated Jul 03 '15 at 20:44

2 Answers2

4

Yes, you can use the RoutingAppender. See this question for details: Log4j2: Dynamic creation of log files for multiple logs

Community
  • 1
  • 1
Remko Popma
  • 35,130
  • 11
  • 92
  • 114
4

Write your own Log File Appender and create a new file every time when it attempts to write some log. The following piece of code might help you.

public class SingleLogMsgFileAppender extends FileAppender {

    private String file = null;

    private static long fileNo;

    public SingleLogMsgFileAppender() {
        super();
        fileNo = 1;
    }

    @Override
    protected void subAppend(LoggingEvent event) {
        createNewFile(true);
        synchronized (this) {
            super.subAppend(event);
        }
    }

    @Override
    public void setFile(String file) {
        this.file = file;
        createNewFile(false);
    }

    public void createNewFile(boolean incrementFileNo) {
        try {
            String fileName = file + "testlogfile." + fileNo + ".log";
            super.setFile(fileName);
            super.activateOptions();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (incrementFileNo) {
            fileNo++;
        }
    }

}

and here is the log4j configuration file

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

    <appender name="CustomAppender" class="loga.randd.threads.log4j.SingleLogMsgFileAppender">
        <param name="File" value="log/" />
        <param name="Append" value="true" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{MM_dd_yyyy HH_mm_ss}%m%n" />
        </layout>
    </appender>

    <root>
        <priority value="debug" />
        <appender-ref ref="CustomAppender" />
    </root>

</log4j:configuration>
Loganathan Mohanraj
  • 1,736
  • 1
  • 13
  • 22
  • So can you show me (by comments) where in your code, it handles the situation of making a new log file for every log message ? i'm not sure I see it – Caffeinated Jul 03 '15 at 20:46
  • is this log4j2 ... or log4j-1.2 ? – Caffeinated Jul 05 '15 at 22:34
  • 1
    createNewFile(..) is the method where the new file is created. the subAppend(..) method will be invoked every time when you attempt to write some logs. I have overridden subAppend() in my appender and invoked createNewFile() from it. – Loganathan Mohanraj Jul 06 '15 at 14:42