Как создать разные файлы журнала для разных пакетов, используя один и тот же log4j logger?
Я пытаюсь настроить отдельные файлы журнала для разных пакетов. Я использую класс Wrapper для log4j
регистратор. Каждый класс в моем приложении вызывает один и тот же класс-обертку. Мой класс обертки:
public class MyLogger
{
private static Logger logger = Logger.getLogger(MyLogger.class.getName());
....
....
}
Это называется так:
MyLogger.write(, , );
Есть ли способ настроить log4j так, чтобы он выводил логирование разных пакетов в разные файлы?
Спасибо!
Редактировать:
Вот мой log4j.properties
файл:
log4j.rootLogger=DEBUG, infoout, aar
log4j.logger.com.businessservice.datapopulation=DEBUG, aar
log4j.additivity.com.businessservice.datapopulation=false
log4j.appender.infoout = org.apache.log4j.RollingFileAppender
log4j.appender.infoout.file=/app/aar_frontend.log
log4j.appender.infoout.append=true
log4j.appender.infoout.Threshold=DEBUG
log4j.appender.infoout.MaxFileSize=2MB
log4j.appender.infoout.MaxBackupIndex=10
log4j.appender.infoout.layout = org.apache.log4j.PatternLayout
log4j.appender.infoout.layout.ConversionPattern = %m%n
log4j.appender.aar = org.apache.log4j.RollingFileAppender
log4j.appender.aar.file=/app/aar/aar_backend.log
log4j.appender.aar.append=true
log4j.appender.aar.Threshold=DEBUG
log4j.appender.aar.MaxFileSize=2MB
log4j.appender.aar.MaxBackupIndex=10
log4j.appender.aar.layout = org.apache.log4j.PatternLayout
log4j.appender.aar.layout.ConversionPattern = %m%n
4 ответа
Если вы создаете статический Logger в классе MyLogger, то у вас есть один экземпляр Logger с именем, установленным в MyLogger. Когда вы вызываете этот регистратор из других пакетов, Log4j не может определить источник этих вызовов, поскольку все они используют один и тот же регистратор.
Лучший способ справиться с этим - определить отдельный Logger внутри каждого класса, но если вы хотите использовать один класс в качестве точки контакта с Log4j, то вы можете сделать это:
package com.daniel.logger;
import org.apache.log4j.Logger;
import com.daniel.package1.ClassA;
import com.daniel.package2.ClassB;
public class MyLogger{
public static void write(String message, Class<?> clazz){
Logger.getLogger(clazz).info(message);
}
public static void main(String[] args){
ClassA.log();
ClassB.log();
}
}
Тогда один из классов, использующий его, может выглядеть так:
package com.daniel.package1;
import com.daniel.logger.MyLogger;
public class ClassA {
public static void log(){
MyLogger.write("ClassA",ClassA.class);
}
}
И log4j.properties
файл будет выглядеть так:
log4j.appender.package1=org.apache.log4j.FileAppender
log4j.appender.package1.File=package1.log
log4j.appender.package1.layout=org.apache.log4j.PatternLayout
log4j.appender.package2=org.apache.log4j.FileAppender
log4j.appender.package2.File=package2.log
log4j.appender.package2.layout=org.apache.log4j.PatternLayout
log4j.logger.com.daniel.package1=DEBUG,package1
log4j.logger.com.daniel.package2=DEBUG,package2
Если вы не хотите передавать класс из ClassA, вы можете использовать неприятный трюк с отражением, который получает имя вызывающего класса, но я бы не рекомендовал это из-за снижения производительности:
public class MyLogger
{
public static void write(String message){
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
Logger.getLogger(stackTraceElements[2].getClassName()).info(message);
}
public static void main(String[] args){
ClassA.log();
ClassB.log();
}
}
Вы можете сделать это следующим образом (com.myco.a и com.myco.b - ваши два разных пакета):
log4j.logger.com.myco.a=DEBUG, infoout
log4j.logger.com.myco.b=DEBUG, aar
Приветствия.
Создание 2-х приложений и 2-х регистраторов будет делать то, что вы хотите.
Прочитайте требуемое расположение файла из файла свойств или около того для каждого пакета. Затем вы можете использовать приведенный ниже метод для обновления местоположения файла log4j, установленного в проп-файле log4j:
private void updateLog4jConfiguration(String logFile) {
java.util.Properties properties = new Properties();
try {
InputStream configStream = getClass().getResourceAsStream( "/log4j.properties");
properties.load(configStream);
configStream.close();
}
catch (IOException e) {
System.out.println("Error: Cannot laod configuration file ");
}
properties.setProperty("log4j.appender.FILE.file", logFile);
org.apache.log4j.LogManager.resetConfiguration();
org.apache.log4j.PropertyConfigurator.configure(properties);
}