Как создать разные файлы журналов для разных пакетов, используя тот же log4j logger?
Я пытаюсь настроить отдельные файлы журналов для разных пакетов. Я использую класс Wrapper для регистратора log4j
. Каждый класс в моем приложении вызывает тот же класс-оболочку. Мой класс оболочки:
public class MyLogger
{
private static Logger logger = Logger.getLogger(MyLogger.class.getName());
....
....
}
Он вызывается так:
MyLogger.write(, , );
Есть ли способ настроить log4j так, чтобы он выводил протоколирование различных пакетов в разные файлы?
Спасибо!
Edit:
Вот мой файл 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
Ответы
Ответ 1
Если вы создаете статический логгер в классе MyLogger, у вас есть один экземпляр Logger с именем, установленным в MyLogger. Когда вы вызываете этот регистратор из других пакетов, Log4j не может определить происхождение этих вызовов, поскольку все они используют один и тот же Logger.
Лучший способ справиться с этим - это определить отдельный 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
Если вы не хотите передавать Class из 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();
}
}
Ответ 2
Вы можете сделать это так (com.myco.a и com.myco.b - ваши 2 разных пакета):
log4j.logger.com.myco.a=DEBUG, infoout
log4j.logger.com.myco.b=DEBUG, aar
Приветствия.
Ответ 3
Создание 2 приложений и 2 регистраторов сделает то, что вы хотите.
Ответ 4
Прочитайте требуемое местоположение пользовательского файла из файла свойств или так для каждого пакета. Затем вы можете использовать приведенный ниже метод для обновления местоположения файла 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);
}