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 - 교환 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를 사용할 수 있습니다.