I have created an application using log4j for storing all the level based logs in a single file, but in the current case the single file will hold all the level logs, such as ALL, INFO, ERROR, FATAL, WARN, DEBUG etc... since in my application i am having an option say a select box upon which when i select ERROR, then it should show only error logs, if i select INFO then it should only INFO logs.
I am parsing the logs file to get the appropriate logs based on a particular level, but in this case say if the log file is very big then it will take more time.
One solution which i have thought for this is to maintain separate log files for each levels, so that we can avoid parsings
Like to know everyone's thought on this. Still if this is fine how can we redirect level based logs to separate log file like ERROR logs to appError.log, INFO logs to appInfo.log, and a common log file to hold all the level based logs.
My log4j.properties is as given below
# LOG4J configuration
log4j.rootLogger=DEBUG, Appender1, Appender2
log4j.appender.Appender1=org.apache.log4j.ConsoleAppender
log4j.appender.Appender1.layout=org.apache.log4j.PatternLayout
log4j.appender.Appender1.layout.ConversionPattern=%d [%t] %-7p %10c{1} - %m%n
log4j.appender.Appender2=org.apache.log4j.FileAppender
log4j.appender.Appender2.File=${appRootPath}/WEB-INF/logs/LogDemos.log
log4j.appender.Appender2.layout=org.apache.log4j.PatternLayout
log4j.appender.Appender2.layout.ConversionPattern=%d [%t] %-7p %10c{1} - %m%n
The parsing method is like as shown below
Scanner scanner = new Scanner(new File(ctx.getRealPath("/")+"/WEB-INF/logs/LogDemos.log"));
while(scanner.hasNext())
{
String level = request.getParameter("level");
String logs = scanner.nextLine();
String regex = "(\\d{4}-\\d{2}-\\d{2}) (\\d{2}:\\d{2}:\\d{2},\\d{3}) \\[(.*)\\] ([^ ]*) +([^ ]*) - (.*)$";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(logs);
if (m.matches() && m.groupCount() == 6) {
String date = m.group(1);
String time = m.group(2);
String threadId = m.group(3);
String priority = m.group(4);
String category = m.group(5);
String message = m.group(6);
if(priority.trim().equalsIgnoreCase(level.trim()))
{
logsList.add(logs);
System.out.println("date: " + date);
System.out.println("time: " + time);
System.out.println("threadId: " + threadId);
System.out.println("priority: " + priority);
System.out.println("category: " + category);
System.out.println("message: " + message);
}
else
{
logsList.add(logs);
}
}
}
session.setAttribute("logs", logsList);
scanner.close();
If you use
org.apache.log4j.varia.LevelRangeFilter
, you can do as follows (forINFO
andERROR
):The default assumption that is wired in to Log4J is that whenever you care about messages at a certain level (e.g. INFO) then you also care about more important messages too (e.g. ERROR). You can set levels on loggers and thresholds on appenders to filter out messages below a certain level of importance but if you want to send (say) INFO messages to a particular appender but not also WARN, ERROR and FATAL, then the only way to achieve that is by applying a filter.
The properties configuration mechanism doesn't support filters, so you will have to switch to the
log4j.xml
configuration style. The following configuration example is taken from the Log4J wiki: