fuse-Karaf 提供了示例(默认情况下为 out)Log4j2 sift appender 配置,并使用 $FUSE_HOME/etc/org.ops4j.pax.logging.cfg 文件中的这个附件程序:
# 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
# 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
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
该配置在 http://logging.apache.org/log4j/2.x/manual/appenders.html#RoutingAppender 中进行了描述
SIFT/Routing 附加器的模式属性是可用于区分用于记录的目标位置。
可用的查找有多种,如下所述 :http://logging.apache.org/log4j/2.x/manual/lookups.html
最重要的查找是 ctx,它会在 ThreadContext 映射(a.k.a)中查找值(键)。MDC).
Fuse Karaf 提供的默认配置使用 ctx:bundle.name 作为模式,这意味着:
lookup bundle.name key in MDC
lookup bundle.name key in MDC
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
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()
但是,如果 Camel 上下文是使用 MDC 支持的 Camel 上下文(蓝色打印 XML DSL):
<camelContext id="my-context" xmlns="http://camel.apache.org/schema/blueprint" useMDCLogging="true">
<camelContext id="my-context" xmlns="http://camel.apache.org/schema/blueprint" useMDCLogging="true">
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
在 MDC/ThreadContext 中,我还有更多可用的密钥,然后在 SIFT appender 配置中可用作模式:
camel.exchangeId - Exchange id
camel.messageId - 消息 id
camel.correlationId - 如果交换的关联 ID (如果其关联)。例如,Splitter EIP 中的子消息
camel.transactionKey - 转换交换的事务 ID。请注意,id 并不唯一,而是其事务模板的 id,用于标记给定事务的事务边界。因此,我们决定将关键的 transactionKey 而不是 transactionID 命名来指出这一事实。
camel.routeId - 路由的 id,其中交换当前正在路由
camel.breadcrumbId - 用于跨传输跟踪消息的唯一 id。
camel.contextId - 用于从不同 camel 上下文跟踪消息的 camel 上下文 id。
See 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
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
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
更重要的是 - 单独附加程序配置不够 - 您必须将其附加到一些日志记录器。同样,示例配置包含:
sample logger using Sift appender
#log4j2.logger.example.name = org.apache.camel
#log4j2.logger.example.level = INFO
#log4j2.logger.example.appenderRef.SiftAppender.ref = SiftAppender
# sample logger using Sift appender
#log4j2.logger.example.name = org.apache.camel
#log4j2.logger.example.level = INFO
#log4j2.logger.example.appenderRef.SiftAppender.ref = SiftAppender
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
(请注意,log4j2.logger.example.appenderRef.SiftAppender.ref 属性的值应与 appender 配置中的 log4j2.appender.mdc.name 的值匹配。
在这里,org.apache.camel 是一个日志记录器名称(或类别名称)。这与 Camel log: 端点中使用的值完全相同。因此,如果您在 Camel 路由中:
<to uri="log:org.apache.camel" />
<to uri="log:org.apache.camel" />
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
日志记录将正常工作。
另一个工作配置是:
<to uri="log:my-special-logger" />
<to uri="log:my-special-logger" />
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
和:
log4j2.logger.example.name = my-special-logger
log4j2.logger.example.level = DEBUG
log4j2.logger.example.appenderRef.SiftAppender.ref = SiftAppender
log4j2.logger.example.name = my-special-logger
log4j2.logger.example.level = DEBUG
log4j2.logger.example.appenderRef.SiftAppender.ref = SiftAppender
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
您可以将过滤器应用到附加程序。过滤器评估每个日志事件,并确定是否将其发送到日志。
Log4j2 提供可供使用过滤器使用。
有关这些内容的综合视图,请参阅 Log4J 站点的 过滤器 。
嵌套的附加程序是一个特殊的附加程序,您可以使用"inside"另一个附加程序。它允许您在附加器链之间创建某种类型的"routing"。
最常用的"嵌套合规"附加器是:
AsyncAppender (org.apache.log4j2.AsyncAppender)异步日志事件。此附加程序收集事件并将其分配给附加到它的所有附加者。
RewriteAppender (org.apache.log4j2.rewrite.RewriteAppender)在可能重写日志事件后将日志事件转发到另一个附加程序。
这个附加程序接受 appender 定义中的 appenders 属性:
log4j2.appender.[appender-name].appenders=[comma-separated-list-of-appender-names]
log4j2.appender.[appender-name].appenders=[comma-separated-list-of-appender-names]
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
例如,您可以创建一个名为 async 的 AsyncAppender,并将日志事件异步分配给 JMS 附加器:
log4j2.appender.async=org.apache.log4j2.AsyncAppender
log4j2.appender.async.appenders=jms
log4j2.appender.jms=org.apache.log4j2.net.JMSAppender
...
log4j2.appender.async=org.apache.log4j2.AsyncAppender
log4j2.appender.async.appenders=jms
log4j2.appender.jms=org.apache.log4j2.net.JMSAppender
...
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
有时,附加程序可能会失败。例如,RollingFileAppender 会尝试写入文件系统,但文件系统已满,或者 JMS 附加程序会尝试发送消息,但 JMS 代理不可用。
日志记录可能是关键的,因此务必要知道日志附加程序是否失败。
每个日志附加程序都可以将错误处理委托给错误处理程序,从而有机会对附加错误做出反应。
FailoverAppender (org.apache.log4j2.varia.FailoverAppender)允许次要附加程序在主附加程序失败时接管。错误消息会在 System.err 上打印,并记录在次要附加器中。
您可以使用 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]
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]
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
路由 附加程序是一种面向 OSGi 的附加程序,允许您根据 MDC (映射诊断上下文)属性分割日志事件。
MDC 允许您区分不同的日志事件来源。
路由 附加程序默认提供面向 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
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
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
默认情况下,Apache Karaf 提供特殊的堆栈跟踪呈现器,添加一些 OSGi 特定信息。
在堆栈追踪中,除了引发异常的类外,您可以在每个堆栈追踪行的末尾找到模式 [id:name:version],其中:
id 是捆绑包 ID
name 是捆绑包名称
version 是捆绑包版本
诊断问题来源非常有帮助。
例如,在以下 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]
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]
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
您可以在 Apache Karaf 中使用您自己的附加程序。
执行此操作的最简单方法是将您的附加程序打包为 OSGi 捆绑包,并将其附加为 org.ops4j.pax.logging.pax-logging-service 捆绑包的片段。
例如,您可以创建 MyAppender :
public class MyAppender extends AppenderSkeleton {
...
}
public class MyAppender extends AppenderSkeleton {
...
}
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
您编译和打包为包含 MANIFEST 的 OSGi 捆绑包,如下所示:
Manifest:
Bundle-SymbolicName: org.mydomain.myappender
Fragment-Host: org.ops4j.pax.logging.pax-logging-service
...
Manifest:
Bundle-SymbolicName: org.mydomain.myappender
Fragment-Host: org.ops4j.pax.logging.pax-logging-service
...
Copy to Clipboard
Copied!
Toggle word wrap
Toggle overflow
在 Apache Karaf 系统 文件夹中复制您的捆绑包。系统 文件夹使用标准 Maven 目录布局:groupId/artifactId/version。
在 etc/startup.properties 配置文件中,您可以在 pax-logging-service 捆绑包前在列表中定义捆绑包。
您必须通过干净运行(提升 数据 文件夹)来重新启动 Apache Karaf,才能重新加载系统捆绑包。现在,您可以在 etc/org.ops4j.pax.logging.cfg 配置文件中直接使用您的 appender。