20.4. 고급 구성

20.4.1. SIFT 로깅

Fuse-Karaf는 Log4j2 sift appender의 샘플(기본적으로 설명) 구성과 $FUSE_HOME/etc/org.ops4j.pax.logging.cfg 파일에서 이 appender를 사용하는 로거를 제공합니다.

# Sift appender
log4j2.appender.mdc.type = Routing
log4j2.appender.mdc.name = SiftAppender
log4j2.appender.mdc.routes.type = Routes
# see: http://logging.apache.org/log4j/2.x/manual/appenders.html#Routes
log4j2.appender.mdc.routes.pattern = $\\{ctx:bundle.name}
log4j2.appender.mdc.routes.sift.type = Route
log4j2.appender.mdc.routes.sift.appender.type = RollingRandomAccessFile
log4j2.appender.mdc.routes.sift.appender.name = RollingFile
log4j2.appender.mdc.routes.sift.appender.fileName = ${karaf.data}/log/sift-$\\{ctx:bundle.name}.log
log4j2.appender.mdc.routes.sift.appender.filePattern = ${karaf.data}/log/sift-$\\{ctx:bundle.name}-%i.log.gz
log4j2.appender.mdc.routes.sift.appender.append = true
log4j2.appender.mdc.routes.sift.appender.layout.type = PatternLayout
log4j2.appender.mdc.routes.sift.appender.layout.pattern = ${log4j2.pattern}
log4j2.appender.mdc.routes.sift.appender.policies.type = Policies
log4j2.appender.mdc.routes.sift.appender.policies.size.type = SizeBasedTriggeringPolicy
log4j2.appender.mdc.routes.sift.appender.policies.size.size = 16MB
log4j2.appender.mdc.routes.sift.appender.strategy.type = DefaultRolloverStrategy
log4j2.appender.mdc.routes.sift.appender.strategy.max = 20
...
# sample logger using Sift appender
#log4j2.logger.example.name = org.apache.camel
#log4j2.logger.example.level = INFO
#log4j2.logger.example.appenderRef.SiftAppender.ref = SiftAppender

구성은 http://logging.apache.org/log4j/2.x/manual/appenders.html#RoutingAppender에 설명되어 있습니다.

SIFT/Routing appender의 pattern 속성은 로깅의 대상 위치를 구분하는 데 사용할 수 있는 것입니다.

다음은 다양한 조회를 사용할 수 있으며 여기에 설명되어 있습니다. http://logging.apache.org/log4j/2.x/manual/lookups.html

가장 중요한 조회는 ThreadContext 맵(.k.a)에서 값(keys)을 조회하는 ctx 입니다. MDC).

Fuse Karaf에서 제공하는 기본 구성은 ctx:bundle.name을 패턴으로 사용합니다. 즉, 다음과 같습니다.

lookup bundle.name key in MDC

bundle. 접두사가 지정된 키는 pax-logging 자체에서 제공하며 다음 3가지 값 중에서 선택할 수 있습니다.

  • bundle.name == org.osgi.framework.Bundle.getSymbolicName()
  • bundle.id == org.osgi.framework.Bundle.getBundleId()
  • bundle.version == org.osgi.framework.Bundle.getVersion().toString()

그러나 다음을 사용하여 MDC 지원을 통해 Camel 컨텍스트가 생성되는 경우(파란트 XML DSL).

<camelContext id="my-context" xmlns="http://camel.apache.org/schema/blueprint" useMDCLogging="true">

MDC/ThreadContext에서 사용할 수 있는 더 많은 키가 있으며 SIFT appender 구성에서 패턴으로 사용할 수 있습니다.

  • camel.exchangeId - The exchange id
  • Camel.messageId - 메시지 ID
  • Camel.correlationId - 상관 관계가 있는 경우 교환의 상관관계 ID입니다. 예를 들어 Splitter EIP에서 하위 메시지
  • Camel. CryostatKey - 트랜잭션된 교환에 대한 트랜잭션 ID입니다. id는 고유하지 않지만 지정된 트랜잭션의 트랜잭션 경계를 표시하는 트랜잭션 템플릿의 ID입니다. 따라서 이 사실을 가리키기 위해 TransactionID가 아닌 키의 이름을 지정했습니다.
  • Camel.routeId - 교환이 현재 라우팅되고 있는 경로의 ID
  • Camel.breadcrumbId - 전송 간 메시지를 추적하는 데 사용되는 고유 ID입니다.
  • Camel.contextId - 다른 카멜 컨텍스트의 메시지를 추적하는 데 사용되는 camel 컨텍스트 ID입니다.

https://people.apache.org/~dkulp/camel/mdc-logging.html에서 참조하십시오.

예를 들어 로깅 대상 파일을 Camel의 경로 ID로 구분하려면 다음을 사용하십시오.

log4j2.appender.mdc.routes.pattern = $\\{ctx:camel.routeId}
...
log4j2.appender.mdc.routes.sift.appender.fileName = ${karaf.data}/log/sift-$\\{ctx:camel.routeId}.log
log4j2.appender.mdc.routes.sift.appender.filePattern = ${karaf.data}/log/sift-$\\{ctx:camel.routeId}-%i.log.gz

한 가지 더 - 추가 구성만으로는 충분하지 않습니다. 일부 로거에 연결해야 합니다. 다시 한 번 샘플 구성에는 다음이 포함됩니다.

# sample logger using Sift appender
#log4j2.logger.example.name = org.apache.camel
#log4j2.logger.example.level = INFO
#log4j2.logger.example.appenderRef.SiftAppender.ref = SiftAppender

( log4j2.logger.example.appenderRef.SiftAppender.ref 속성의 SiftAppender 값은 appender 구성의 log4j2.appender.mdc.name 값과 일치해야 합니다).

여기서 org.apache.camel은 로거 이름(또는 카테고리 이름)입니다. 이는 Camel의 로그에 사용되는 끝점과 정확히 동일합니다. If you have (in Camel route):

<to uri="log:org.apache.camel" />

로깅이 작동했습니다.

다른 작업 구성은 다음과 같습니다.

<to uri="log:my-special-logger" />

및 다음을 수행합니다.

log4j2.logger.example.name = my-special-logger
log4j2.logger.example.level = DEBUG
log4j2.logger.example.appenderRef.SiftAppender.ref = SiftAppender

20.4.2. 필터

appender에 필터를 적용할 수 있습니다. 필터는 각 로그 이벤트를 평가하고 로그로 보낼지 여부를 결정합니다.

Log4j2는 필터를 사용할 준비가 되어 있습니다.

참고

이에 대한 포괄적인 보기는 Log4J 사이트의 필터 를 참조하십시오.

20.4.3. 중첩된 appender

중첩된 appender는 다른 appender를 "내부"하는 특수한 종류의 appender입니다. 이를 통해 appender 체인 사이에 일종의 "라우팅"을 생성할 수 있습니다.

가장 많이 사용되는 "nested compliant" appender는 다음과 같습니다.

  • AsyncAppender(org.apache.log4j2.AsyncAppender)는 이벤트를 비동기적으로 기록합니다. 이 appender는 이벤트를 수집하여 연결된 모든 부록에 전달합니다.
  • RewriteAppender(org.apache.log4j2.rewrite.RewriteAppender)는 로그 이벤트를 다시 작성한 후 다른 appender로 로그 이벤트를 전달합니다.

이러한 종류의 appender는 appender 정의에서 appenders 속성을 허용합니다.

log4j2.appender.[appender-name].appenders=[comma-separated-list-of-appender-names]

예를 들어 async 라는 Async 및 비동기적으로 로그 이벤트를 JMS appender에 디스패치하는 AsyncAppender를 생성할 수 있습니다.

log4j2.appender.async=org.apache.log4j2.AsyncAppender
log4j2.appender.async.appenders=jms

log4j2.appender.jms=org.apache.log4j2.net.JMSAppender
...

20.4.4. 오류 처리기

경우에 따라 appender가 실패할 수 있습니다. 예를 들어 RollingFileAppender 는 파일 시스템에 작성하려고 하지만 파일 시스템이 가득거나 JMS appender가 메시지를 전송하려고 하지만 JMS 브로커를 사용할 수 없습니다.

로그 appender가 실패하는지 확인하는 것이 중요하므로 로깅이 중요할 수 있습니다.

각 로그 appender는 오류 처리기에 오류 처리를 위임하여 appender 오류에 대응할 수 있는 기회를 제공합니다.

  • CryostatAppender(org.apache.log4j2.varia.FailoverAppender)를 사용하면 기본 추가 기능이 실패할 경우 보조 첨부자가 대신할 수 있습니다. 오류 메시지가 System.err 에 출력되고 보조 첨부 파일에 기록됩니다.
참고

Cryostat Appender에 대한 자세한 내용은 Log4j2의 Apppender 페이지로 이동합니다.

appender 정의 자체에서 errorhandler 속성을 사용하여 각 appender에 사용할 오류 처리기 를 정의할 수 있습니다.

log4j2.appender.[appender-name].errorhandler=[error-handler-class]
log4j2.appender.[appender-name].errorhandler.root-ref=[true|false]
log4j2.appender.[appender-name].errorhandler.logger-ref=[logger-ref]
log4j2.appender.[appender-name].errorhandler.appender-ref=[appender-ref]

20.4.5. OSGi 특정 MDC 속성

라우팅 부록 은 MDC(Mapped Diagnostic Context) 속성을 기반으로 로그 이벤트를 분할할 수 있는 OSGi 지향 appender입니다.

MDC를 사용하면 다양한 로그 이벤트 소스를 구분할 수 있습니다.

라우팅 appender는 기본적으로 OSGi 지향 MDC 속성을 제공합니다.

  • bundle.id 는 번들 ID입니다.
  • bundle.name 은 번들 심볼릭 이름입니다.
  • bundle.version 은 번들 버전입니다.

이러한 MDC 속성을 사용하여 번들당 로그 파일을 생성할 수 있습니다.

log4j2.appender.routing.type = Routing
log4j2.appender.routing.name = Routing
log4j2.appender.routing.routes.type = Routes
log4j2.appender.routing.routes.pattern = $$\\{ctx:bundle.name\\}
log4j2.appender.routing.routes.bundle.type = Route
log4j2.appender.routing.routes.bundle.appender.type = RollingRandomAccessFile
log4j2.appender.routing.routes.bundle.appender.name = Bundle-$\\{ctx:bundle.name\}
log4j2.appender.routing.routes.bundle.appender.fileName = ${karaf.data}/log/bundle-$\\{ctx:bundle.name\\}.log
log4j2.appender.routing.routes.bundle.appender.filePattern = ${karaf.data}/log/bundle-$\\{ctx:bundle.name\\}.log.%d{yyyy-MM-dd}
log4j2.appender.routing.routes.bundle.appender.append = true
log4j2.appender.routing.routes.bundle.appender.layout.type = PatternLayout
log4j2.appender.routing.routes.bundle.appender.policies.type = Policies
log4j2.appender.routing.routes.bundle.appender.policies.time.type = TimeBasedTriggeringPolicy
log4j2.appender.routing.routes.bundle.appender.strategy.type = DefaultRolloverStrategy
log4j2.appender.routing.routes.bundle.appender.strategy.max = 31

log4j2.rootLogger.appenderRef.Routing.ref = Routing

20.4.6. 향상된 OSGi 스택 추적 렌더러

기본적으로 Apache Karaf는 특정 스택 추적 렌더러를 제공하여 일부 OSGi 특정 정보를 추가합니다.

스택 추적에서 예외를 throw하는 클래스 외에도 각 스택 추적 라인 끝에 [id:name:version] 패턴을 찾을 수 있습니다.

  • 번들 ID입니다.
  • 번들 이름입니다.
  • version 은 bundle 버전입니다.

문제의 원인을 진단하는 것이 매우 유용합니다.

예를 들어 다음 IllegalArgumentException 스택 추적에서는 예외 소스에 대한 OSGi 세부 정보를 볼 수 있습니다.

java.lang.IllegalArgumentException: Command not found:  *:foo
	at org.apache.felix.gogo.runtime.shell.Closure.execute(Closure.java:225)[21:org.apache.karaf.shell.console:4.0.0]
	at org.apache.felix.gogo.runtime.shell.Closure.executeStatement(Closure.java:162)[21:org.apache.karaf.shell.console:4.0.0]
	at org.apache.felix.gogo.runtime.shell.Pipe.run(Pipe.java:101)[21:org.apache.karaf.shell.console:4.0.0]
	at org.apache.felix.gogo.runtime.shell.Closure.execute(Closure.java:79)[21:org.apache.karaf.shell.console:4.0.0]
	at org.apache.felix.gogo.runtime.shell.CommandSessionImpl.execute(CommandSessionImpl.java:71)[21:org.apache.karaf.shell.console:4.0.0]
	at org.apache.karaf.shell.console.jline.Console.run(Console.java:169)[21:org.apache.karaf.shell.console:4.0.0]
	at java.lang.Thread.run(Thread.java:637)[:1.7.0_21]

20.4.7. 사용자 정의 appender

Apache Karaf에서 고유한 appender를 사용할 수 있습니다.

가장 쉬운 방법은 appender를 OSGi 번들로 패키지하고 org.ops4j.pax.logging.pax-logging-service 번들의 조각으로 연결하는 것입니다.

예를 들어 MyAppender 를 만듭니다.

public class MyAppender extends AppenderSkeleton {
...
}

다음과 같이 MANIFEST가 포함된 OSGi 번들로 컴파일하고 패키징합니다.

Manifest:
Bundle-SymbolicName: org.mydomain.myappender
Fragment-Host: org.ops4j.pax.logging.pax-logging-service
...

Apache Karaf 시스템 폴더에 번들을 복사합니다. 시스템 폴더는 표준 Maven 디렉터리 레이아웃인 groupId/artifactId/version을 사용합니다.

etc/startup.properties 구성 파일에서 pax-logging-service 번들 전에 목록에 번들을 정의합니다.

시스템 번들을 다시 로드하려면 새로 실행( 데이터 폴더 수행)을 사용하여 Apache Karaf를 다시 시작해야 합니다. 이제 etc/org.ops4j.pax.logging.cfg 구성 파일에서 직접 appender를 사용할 수 있습니다.