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]

我们还可以通过添加showBodyTypemaxChars选项来减少输出的详细程度:

.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上找到。


« 上一篇: Java Weekly, Issue 536