로거의 다른 레벨을 다른 목적지에 로그하도록 로그 백 을 구성 하려면 어떻게 해야합니까?
예를 들어, 다음 Logback 구성 주어진 기록 Logback됩니다 INFO
에 대한 메시지 STDOUT
와 ERROR
메시지를하려면 STDERR
?
(이 예는 3 장 : 로그 백 구성에logback-examples/src/main/java/chapters/configuration/sample4.xml
표시된 예의 변형입니다 ).
<configuration>
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<appender name="STDERR"
class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
<target>System.err</target>
</appender>
<!-- What is the effective level of "chapters.configuration"? -->
<logger name="chapters.configuration" level="INFO" additivity="false">
<appender-ref ref="STDOUT" />
</logger>
<logger name="chapters.configuration" level="ERROR" additivity="false">
<appender-ref ref="STDERR" />
</logger>
<!-- turn OFF all logging (children can override) -->
<root level="OFF">
<appender-ref ref="STDOUT" />
</root>
</configuration>
답변
업데이트 : Groovy를 사용한 모든 구성 기반 접근 방식은 Dean Hiller의 답변을 참조하십시오 .
–
Logback 필터를 사용 하여 몇 가지 흥미로운 작업을 수행 할 수 있습니다 . 아래 구성은 stderr에 경고 및 오류 메시지를 표시하고 stdout에 모든 것을 인쇄합니다.
logback.xml
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<target>System.out</target>
<filter class="com.foo.StdOutFilter" />
...
</appender>
<appender name="stderr" class="ch.qos.logback.core.ConsoleAppender">
<target>System.err</target>
<filter class="com.foo.ErrOutFilter" />
...
</appender>
<logger name="mylogger" level="debug">
<appender-ref ref="stdout" />
<appender-ref ref="stderr" />
</logger>
com.foo.StdOutFilter
public class StdOutFilter extends ch.qos.logback.core.filter.AbstractMatcherFilter
{
@Override
public FilterReply decide(Object event)
{
if (!isStarted())
{
return FilterReply.NEUTRAL;
}
LoggingEvent loggingEvent = (LoggingEvent) event;
List<Level> eventsToKeep = Arrays.asList(Level.TRACE, Level.DEBUG, Level.INFO);
if (eventsToKeep.contains(loggingEvent.getLevel()))
{
return FilterReply.NEUTRAL;
}
else
{
return FilterReply.DENY;
}
}
}
com.foo.ErrOutFilter
public class ErrOutFilter extends ch.qos.logback.core.filter.AbstractMatcherFilter
{
@Override
public FilterReply decide(Object event)
{
if (!isStarted())
{
return FilterReply.NEUTRAL;
}
LoggingEvent loggingEvent = (LoggingEvent) event;
List<Level> eventsToKeep = Arrays.asList(Level.WARN, Level.ERROR);
if (eventsToKeep.contains(loggingEvent.getLevel()))
{
return FilterReply.NEUTRAL;
}
else
{
return FilterReply.DENY;
}
}
}
답변
이것이 가장 간단한 해결책이라고 생각합니다.
<configuration>
<contextName>selenium-plugin</contextName>
<!-- Logging configuration -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<Target>System.out</Target>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%level] %msg%n</pattern>
</encoder>
</appender>
<appender name="STDERR" class="ch.qos.logback.core.ConsoleAppender">
<Target>System.err</Target>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%level] [%thread] %logger{10} [%file:%line] %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="STDERR" />
</root>
</configuration>
답변
ThresoldFilter 및 LevelFilters를 사용하여 구성 만 기반으로하는 솔루션으로 실제로 이해하기가 간단합니다 .
<configuration>
<appender name="STDERR" class="ch.qos.logback.core.ConsoleAppender">
<target>System.err</target>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
<encoder>
<pattern>%date %level [%thread] %logger %msg%n</pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<target>System.out</target>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
</filter>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
</filter>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>TRACE</level>
<onMatch>ACCEPT</onMatch>
</filter>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>DENY</onMatch>
</filter>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>DENY</onMatch>
</filter>
<encoder>
<pattern>%date %level [%thread] %logger %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="STDERR" />
</root>
</configuration>
답변
좋아, 여기 내가 좋아하는 XML 방식이 있습니다. 나는 일식 버전을 위해 이것을한다. 그래서 나는 할 수있다.
- 물건을 클릭하면 로그 내역으로 이동합니다.
- 정보를 아래에서 검은 색으로보고 빨간색으로 경고 / 심각하게
그리고 어떤 이유로 SO는 이것을 올바르게 표시하지 않지만 대부분 거기에있는 것 같습니다 …
<configuration scan="true" scanPeriod="30 seconds">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<evaluator class="ch.qos.logback.classic.boolex.GEventEvaluator">
<expression>
e.level.toInt() <= INFO.toInt()
</expression>
</evaluator>
<OnMismatch>DENY</OnMismatch>
<OnMatch>NEUTRAL</OnMatch>
</filter>
<encoder>
<pattern>%date{ISO8601} %X{sessionid}-%X{user} %caller{1} %-4level: %message%n</pattern>
</encoder>
</appender>
<appender name="STDERR" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>warn</level>
</filter>
<encoder>
<pattern>%date{ISO8601} %X{sessionid}-%X{user} %caller{1} %-4level: %message%n</pattern>
</encoder>
<target>System.err</target>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="STDOUT"/>
<appender-ref ref="STDERR"/>
</root>
</configuration>
답변
가장 간단한 해결책은 ThresholdFilter
어 펜더 에서 사용 하는 것입니다.
<appender name="..." class="...">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
전체 예 :
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<encoder>
<pattern>%d %-5level: %msg%n</pattern>
</encoder>
</appender>
<appender name="STDERR" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<target>System.err</target>
<encoder>
<pattern>%d %-5level: %msg%n</pattern>
</encoder>
</appender>
<root>
<appender-ref ref="STDOUT" />
<appender-ref ref="STDERR" />
</root>
</configuration>
업데이트 : Mike가 주석에서 지적했듯이 ERROR 수준의 메시지가 여기에 STDOUT 및 STDERR로 인쇄됩니다. OP의 의도가 무엇인지 확실하지 않습니다. 이것이 원하는 것이 아니라면 Mike의 대답을 시도해 볼 수 있습니다.
답변
이것은 내가 사용하는 구성이며 잘 작동하며 XML + JaninoEventEvaluator를 기반으로합니다 ( Janino 라이브러리를 Classpath에 추가해야 함)
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%date | [%-5level] in [%file:%line] - %msg %n</pattern>
</encoder>
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<evaluator class="ch.qos.logback.classic.boolex.JaninoEventEvaluator">
<expression>
level <= INFO
</expression>
</evaluator>
<OnMismatch>DENY</OnMismatch>
<OnMatch>NEUTRAL</OnMatch>
</filter>
</appender>
<appender name="STDERR" class="ch.qos.logback.core.ConsoleAppender">
<target>System.err</target>
<encoder>
<pattern>%date | [%-5level] in [%file:%line] - %msg %n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
<appender-ref ref="STDERR" />
</root>
</configuration>
답변
logback.groovy를 사용하여 로그 백을 구성하지만 xml 구성으로도 수행 할 수 있습니다.
import static ch.qos.logback.classic.Level.*
import static ch.qos.logback.core.spi.FilterReply.DENY
import static ch.qos.logback.core.spi.FilterReply.NEUTRAL
import ch.qos.logback.classic.boolex.GEventEvaluator
import ch.qos.logback.classic.encoder.PatternLayoutEncoder
import ch.qos.logback.core.ConsoleAppender
import ch.qos.logback.core.filter.EvaluatorFilter
def patternExpression = "%date{ISO8601} [%5level] %msg%n"
appender("STDERR", ConsoleAppender) {
filter(EvaluatorFilter) {
evaluator(GEventEvaluator) {
expression = 'e.level.toInt() >= WARN.toInt()'
}
onMatch = NEUTRAL
onMismatch = DENY
}
encoder(PatternLayoutEncoder) {
pattern = patternExpression
}
target = "System.err"
}
appender("STDOUT", ConsoleAppender) {
filter(EvaluatorFilter) {
evaluator(GEventEvaluator) {
expression = 'e.level.toInt() < WARN.toInt()'
}
onMismatch = DENY
onMatch = NEUTRAL
}
encoder(PatternLayoutEncoder) {
pattern = patternExpression
}
target = "System.out"
}
logger("org.hibernate.type", WARN)
logger("org.hibernate", WARN)
logger("org.springframework", WARN)
root(INFO,["STDERR","STDOUT"])
필터 클래스를 만들 필요가 없으므로 GEventEvaluator를 사용하는 것이 더 간단하다고 생각합니다.
영어로 사과드립니다!