1. 概述
在软件开发中,日志记录至关重要,它有助于记录应用程序的每一个足迹。它帮助追踪应用的行为和状态,对调试尤其有用。
Apache Camel 提供了一个组件、接口和拦截器来记录消息和交换。它通过提供各种日志框架的抽象层,简化了日志管理。
在这个教程中,我们将探讨在Camel应用中使用四种方法记录消息和交换的方式。
2. 使用Log EIP
自Apache Camel 2.2以来,提供了轻量级的log()
DSL,用于从路由中输出人类可读的消息。其主要用途是快速将消息输出到日志控制台。此外,我们还可以结合Camel的简单表达式语言(Simple),从路由中进一步将详细信息添加到日志控制台。
让我们看一个从一个文件夹复制文件的例子:
class FileCopierCamelRoute extends RouteBuilder {
void configure() {
from("file:data/inbox?noop=true")
.log("We got an incoming file ${file:name} containing: ${body}")
.to("file:data/outbox")
.log("Successfully transfer file: ${file:name}");
}
}
在上面的代码中,我们配置了一个RouteBuilder
,用于从inbox
文件夹传输文件到outbox
。首先,我们定义了接收到文件的位置。然后,我们使用log()
DSL输出关于接收到的文件及其内容的人类可读日志。同时,我们利用Simple表达式语言获取文件名和文件内容作为日志消息的一部分。
这是日志输出:
14:39:23.389 [Camel (camel-1) thread #1 - file://data/inbox] INFO route1 - We got an incoming file welcome.txt containing: Welcome to Baeldung
14:39:23.423 [Camel (camel-1) thread #1 - file://data/inbox] INFO route1 - Successlly transfer file: welcome.txt
与Log组件和Tracer拦截器相比,log()
DSL更加轻量级。
此外,我们可以显式指定日志级别和名称:
// ...
.log(LoggingLevel.DEBUG,"Output Process","The Process ${id}")
// ...
在这里,我们在传递日志消息之前指定了日志级别和名称。我们还支持WARN、TRACE和OFF作为日志级别。如果没有指定调试级别,log()
DSL将使用INFO级别。
3. 使用Processor
接口
Processor
是Apache Camel中的一个重要接口,它允许我们访问交换以进行进一步处理。它提供了改变交换体的灵活性。然而,我们也可以用它来输出人类可读的日志消息。
首先,Processor
本身并不是一个日志工具。因此,我们需要创建一个Logger
实例才能使用。Apache Camel默认使用SLF4J库。让我们创建一个Logger
实例:
private static final Logger LOGGER = LoggerFactory.getLogger(FileCopierCamelRoute.class);
接下来,让我们看一个示例,将消息传递给一个bean进行进一步处理:
void configure() {
from("file:data/inbox?noop=true")
.to("log:com.baeldung.apachecamellogging?level=INFO")
.process(process -> {
LOGGER.info("We are passing the message to a FileProcesor bean to capitalize the message body");
})
.bean(FileProcessor.class)
.to("file:data/outbox")
}
这里,我们将接收到的消息传递给FileProcessor
bean,将文件内容转换为大写。但在传递给bean进行处理之前,我们创建了一个Processor
实例来记录一条信息。
最后,这是日志输出:
14:50:47.048 [Camel (camel-1) thread #1 - file://data/inbox] INFO c.b.a.FileCopierCamelRoute - We are passing the message to a FileProcesor to Capitalize the message body
从输出可以看出,自定义的日志消息被输出到了控制台。
4. 使用Log组件
Apache Camel提供了一个Log组件,用于将Camel Message
记录到控制台输出。要使用Log组件,我们可以将消息路由到它:
void configure() {
from("file:data/inbox?noop=true")
.to("log:com.baeldung.apachecamellogging?level=INFO")
.bean(FileProcessor.class)
.to("file:data/outbox")
.to("log:com.baeldung.apachecamellogging")
}
在这段代码中,我们两次使用了Log组件。第一次,我们使用level
选项以INFO级别记录消息体。另外,我们在处理文件后也记录了消息体,但没有指定日志级别。
值得注意的是,如果没有指定日志级别,Log组件将使用INFO级别作为默认值。
这是日志输出:
09:36:32.432 [Camel (camel-1) thread #1 - file://data/inbox] INFO com.baeldung.apachecamellogging - Exchange[ExchangePattern: InOnly, BodyType: org.apache.camel.component.file.GenericFile, Body: [Body is file based: GenericFile[welcome.txt]]]
09:36:32.454 [Camel (camel-1) thread #1 - file://data/inbox] INFO com.baeldung.apachecamellogging - Exchange[ExchangePattern: InOnly, BodyType: String, Body: WELCOME TO BAELDUNG]
我们还可以通过添加showBodyType
和maxChars
选项来减少输出的详细程度:
.to("log:com.baeldung.apachecamellogging?showBodyType=false&maxChars=20")
在上述代码中,我们忽略了消息体的时间,并将字符流精简到20个。
5. 使用Tracer
Tracer是Apache Camel架构的一部分,它帮助在运行时记录消息路由过程。它在路由过程中跟踪交换快照。它可以拦截消息从一个节点移动到另一个节点。
要使用Tracer,我们需要在路由配置方法中启用它:
getContext().setTracing(true);
这使得Tracer拦截器能够拦截所有交换过程并将它们记录到日志控制台。
让我们看一个示例代码,启用Tracer跟踪交换过程:
void configure() {
getContext().setTracing(true);
from("file:data/json?noop=true")
.unmarshal().json(JsonLibrary.Jackson)
.bean(FileProcessor.class, "transform")
.marshal().json(JsonLibrary.Jackson)
.to("file:data/output");
}
在代码中,我们从源复制一个JSON文件,将其转换为Camel可以处理的数据结构,然后将内容传递给一个bean更改文件内容。接着,我们将消息转换为JSON并发送到预期的目的地。
这是Tracer拦截器的日志输出:
// ...
09:23:10.767 [Camel (camel-1) thread #1 - file://data/json] INFO FileCopierTracerCamelRoute:14 - *--> [route1 ] [from[file:data/json?noop=true] ]
09:23:10.768 [Camel (camel-1) thread #1 - file://data/json] INFO FileCopierTracerCamelRoute:14 - [route1 ] [log:input?level=INFO ]
// ...
在输出中,Tracer记录了从生产者到消费者的整个过程和所有交换。这对于调试非常有帮助。
值得注意的是,日志输出较为详细,为了简洁,我们只显示了关键的日志消息。
6. 总结
在这篇文章中,我们学习了在Apache Camel中记录日志的四种方法。我们还看到了使用log()
DSL、Tracer、Processor
接口和Log组件将消息记录到控制台的示例。log()
DSL和Processor
接口适合于生成人类可读的日志,而Log组件和Tracer则适用于更复杂的调试日志。
如往常一样,示例代码的源码可以在GitHub上找到。