Насколько я понимаю, ваша цель состоит в том, чтобы выполнить следующие пункты:
Я намереваюсь записать ОШИБКИ и ФАТАЛЬНЫЕ в файл, следовательно, используя level = ERROR.Я намереваюсь записать все журналы в консоль, следовательно, используя level = TRACE for Console.
Пожалуйста, прочитайте весь ответ, прежде чем сделать окончательный выбор относительно того, что вы будете внедрять в свой код.
Вы можете сделать это, настроив свои регистраторы следующим образом:
<Loggers>
<Root>
<AppenderRef ref="console"/>
</Root>
<Logger name="parallel" level="ALL" additivity="true">
<AppenderRef ref="fileLogger" level="ERROR"/>
</Logger>
</Loggers>
События журнала будут приниматься каждым регистратором на основе имени регистратора и уровня события.Например, если вы звоните log.error(...)
, генерируется событие уровня ERROR
.Если log
было получено через LogManager.getLogger(ClassA.class)
, то log4j будет искать в своей конфигурации регистратор с именем «parallel.ClassA».Если он не найдет такой регистратор, он перейдет вверх по иерархии к менее специфичному регистратору - «параллельному».Если этот регистратор не существует, он перейдет к корневому регистратору.
Как только регистратор идентифицирован, log4j должен определить, является ли событие принятым этим регистратором.Это основано на настройке уровня для регистратора.Поскольку «параллельный» логгер установлен на уровне ALL
, он будет принимать события любого уровня.
После того, как регистратор принимает событие, его добавщики также должны принять событие.Уровень, связанный с файловым аппендером «параллельного» регистратора, равен ERROR
, поэтому этот аппендер будет принимать только события уровня ERROR
и FATAL
.
Поскольку аддитивность составляет true
для «параллельного» регистратора всякий раз, когда он принимает событие, он передает это событие аппендерам всех своих родительских регистраторов (если только один из них не сломается)цепочку, указав аддитивность false
- подробности см. на странице архитектуры log4j2 ).Таким образом, любые события, принятые «параллелью», будут передаваться приложению консоли, связанному с корневым регистратором.
Существует проблема с этим подходом в том, что если событие журнала достигло корневого регистратора суровень ERROR или FATAL не будет записан в ваш файл журнала.Логи будут «просачиваться» в консоль.Это может произойти, если вы случайно написали какой-то плохой код или случайно забыли обновить файл конфигурации после добавления нового кода.
Вот пример кода, иллюстрирующий проблему:
package parallel;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class ClassA {
private static final Logger log = LogManager.getLogger(ClassA.class);
public static void main(String[] args) {
log.info("info");
log.debug("debug");
log.warn("warn");
log.error("error");
log.fatal("fatal");
log.trace("trace");
// See the mistake here?
// The wrong logger name was used in the code,
// now the error event goes to the root logger!
final Logger log2 = LogManager.getLogger("foo");
log2.error("Woops an error!");
}
}
консольный вывод для вышеприведенного с использованием конфигурации с начала ответа:
[INFO ] 2019-05-05 12:48:31.410 [main] ClassA - info
[DEBUG] 2019-05-05 12:48:31.411 [main] ClassA - debug
[WARN ] 2019-05-05 12:48:31.411 [main] ClassA - warn
[ERROR] 2019-05-05 12:48:31.411 [main] ClassA - error
[FATAL] 2019-05-05 12:48:31.412 [main] ClassA - fatal
[TRACE] 2019-05-05 12:48:31.412 [main] ClassA - trace
[ERROR] 2019-05-05 12:48:31.413 [main] foo - Woops an error!
Файл журнала ошибок показывает только:
[ERROR] 2019-05-05 12:48:31 [main] ClassA - error
[FATAL] 2019-05-05 12:48:31 [main] ClassA - fatal
Самое простое решение - просто переместить все ваши приложения в корневой логгер, как показано ниже:
<Loggers>
<Root level="ALL">
<AppenderRef ref="console"/>
<AppenderRef ref="fileLogger" level="ERROR"/>
</Root>
</Loggers>
Теперь все события принимаются корневым регистратором и консольным приложением, но только события ERROR и FATALпринимается заявителем файла.Теперь даже при неверном коде журнал событий будет идти в нужное место.
Выход консоли:
[INFO ] 2019-05-05 12:59:32.419 [main] ClassA - info
[DEBUG] 2019-05-05 12:59:32.421 [main] ClassA - debug
[WARN ] 2019-05-05 12:59:32.421 [main] ClassA - warn
[ERROR] 2019-05-05 12:59:32.421 [main] ClassA - error
[FATAL] 2019-05-05 12:59:32.421 [main] ClassA - fatal
[TRACE] 2019-05-05 12:59:32.421 [main] ClassA - trace
[ERROR] 2019-05-05 12:59:32.422 [main] foo - Woops an error!
Файл журнала ошибок:
[ERROR] 2019-05-05 12:59:32 [main] ClassA - error
[FATAL] 2019-05-05 12:59:32 [main] ClassA - fatal
[ERROR] 2019-05-05 12:59:32 [main] foo - Woops an error!
Другие возможные полезные ссылки:
https://stackoverflow.com/a/51567436/3284624
Надеюсь, это поможет вам!