SLF4J и Log4j-API предоставляют маркеры для того, что вы хотите. В SLF4J вы можете создавать свои маркеры с:
Marker apples = MarkerFactory.getMarker("Apples");
Marker oranges = MarkerFactory.getMarker("Oranges");
Marker mangos = MarkerFactory.getMarker("Mangos");
Кроме того, у маркеров может быть родитель, поэтому вы можете сделать:
Marker fruit = MarkerFactory.getMarker("Fruit");
Marker apples = MarkerFactory.getMarker("Apples");
apples.add(fruit);
Marker oranges = MarkerFactory.getMarker("Oranges");
apples.add(fruit);
Marker mangos = MarkerFactory.getMarker("Mangos");
apples.add(fruit);
В конфигурации вы можете либо проверить указать c Маркер или если вы хотите проверить все Маркеры, которые являются Фруктами, вы бы проверили этот Маркер.
Затем вы используете маркеры в своем приложении как:
logger.info(apples, "They are red in color");
logger.info(oranges, "They are orange in color");
logger.info(mangoes, "They are yellowish in color");
Наконец, в вашей конфигурации вы можете использовать турбо-фильтр для:
<turboFilter class="ch.qos.logback.classic.turbo.MarkerFilter">
<Marker>Apples</Marker>
<OnMatch>NEUTRAL</OnMatch>
<OnMismatch>DENY</OnMismatch>
</turboFilter>
для фильтрации на глобальном уровне или вы можете использовать один из фильтров оценщика для фильтрации в Appender. Вы также можете использовать SiftingAppender для динамического создания приложений, если вы пишете пользовательский дискриминатор.
С API Log4j все немного проще. Чтобы создать маркер без родителя:
Marker apples = MarkerManager.getMarker("Apples");
Marker oranges = MarkerManager.getMarker("Oranges");
Marker mangos = MarkerManager.getMarker("Mangos");
или с родителем:
Marker fruit = MarkerManager.getMarker("Fruit");
Marker apples = MarkerManager.getMarker("Apples").setParents(fruit);
Marker oranges = MarkerManager.getMarker("Oranges").setParents(fruit);
Marker mangos = MarkerManager.getMarker("Mangos").setParents(fruit);
Код для их использования в Log4j точно такой же:
logger.info(apples, "They are red in color");
logger.info(oranges, "They are orange in color");
logger.info(mangoes, "They are yellowish in color");
Большая разница в конфигурации. Log4j имеет только один вид фильтра, и его можно использовать на глобальном уровне (например, турбо-фильтр), либо в журнале, справочнике Appender или в Appender. В вашем случае вы захотите использовать MarkerFilter :
<MarkerFilter marker="Apples" onMatch="NEUTRAL" onMismatch="DENY"/>
и добавить это либо к каждой ссылке на Appender, либо к каждому Appender.
Аналогично SiftingAppender Log4j также предоставляет RoutingAppender . Он использует поиск, чтобы определить, как выполнить маршрутизацию. Из коробки Log4j не предоставляет один для извлечения данных из события журнала, но было бы просто написать один или добавить один в Log4j , или вы можете использовать скрипт для извлечения маркера из события .
Вы должны знать, что использование MarkerFilters сопряжено с некоторыми издержками, хотя и незначительными. Вот тест из модуля log4j-perf при запуске 4 потоков на моем MacBook Pro. Даже в худшем случае, когда Logback проверяет наличие родительского маркера по отношению к событию, содержащему дочерний маркер, каждое сравнение в среднем занимает всего 17 наносекунд.
Benchmark Mode Cnt Score Error Units
MarkerFilterBenchmark.baseline avgt 10 2.412 ± 0.088 ns/op
MarkerFilterBenchmark.log4jParentMarker avgt 10 8.337 ± 0.186 ns/op
MarkerFilterBenchmark.log4jSimpleMarker avgt 10 8.043 ± 0.145 ns/op
MarkerFilterBenchmark.log4jTooFine avgt 10 2.825 ± 0.281 ns/op
MarkerFilterBenchmark.logbackParentMarker avgt 10 17.865 ± 0.533 ns/op
MarkerFilterBenchmark.logbackSimpleMarker avgt 10 10.471 ± 0.089 ns/op
MarkerFilterBenchmark.logbackTooFine avgt 10 4.255 ± 0.014 ns/op
Последняя мысль. Ceki Gulcu изобрел концепцию Markers, когда создал SLF4J, и он заслуживает похвалы за это, поскольку это была фантастическая идея c.