camel系列-Tracer

概念

Camel 的Tracer(跟踪器)用于在路由期间记录消息详细信息,您可以在其中看到每条消息发生时的路由路径。还会记录消息的详细信息,例如消息正文。

开启Tracer

1
2
3
4
5
6
public static void main(String[] args) throws Exception {
Main main = new Main();
main.configure().withRoutesIncludePattern("routes/*.xml");
main.configure().withTracing(true);
main.run(args);
}

运行日志

日志会打印路由相关的 Exchange 信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15:54:08.704 [DefaultQuartzScheduler-MyXmlCamel_Worker-2] INFO  org.apache.camel.Tracing - *--> [foo         ] [from[quartz:foo?cron={{myCron}}] ] Exchange[Id: 89D3473A20DFC41-0000000000000000, BodyType: null, Body: [Body is null]]
15:54:08.704 [DefaultQuartzScheduler-MyXmlCamel_Worker-1] INFO org.apache.camel.Tracing - *--> [foo ] [from[quartz:foo?cron={{myCron}}] ] Exchange[Id: 89D3473A20DFC41-0000000000000001, BodyType: null, Body: [Body is null]]
15:54:08.708 [DefaultQuartzScheduler-MyXmlCamel_Worker-2] INFO org.apache.camel.Tracing - [foo ] [bean[ref:myBean method:hello] ] Exchange[Id: 89D3473A20DFC41-0000000000000000, BodyType: null, Body: [Body is null]]
15:54:08.708 [DefaultQuartzScheduler-MyXmlCamel_Worker-1] INFO org.apache.camel.Tracing - [foo ] [bean[ref:myBean method:hello] ] Exchange[Id: 89D3473A20DFC41-0000000000000001, BodyType: null, Body: [Body is null]]
15:54:08.721 [DefaultQuartzScheduler-MyXmlCamel_Worker-1] INFO org.apache.camel.Tracing - [foo ] [log ] Exchange[Id: 89D3473A20DFC41-0000000000000001, BodyType: String, Body: Hello how are you?]
15:54:08.721 [DefaultQuartzScheduler-MyXmlCamel_Worker-2] INFO org.apache.camel.Tracing - [foo ] [log ] Exchange[Id: 89D3473A20DFC41-0000000000000000, BodyType: String, Body: Hello how are you?]
15:54:08.721 [DefaultQuartzScheduler-MyXmlCamel_Worker-1] INFO foo - Hello how are you?
15:54:08.721 [DefaultQuartzScheduler-MyXmlCamel_Worker-2] INFO foo - Hello how are you?
15:54:08.724 [DefaultQuartzScheduler-MyXmlCamel_Worker-1] INFO org.apache.camel.Tracing - [foo ] [bean[ref:myBean method:bye] ] Exchange[Id: 89D3473A20DFC41-0000000000000001, BodyType: String, Body: Hello how are you?]
15:54:08.724 [DefaultQuartzScheduler-MyXmlCamel_Worker-2] INFO org.apache.camel.Tracing - [foo ] [bean[ref:myBean method:bye] ] Exchange[Id: 89D3473A20DFC41-0000000000000000, BodyType: String, Body: Hello how are you?]
15:54:08.725 [DefaultQuartzScheduler-MyXmlCamel_Worker-2] INFO org.apache.camel.Tracing - [foo ] [log ] Exchange[Id: 89D3473A20DFC41-0000000000000000, BodyType: String, Body: Bye World]
15:54:08.725 [DefaultQuartzScheduler-MyXmlCamel_Worker-1] INFO org.apache.camel.Tracing - [foo ] [log ] Exchange[Id: 89D3473A20DFC41-0000000000000001, BodyType: String, Body: Bye World]
15:54:08.725 [DefaultQuartzScheduler-MyXmlCamel_Worker-2] INFO foo - Bye World
15:54:08.725 [DefaultQuartzScheduler-MyXmlCamel_Worker-1] INFO foo - Bye World

ExchangeFormatter

我们可以通过 ExchangeFormatter 来实现自定义的 Exchange 内容格式输出,系统默认格式实现为DefaultExchangeFormatter

自定义格式示例

  1. 实现 ExchangeFormatter 接口的 format 方法
1
2
3
4
5
6
public class CustomExchangeFormatter implements ExchangeFormatter {
@Override
public String format(Exchange exchange) {
return "customFormat:"+exchange.getIn().getBody();
}
}
  1. 使用 Tracer 的 setExchangeFormatter 方法设置 ExchangeFormatter
1
2
3
4
5
6
7
8
9
10
11
12
13
public static void main(String[] args) throws Exception {
// use Camels Main class
Main main = new Main();
main.configure().withTracing(true);
main.addMainListener(new MainListenerSupport() {
@Override
public void afterConfigure(BaseMainSupport main) {
main.getCamelContext().getTracer().
setExchangeFormatter(new CustomExchangeFormatter());
}
});
main.run(args);
}
  1. 测试运行日志
1
2
INFO  org.apache.camel.Tracing -      [foo         ] [bean[ref:myBean method:bye]      ] customFormat:Hello how are you?
INFO org.apache.camel.Tracing - [foo ] [log ] customFormat:Bye World

Backlog Tracer

Backlog Tracer 将跟踪消息存储在积压队列中,需要手动调用BacklogTracer 的相关 dump 方法来消费消息

开启 Backlog Tracer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args) throws Exception {

Main main = new Main();
main.configure().withBacklogTracing(true);
main.addMainListener(new MainListenerSupport() {
@Override
public void afterConfigure(BaseMainSupport main) {
BacklogTracer tracer=main.getCamelContext().getExtension(BacklogTracer.class);
tracer = BacklogTracer.createTracer(main.getCamelContext());
main.getCamelContext().setExtension(BacklogTracer.class, tracer);
tracer.setEnabled(true);
}
});
main.run(args);
}

运行效果

  1. 内存队列数量

  1. 调用 dumpAllTracedMessagesAsXml 后效果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<backlogTracerEventMessages>
<backlogTracerEventMessage>
<uid>58</uid>
<timestamp>2022-04-08T16:39:57.704+0800</timestamp>
<routeId>foo</routeId>
<toNode>log1</toNode>
<exchangeId>800F9FA329C6554-000000000000000B</exchangeId>
<message exchangeId="800F9FA329C6554-000000000000000B">
<headers>
<header key="CamelMessageTimestamp" type="java.lang.Long">1649407156007</header>
<header key="calendar"></header>
<header key="fireTime" type="java.util.Date">Fri Apr 08 16:39:16 CST 2022</header>
<header key="jobDetail" type="org.quartz.impl.JobDetailImpl">JobDetail 'Camel_MyXmlCamel.foo': jobClass: 'org.apache.camel.component.quartz.CamelJob concurrentExectionDisallowed: false persistJobDataAfterExecution: false isDurable: false requestsRecovers: false</header>
<header key="jobInstance" type="org.apache.camel.component.quartz.CamelJob">org.apache.camel.component.quartz.CamelJob@329ec7ad</header>
<header key="jobRunTime" type="java.lang.Long">-1</header>
<header key="mergedJobDataMap" type="org.quartz.JobDataMap">org.quartz.JobDataMap@23f33ac1</header>
<header key="nextFireTime" type="java.util.Date">Fri Apr 08 16:39:18 CST 2022</header>
<header key="previousFireTime" type="java.util.Date">Fri Apr 08 16:39:14 CST 2022</header>
<header key="refireCount" type="java.lang.Integer">0</header>
<header key="result"></header>
<header key="scheduledFireTime" type="java.util.Date">Fri Apr 08 16:39:16 CST 2022</header>
<header key="scheduler" type="org.quartz.impl.StdScheduler">org.quartz.impl.StdScheduler@281258a7</header>
<header key="trigger" type="org.quartz.impl.triggers.CronTriggerImpl">Trigger 'Camel_MyXmlCamel.foo': triggerClass: 'org.quartz.impl.triggers.CronTriggerImpl calendar: 'null' misfireInstruction: 1 nextFireTime: Fri Apr 08 16:39:18 CST 2022</header>
<header key="triggerGroup" type="java.lang.String">Camel_MyXmlCamel</header>
<header key="triggerName" type="java.lang.String">foo</header>
</headers>
<body type="java.lang.String">Hello how are you?</body>
</message>
</backlogTracerEventMessage>
</backlogTracerEventMessages>

和 TRACER 的区别

Backlog Tracer将消息的捕获存储在内部积压队列中。

Tracer基于事件并在消息发生时记录消息(或路由到另一个 Camel 目的地)。

当您只需要在跟踪消息发生时记录它们时,请使用Tracer 。

积压跟踪器允许您按需从积压队列中提取消息。积压跟踪器与支持 JMX 的工具一起工作得更好,因为它更简单,允许以 POJO 或 XML 格式批量转储所有跟踪的消息。

参考