Ответ 1
Проблема решена, я должен был сделать:
<logger name="com.server" additivity="false">
<level value="INFO" />
<appender-ref ref="async" />
</logger>
Я не могу понять, почему log4j добавляется дважды в разных форматах. Кто-нибудь сталкивался с этим раньше?
Вот мой файл log4j.xml:
<log4j:configuration>
<appender name="async" class="org.apache.log4j.AsyncAppender">
<!-- this parameter need to be set to false to avoid application from hanging. -->
<param name="Blocking" value="false" />
<appender-ref ref="myAppender" />
</appender>
<appender name="myAppender" class="org.apache.log4j.ConsoleAppender">
<param name="Threshold" value="INFO" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{ISO8601} [%t] %c %x - %m%n" />
</layout>
</appender>
<logger name="com.server">
<level value="INFO" />
</logger>
<logger name="org.springframework">
<level value="INFO" />
</logger>
<logger name="org.hibernate.LazyInitializationException" additivity="false">
<level value="off" />
<appender-ref ref="async" />
</logger>
<logger name="net.sf.ehcache">
<level value="INFO" />
</logger>
<logger name="com.mchange">
<level value="INFO" />
</logger>
<root>
<priority value="INFO" />
<appender-ref ref="async" />
</root>
</log4j:configuration>
И вот несколько примеров:
INFO 2016-08-26 11:01:38,353 [main] com.server.Server - Server started successfully...
11:01:38,353 INFO : Server started successfully...
EDIT: Когда я изменяю порог приложения myAppender на "ERROR", отображается второе сообщение журнала ( "Начало, начинающееся со времени, а не" INFO "). Есть ли какой-то логгер по умолчанию, который мне нужно отключить? Кажется, что что-то все еще регистрирует сообщения уровня" INFO", хотя указанный appender для сообщений уровня "ERROR". Кроме того, если я прокомментирую весь файл log4j.xml, все еще регистрируется второе сообщение журнала (и все подобное). Как я могу это предотвратить? Спасибо!
Проблема решена, я должен был сделать:
<logger name="com.server" additivity="false">
<level value="INFO" />
<appender-ref ref="async" />
</logger>
Я не знаком с синтаксисом XML log4j (я использую log4j.properties для конфигурации), поэтому вот мои 2 цента, чтобы помочь вам отладить и исправить код.
Сначала попробуйте использовать ниже корневую регистрационную конфигурацию вместо -
<logger name="org.hibernate.LazyInitializationException" additivity="false">
<level value="off" />
<appender-ref ref="myAppender" />
</logger>
..............
...........
<root>
<priority value="INFO" />
<appender-ref ref="myAppender" />
</root>
Если выше не работает, попробуйте положить <param name="Threshold" value="ERROR" />
как в async
, так и myAppender
, и я думаю, что текст Server started successfully
не будет напечатан (я думаю, вы уже пробовали с myAppender
)
Если это помогает, то это означает, что вы пытаетесь ссылаться/наследовать регистратор, не работает или правильно работает, поэтому вы можете подумать в этом направлении и исправить проблему, вам нужно больше узнать о элементе appender-ref
и AsyncAppender
.
Если выше работает или нет, я предполагаю, что вы пытаетесь добиться следующих результатов:
Я бы сделал это в log4j.properties, как показано ниже:
log4j.logger.com.sks.cs50=DEBUG, CS50GlobalFileAppender, stdout
#####CS50 Web log##########
log4j.appender.CS50GlobalFileAppender=org.apache.log4j.RollingFileAppender
log4j.appender.CS50GlobalFileAppender.File=${logDir}cs50.log
log4j.appender.CS50GlobalFileAppender.MaxBackupIndex=50
log4j.appender.CS50GlobalFileAppender.Threshold=DEBUG
log4j.appender.CS50GlobalFileAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.CS50GlobalFileAppender.layout.ConversionPattern=%C %d [%t] [%X{randomNumber}] %-5p - %m%n
log4j.appender.CS50GlobalFileAppender.MaxFileSize=500000KB
# Log format to standard output
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d [%X{randomNumber}] %-5p - %m%n
log4j.logger.org.apache = INFO
log4j.logger.com.sun = INFO
log4j.logger.sun = INFO
log4j.logger.javax.xml.bind = INFO
log4j.logger.org.springframework = INFO
log4j.logger.com.cgi = DEBUG
Итак, я думаю, вы можете сделать что-то, как показано ниже.
<log4j:configuration>
<appender name="async" class="org.apache.log4j.AsyncAppender">
<!-- this parameter need to be set to false to avoid application from hanging. -->
<param name="Blocking" value="false" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{ISO8601} [%t] %c %x - %m%n" />
</layout>
</appender>
<appender name="myAppender" class="org.apache.log4j.ConsoleAppender">
<param name="Threshold" value="INFO" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{ISO8601} [%t] %c %x - %m%n" />
</layout>
</appender>
<logger name="com.server">
<level value="INFO" />
</logger>
<logger name="org.springframework">
<level value="INFO" />
</logger>
<logger name="org.hibernate.LazyInitializationException" additivity="false">
<level value="off" />
<appender-ref ref="async" />
</logger>
<logger name="net.sf.ehcache">
<level value="INFO" />
</logger>
<logger name="com.mchange">
<level value="INFO" />
</logger>
<root>
<priority value="INFO" />
<appender-ref ref="async" />
<appender-ref ref="myAppender" />
</root>
</log4j:configuration>
Обратите внимание на, что выше XML-конфигурации с допущением, что org.apache.log4j.AsyncAppender
печатает в каком-то файле журнала, но если это не так (я полагаю, что это не так), то выше не будет (вы можете использовать выше XML-конфигурацию для достижения файла + консольного ведения журнала, если вы замените AsyncAppender
на org.apache.log4j.RollingFileAppender
), и мне было бы интересно, почему вы просто не можете использовать org.apache.log4j.AsyncAppender
напрямую, потому что он уже печатает на консоли, поэтому можно просто использовать:
<appender name="async" class="org.apache.log4j.AsyncAppender">
<!-- this parameter need to be set to false to avoid application from hanging. -->
<param name="Blocking" value="false" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{ISO8601} [%t] %c %x - %m%n" />
</layout>
</appender>
почему Log4j регистрируется дважды?
Log4j
регистрируется для всех регистраторов в иерархии, если вы не спросите об этом до (путем установки additivity
в false
), так что вы видите вывод из вашего регистратора com.server
и регистратора ROOT
по умолчанию, который всегда существует. решение проблемы выше
Это происходит, потому что вы не определили
additive = "false" на вашем ком.сервере. теперь я исправил его, вы можете попробовать.
<appender name="async" class="org.apache.log4j.AsyncAppender">
<!-- this parameter need to be set to false to avoid application from hanging. -->
<param name="Blocking" value="false" />
<appender-ref ref="myAppender" />
</appender>
<appender name="myAppender" class="org.apache.log4j.ConsoleAppender">
<param name="Threshold" value="INFO" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{ISO8601} [%t] %c %x - %m%n" />
</layout>
</appender>
<logger name="com.server" additivity="false">
<level value="INFO" />
</logger>
<logger name="org.springframework">
<level value="INFO" />
</logger>
<logger name="org.hibernate.LazyInitializationException" additivity="false">
<level value="off" />
<appender-ref ref="async" />
</logger>
<logger name="net.sf.ehcache">
<level value="INFO" />
</logger>
<logger name="com.mchange">
<level value="INFO" />
</logger>
<root>
<priority value="INFO" />
<appender-ref ref="async" />
</root>
Я предполагаю, что где-то в вашем приложении добавляется еще один appender, возможно, вот так:
package de.scrum_master.app;
import java.io.OutputStreamWriter;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
public class Application {
private static Logger log = Logger.getLogger(Application.class);
public static void main(String[] args) throws InterruptedException {
//log.setAdditivity(false);
ConsoleAppender ca = new ConsoleAppender();
ca.setWriter(new OutputStreamWriter(System.out));
ca.setLayout(new PatternLayout("%-5p [%t]: %m%n"));
log.addAppender(ca);
log.info("Hello world");
log.info("Bye world");
Thread.sleep(1000);
}
}
Это в дополнение к файлу log4j.xml или log4j.properties, найденному в пути к классам, вызывает эффект, который вы видите в ваших журналах.
Обновление: Или может быть вызвано даже что-то вроде Logger.getRootLogger().addAppender(ca)
, влияющее на корневой журнал, а не только на конкретный.
Используя ваш конфигурационный файл для меня, вы получите следующий выход журнала:
INFO [main]: Hello world
INFO [main]: Bye world
INFO 2016-09-04 13:48:25,887 [main] de.scrum_master.app.Application - Hello world
INFO 2016-09-04 13:48:25,889 [main] de.scrum_master.app.Application - Bye world
Уже были некоторые ответы, поэтому я просто пошел вперед и создал программу, чтобы доказать, что это действительно работает, если в коде нет какой-либо проблемы. См. мои два простых класса ниже и попытайтесь выяснить разницу между этими и вашими.
import org.apache.log4j.xml.DOMConfigurator;
import com.server.Test;
public class MyListener {
public static void main(String[] args) {
DOMConfigurator.configure("/home/sanjeevd/depot/bas/projects/xxx.1/yyy/src/log4j.xml");
Test test = new Test();
}
}
package com.server;
import org.apache.log4j.Logger;
public class Test {
private static Logger logger = Logger.getLogger(Test.class);
public Test() {
logger.info("PRINTTTTTTTTTTTT");
}
}
Также добавьте эти две строки вверху вашего log4j.xml -
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
Сказав это, я в основном уверен, что есть какой-то другой регистратор, который инициализируется или в вашем приложении более одного lo4j.xml и т.д. Обратите внимание: я ничего не изменил в вашем log4j.xml, кроме добавление заголовков.
Выход ниже (и он печатает только цифры) -
INFO 2016-09-06 10:57:37,506 [main] com.server.Test - PRINTTTTTTTTTTTT
Еще одна вещь, которую вы должны сделать, это установить "системное свойство" для отладки начальной загрузки, чтобы узнать, что происходит на уровне log4j, т.е. поставить
System.setProperty("log4j.debug", "true");
непосредственно перед настройкой log4j. Если вы развертываете его в каком-либо контейнере сервлетов (tomcat и т.д.), Тогда во время запуска передайте параметр -Dlog4j.debug = true.
Выход в моем случае был -
log4j: Trying to find [log4j.xml] using context classloader [email protected]
log4j: Using URL [file:/home/sanjeevd/depot/bas/projects/xxx.1/yyy/bin/log4j.xml] for automatic log4j configuration.
log4j: Preferred configurator class: org.apache.log4j.xml.DOMConfigurator
log4j: System property is :null
log4j: Standard DocumentBuilderFactory search succeded.
log4j: DocumentBuilderFactory is: com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
log4j: debug attribute= "null".
log4j: Ignoring debug attribute.
log4j: reset attribute= "false".
log4j: Threshold ="null".
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [com.server] additivity to [true].
log4j: Level value for com.server is [INFO].
log4j: com.server level set to INFO
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [org.springframework] additivity to [true].
log4j: Level value for org.springframework is [INFO].
log4j: org.springframework level set to INFO
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [org.hibernate.LazyInitializationException] additivity to [false].
log4j: Level value for org.hibernate.LazyInitializationException is [off].
log4j: org.hibernate.LazyInitializationException level set to OFF
log4j: Class name: [org.apache.log4j.AsyncAppender]
log4j: Attaching appender named [myAppender] to appender named [async].
log4j: Class name: [org.apache.log4j.ConsoleAppender]
log4j: Setting property [threshold] to [INFO].
log4j: Setting property [target] to [System.out].
log4j: Parsing layout of class: "org.apache.log4j.PatternLayout"
log4j: Setting property [conversionPattern] to [%-5p %d{ISO8601} [%t] %c %x - %m%n].
log4j: Adding appender named [async] to category [org.hibernate.LazyInitializationException].
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [net.sf.ehcache] additivity to [true].
log4j: Level value for net.sf.ehcache is [INFO].
log4j: net.sf.ehcache level set to INFO
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [com.mchange] additivity to [true].
log4j: Level value for com.mchange is [INFO].
log4j: com.mchange level set to INFO
log4j: Level value for root is [INFO].
log4j: root level set to INFO
log4j: Adding appender named [async] to category [root].
log4j: System property is :null
log4j: Standard DocumentBuilderFactory search succeded.
log4j: DocumentBuilderFactory is: com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
log4j: debug attribute= "null".
log4j: Ignoring debug attribute.
log4j: reset attribute= "false".
log4j: Threshold ="null".
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [com.server] additivity to [true].
log4j: Level value for com.server is [INFO].
log4j: com.server level set to INFO
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [org.springframework] additivity to [true].
log4j: Level value for org.springframework is [INFO].
log4j: org.springframework level set to INFO
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [org.hibernate.LazyInitializationException] additivity to [false].
log4j: Level value for org.hibernate.LazyInitializationException is [off].
log4j: org.hibernate.LazyInitializationException level set to OFF
log4j: Class name: [org.apache.log4j.AsyncAppender]
log4j: Attaching appender named [myAppender] to appender named [async].
log4j: Class name: [org.apache.log4j.ConsoleAppender]
log4j: Setting property [threshold] to [INFO].
log4j: Setting property [target] to [System.out].
log4j: Parsing layout of class: "org.apache.log4j.PatternLayout"
log4j: Setting property [conversionPattern] to [%-5p %d{ISO8601} [%t] %c %x - %m%n].
log4j: Adding appender named [async] to category [org.hibernate.LazyInitializationException].
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [net.sf.ehcache] additivity to [true].
log4j: Level value for net.sf.ehcache is [INFO].
log4j: net.sf.ehcache level set to INFO
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [com.mchange] additivity to [true].
log4j: Level value for com.mchange is [INFO].
log4j: com.mchange level set to INFO
log4j: Level value for root is [INFO].
log4j: root level set to INFO
log4j: Adding appender named [async] to category [root].
Я думаю, что добавление additive = "false" в ваш com.server логгер решит проблему.
<logger name="com.server" additivity="false">
<level value="INFO" />
</logger>
https://logging.apache.org/log4j/2.x/manual/configuration.html#Additivity