camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Camel > Tracer
Date Sat, 29 Dec 2012 12:16:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2042/9/1/_/styles/combined.css?spaceKey=CAMEL&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/CAMEL/Tracer">Tracer</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~muellerc">Christian
Mueller</a>
    </h4>
        <br/>
                         <h4>Changes (1)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >You can enable or disable the Tracer&#39;s
logging dynamically, by calling the tracer&#39;s {{setEnabled}} method. <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">{tip:title=Logging
dependencies} <br>Checkout which [dependencies|camel jar dependencies] are required
by Camel for logging purpose. <br>{tip} <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h3. Options <br>{div:class=confluenceTableSmall}
<br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h2><a name="Tracer-TracerInterceptor"></a>Tracer Interceptor</h2>

<p>Camel supports a tracer interceptor that is used for logging the route executions
at <tt>INFO</tt> level.</p>

<p>The Tracer is an InterceptStrategy which can be applied to a DefaultCamelContext
or SpringCamelContext to ensure that there is a TracerInterceptor created for every node in
the DSL.</p>

<p>You can enable or disable the Tracer's logging dynamically, by calling the tracer's
<tt>setEnabled</tt> method.</p>

<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/check.gif" width="16" height="16"
align="absmiddle" alt="" border="0"></td><td><b>Logging dependencies</b><br
/>Checkout which <a href="/confluence/display/CAMEL/Camel+jar+dependencies" title="Camel
jar dependencies">dependencies</a> are required by Camel for logging purpose.</td></tr></table></div>

<h3><a name="Tracer-Options"></a>Options</h3>
<div class="confluenceTableSmall"><div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Option </th>
<th class='confluenceTh'> Default </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> formatter </td>
<td class='confluenceTd'>&nbsp;</td>
<td class='confluenceTd'> Sets the Trace Formatter to use. Will default use <tt>org.apache.camel.processor.interceptor.DefaultTraceFormatter</tt>.
</td>
</tr>
<tr>
<td class='confluenceTd'> enabled </td>
<td class='confluenceTd'> true </td>
<td class='confluenceTd'> Flag to enable or disable this tracer </td>
</tr>
<tr>
<td class='confluenceTd'> logLevel </td>
<td class='confluenceTd'> <tt>INFO</tt> </td>
<td class='confluenceTd'> The logging level to use: FATAL, ERROR, WARN, INFO, DEBUG,
TRACE, OFF </td>
</tr>
<tr>
<td class='confluenceTd'> logName </td>
<td class='confluenceTd'>&nbsp;</td>
<td class='confluenceTd'> The log name to use. Will default use <tt>org.apache.camel.processor.interceptor.TraceInterceptor</tt>.</td>
</tr>
<tr>
<td class='confluenceTd'> traceFilter </td>
<td class='confluenceTd'> null </td>
<td class='confluenceTd'> An exchange <a href="/confluence/display/CAMEL/Predicate"
title="Predicate">Predicate</a> to filter the tracing. </td>
</tr>
<tr>
<td class='confluenceTd'> traceInterceptors </td>
<td class='confluenceTd'> false </td>
<td class='confluenceTd'> Flag to enable or disable tracing of interceptors </td>
</tr>
<tr>
<td class='confluenceTd'> traceExceptions </td>
<td class='confluenceTd'> true</td>
<td class='confluenceTd'> Flag to enable or disable tracing of thrown exception during
processing of the exchange </td>
</tr>
<tr>
<td class='confluenceTd'> traceOutExchanges </td>
<td class='confluenceTd'> false </td>
<td class='confluenceTd'> Flag to enable fine grained tracing with a callback for both
IN (before) and OUT (after). Is disabled by default which means there is only one trace callback
executed. </td>
</tr>
<tr>
<td class='confluenceTd'> logStackTrace </td>
<td class='confluenceTd'> false </td>
<td class='confluenceTd'> When tracing exception you can control whether the stack trace
should be logged also. If <b>not</b> then only the exception class and message
is logged. </td>
</tr>
<tr>
<td class='confluenceTd'> useJpa </td>
<td class='confluenceTd'> false </td>
<td class='confluenceTd'> To use a <tt>JpaTraceEventMessage</tt> from <b>camel-jpa</b>
component as the <tt>TraceEventMessage</tt>. This requires that <b>camel-jpa.jar</b>
is on the classpath. </td>
</tr>
<tr>
<td class='confluenceTd'> destinationUri </td>
<td class='confluenceTd'> null </td>
<td class='confluenceTd'> Optional destination uri to route <a href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/interceptor/TraceEventExchange.html"
class="external-link" rel="nofollow">TraceEventExchange</a> containing <a href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/interceptor/TraceEventMessage.html"
class="external-link" rel="nofollow">TraceEventMessage</a> with details about the
trace. Can be used for custom processing to store traces in database using <a href="/confluence/display/CAMEL/JPA"
title="JPA">JPA</a>. </td>
</tr>
<tr>
<td class='confluenceTd'> jpaTraceEventMessageClassName </td>
<td class='confluenceTd'> null </td>
<td class='confluenceTd'> <b>Camel 2.3:</b> Fully class name for a custom
 <tt>org.apache.camel.processor.interceptor.TraceEventMessage</tt> class which
contains the traced information. For example you can use your custom JPA @Entity class to
store traced information in a database according to your schema layout. </td>
</tr>
<tr>
<td class='confluenceTd'> traceHandler </td>
<td class='confluenceTd'> null </td>
<td class='confluenceTd'> <b>Camel 2.3:</b> To use a custom <tt>org.apache.camel.processor.interceptor.TraceEventHandler</tt>
where you can control what happens when a trace event occurs. </td>
</tr>
<tr>
<td class='confluenceTd'> traceInterceptorFactory </td>
<td class='confluenceTd'> null </td>
<td class='confluenceTd'> <b>Camel 2.3:</b> To use a custom <tt>org.apache.camel.processor.interceptor.TraceInterceptorFactory</tt>
where you can create the runtime trace instance which does the actual tracing. It should be
a <tt>Processor</tt> instance. The default tracer is implemented in the class
<tt>org.apache.camel.processor.interceptor.TraceInterceptor</tt>. </td>
</tr>
</tbody></table>
</div>
</div>

<h3><a name="Tracer-Formatting"></a>Formatting</h3>
<p>The tracer formats the execution of exchanges to log lines. They are logged at INFO
level in the log category: <tt>org.apache.camel.processor.interceptor.TraceInterceptor</tt>.<br/>
The tracer uses by default the <tt>org.apache.camel.processor.interceptor.DefaultTraceFormatter</tt>
to format the log line.</p>

<p><tt>DefaultTraceFormatter</tt> has the following options:</p>
<div class="confluenceTableSmall"><div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Option </th>
<th class='confluenceTh'> Default </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> breadCrumbLength </td>
<td class='confluenceTd'> 0 </td>
<td class='confluenceTd'> Fixed length of the bread crumb. 0 = no fixed length. Setting
a value to e.g. 80 allows the tracer logs to be aligned for easier reading. </td>
</tr>
<tr>
<td class='confluenceTd'> nodeLength </td>
<td class='confluenceTd'> 0 </td>
<td class='confluenceTd'> Fixed length of the node. 0 = no fixed length. Setting a value
to e.g. 40 allows the tracer logs to be aligned for easier reading.</td>
</tr>
<tr>
<td class='confluenceTd'> showBreadCrumb </td>
<td class='confluenceTd'> true </td>
<td class='confluenceTd'> Outputs the unique unit of work for the exchange. To be used
for correlation so you can identify the same exchange. </td>
</tr>
<tr>
<td class='confluenceTd'> showNode </td>
<td class='confluenceTd'> true </td>
<td class='confluenceTd'> Previous and destination node, so you can see from -&gt;
to. </td>
</tr>
<tr>
<td class='confluenceTd'> showExchangeId </td>
<td class='confluenceTd'> false </td>
<td class='confluenceTd'> To output the unique exchange id. Currently the breadcrumb
is sufficient. </td>
</tr>
<tr>
<td class='confluenceTd'> showShortExchangeId </td>
<td class='confluenceTd'> false </td>
<td class='confluenceTd'> To output the unique exchange id in short form, without the
hostname. </td>
</tr>
<tr>
<td class='confluenceTd'> showProperties </td>
<td class='confluenceTd'> false </td>
<td class='confluenceTd'> Output the exchange properties </td>
</tr>
<tr>
<td class='confluenceTd'> showHeaders </td>
<td class='confluenceTd'> true </td>
<td class='confluenceTd'> Output the in message headers </td>
</tr>
<tr>
<td class='confluenceTd'> showBodyType </td>
<td class='confluenceTd'> true </td>
<td class='confluenceTd'> Output the in body Java type </td>
</tr>
<tr>
<td class='confluenceTd'> showBody </td>
<td class='confluenceTd'> true </td>
<td class='confluenceTd'> Output the in body </td>
</tr>
<tr>
<td class='confluenceTd'> showOutHeaders </td>
<td class='confluenceTd'> false </td>
<td class='confluenceTd'> Output the out (if any) message headers </td>
</tr>
<tr>
<td class='confluenceTd'> showOutBodyType </td>
<td class='confluenceTd'> false </td>
<td class='confluenceTd'> Output the out (if any) body Java type </td>
</tr>
<tr>
<td class='confluenceTd'> showOutBody </td>
<td class='confluenceTd'> false </td>
<td class='confluenceTd'> Output the out (if any) body </td>
</tr>
<tr>
<td class='confluenceTd'> showExchangePattern </td>
<td class='confluenceTd'> true </td>
<td class='confluenceTd'> Output the exchange pattern </td>
</tr>
<tr>
<td class='confluenceTd'> showException </td>
<td class='confluenceTd'> true </td>
<td class='confluenceTd'> Output the exception if the exchange has failed </td>
</tr>
<tr>
<td class='confluenceTd'> showRouteId </td>
<td class='confluenceTd'> true </td>
<td class='confluenceTd'> <b>Camel 2.8:</b> Output the id of the route </td>
</tr>
<tr>
<td class='confluenceTd'> maxChars </td>
<td class='confluenceTd'>&nbsp;</td>
<td class='confluenceTd'> Is used to limit the number of chars logged per line. The
default value is <tt>10000</tt> from <b>Camel 2.9</b> onwards. </td>
</tr>
</tbody></table>
</div>
</div>

<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/check.gif" width="16" height="16"
align="absmiddle" alt="" border="0"></td><td><b>Logging stream bodies</b><br
/>Camel <a href="/confluence/display/CAMEL/Tracer" title="Tracer">Tracer</a>
will by default <b>not</b> log stream or files bodies <b>from Camel 2.8
onwards</b>. You can force Camel to log those by setting the property on the <a href="/confluence/display/CAMEL/CamelContext"
title="CamelContext">CamelContext</a> properties
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
camelContext.getProperties().put(Exchange.LOG_DEBUG_BODY_STREAMS, <span class="code-keyword">true</span>);
</pre>
</div></div></td></tr></table></div>


<p>Example:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
ID-claus-acer/4412-1222625653890/2-0 -&gt; to(mock:a)                , Pattern:InOnly
, Headers:{to=James} , BodyType:<span class="code-object">String</span> , Body:Hello
London
</pre>
</div></div>

<p><tt>ID-claus-acer/3690-1214458315718/2-0</tt> is the breadcrumb with
the unique correlation id.<br/>
<tt>node3</tt> is the id of the node in the route path. Is always shown.<br/>
<tt>To[mock:a]</tt> is the destination node.<br/>
<tt>InOnly</tt> is the exchange pattern. Is always shown.<br/>
Then the rest is properties, headers and the body.</p>

<h4><a name="Tracer-Showingfromandto"></a>Showing from and to</h4>
<p>The trace log will output both the from and to so you can see where the Exchange
came from, such as:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
&gt;&gt;&gt; direct:start --&gt; process(MyProcessor)
&gt;&gt;&gt; process(MyProcessor) --&gt; to(mock:a)
&gt;&gt;&gt; to(mock:a) --&gt; to(mock:b)
</pre>
</div></div>

<h3><a name="Tracer-Enabling"></a>Enabling</h3>

<p>To enable tracer from the main run</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
java org.apache.camel.spring.Main -t
</pre>
</div></div>
<p>or </p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
java org.apache.camel.spring.Main -trace
</pre>
</div></div>

<p>and the tracer will be active.</p>

<h3><a name="Tracer-EnablingfromJavaDSL"></a>Enabling from Java DSL</h3>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
context.setTracing(<span class="code-keyword">true</span>);
</pre>
</div></div>

<p>You can configure tracing at a higher granularity as you can configure it on camel
context and then override and set it per route as well. For instance you could just enable
tracer for one particular route.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
INFO  TraceInterceptor     - ID-davsclaus-local-54403-1246038742624-0-0 &gt;&gt;&gt;
from(direct:start) --&gt; MyProcessor     , Pattern:InOnly, Headers:{to=James}, BodyType:<span
class="code-object">String</span>, Body:Hello London
INFO  TraceInterceptor     - ID-davsclaus-local-54403-1246038742624-0-0 &gt;&gt;&gt;
MyProcessor --&gt; mock:a                 , Pattern:InOnly, Headers:{to=James}, BodyType:<span
class="code-object">String</span>, Body:Hello London
INFO  TraceInterceptor     - ID-davsclaus-local-54403-1246038742624-0-0 &gt;&gt;&gt;
mock:a --&gt; mock:b                      , Pattern:InOnly, Headers:{to=James}, BodyType:<span
class="code-object">String</span>, Body:Hello London
...
INFO  TraceInterceptor     - ID-davsclaus-local-54403-1246038742624-0-1 &gt;&gt;&gt;
from(direct:start) --&gt; MyProcessor     , Pattern:InOnly, Headers:{from=Claus}, BodyType:<span
class="code-object">String</span>, Body:This is Copenhagen calling
INFO  TraceInterceptor     - ID-davsclaus-local-54403-1246038742624-0-1 &gt;&gt;&gt;
MyProcessor --&gt; mock:a                 , Pattern:InOnly, Headers:{from=Claus}, BodyType:<span
class="code-object">String</span>, Body:This is Copenhagen calling
INFO  TraceInterceptor     - ID-davsclaus-local-54403-1246038742624-0-1 &gt;&gt;&gt;
mock:a --&gt; mock:b                      , Pattern:InOnly, Headers:{from=Claus}, BodyType:<span
class="code-object">String</span>, Body:This is Copenhagen calling
</pre>
</div></div>

<h3><a name="Tracer-ConfiguringfromJavaDSL"></a>Configuring from Java DSL</h3>
<p>The tracer options can be configured from the Java DSL like this:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
    <span class="code-keyword">public</span> void configure() <span class="code-keyword">throws</span>
Exception {
        <span class="code-comment">// add tracer as an interceptor so it will log the
exchange executions at runtime
</span>        <span class="code-comment">// <span class="code-keyword">this</span>
can aid us to understand/see how the exchanges is routed etc.
</span>        Tracer tracer = <span class="code-keyword">new</span> Tracer();
        formatter.getDefaultTraceFormatter().setShowBreadCrumb(<span class="code-keyword">false</span>);
        formatter.getDefaultTraceFormatter().setShowNode(<span class="code-keyword">false</span>);
        ...
        getContext().addInterceptStrategy(tracer);
</pre>
</div></div>

<h4><a name="Tracer-Usingpredicatestofilterexchanges"></a>Using predicates
to filter exchanges</h4>
<p>In the code below we want the tracer only to trace if the body contains the text
<tt>London</tt>. As this is just an example can of course set any <a href="/confluence/display/CAMEL/Predicate"
title="Predicate">Predicate</a> that matches your criteria:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
    Tracer tracer = <span class="code-keyword">new</span> Tracer();
    <span class="code-comment">// set the level to FATAL so we can easily spot it
</span>    tracer.setLogLevel(LoggingLevel.FATAL);
    <span class="code-comment">// and only trace <span class="code-keyword">if</span>
the body contains London as text
</span>    tracer.setTraceFilter(body().contains(constant(<span class="code-quote">"London"</span>)));
</pre>
</div></div>

<h3><a name="Tracer-EnablingfromSpringXML"></a>Enabling from Spring XML</h3>

<p>There is now a <b>trace</b> attribute you can specify on the *&lt;camelContext/&gt;
for example</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
  &lt;camelContext trace=<span class="code-quote">"<span class="code-keyword">true</span>"</span>
xmlns=<span class="code-quote">"http:<span class="code-comment">//activemq.apache.org/camel/schema/spring"</span>&gt;
</span>    ...
  &lt;/camelContext&gt;
</pre>
</div></div>

<p>You can see this in action with the <a href="http://svn.apache.org/repos/asf/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringTraceTest.java"
class="external-link" rel="nofollow">SpringTraceTest</a> and its <a href="http://svn.apache.org/repos/asf/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringTraceTest-context.xml"
class="external-link" rel="nofollow">spring.xml file</a></p>

<p>Another option is to just include a spring XML which defines the Tracer bean such
as the <a href="http://svn.apache.org/repos/asf/camel/trunk/components/camel-spring/src/main/resources/META-INF/services/org/apache/camel/spring/trace.xml"
class="external-link" rel="nofollow">one that is automatically included if you run the
Main with -t above</a>.</p>

<h3><a name="Tracer-ConfigurationfromSpring"></a>Configuration from Spring</h3>
<p>You can configure the tracer as a Spring bean. Just add a bean with the bean class
<tt>org.apache.camel.processor.interceptor.Tracer</tt> and Camel will use it as
the Tracer.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml"><span class="code-tag"><span class="code-comment">&lt;!--
we can configure the tracer by defining the tracer bean and set the properties as we like
--&gt;</span></span>
<span class="code-tag"><span class="code-comment">&lt;!-- the id name can
be anything its the class that must be org.apache.camel.processor.interceptor.Tracer --&gt;</span></span>
<span class="code-tag">&lt;bean id=<span class="code-quote">"camelTracer"</span>
class=<span class="code-quote">"org.apache.camel.processor.interceptor.Tracer"</span>&gt;</span>
    <span class="code-tag">&lt;property name=<span class="code-quote">"traceExceptions"</span>
value=<span class="code-quote">"false"</span>/&gt;</span>
    <span class="code-tag">&lt;property name=<span class="code-quote">"traceInterceptors"</span>
value=<span class="code-quote">"true"</span>/&gt;</span>
    <span class="code-tag">&lt;property name=<span class="code-quote">"logLevel"</span>
value=<span class="code-quote">"ERROR"</span>/&gt;</span>
    <span class="code-tag">&lt;property name=<span class="code-quote">"logName"</span>
value=<span class="code-quote">"com.mycompany.messages"</span>/&gt;</span>
<span class="code-tag">&lt;/bean&gt;</span>

<span class="code-tag">&lt;camelContext trace=<span class="code-quote">"true"</span>
xmlns=<span class="code-quote">"http://camel.apache.org/schema/spring"</span>&gt;</span>
    <span class="code-tag">&lt;route&gt;</span>
        <span class="code-tag">&lt;from uri=<span class="code-quote">"direct:start"</span>/&gt;</span>
        <span class="code-tag">&lt;to uri=<span class="code-quote">"mock:result"</span>/&gt;</span>
    <span class="code-tag">&lt;/route&gt;</span>
<span class="code-tag">&lt;/camelContext&gt;</span>
</pre>
</div></div>

<p>You can configure the formatting of tracer as a Spring bean. Just add a bean with
the id <b>traceFormatter</b> and Camel will lookup this id and use the formatter,
as the example below illustrates:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml"><span class="code-tag">&lt;bean id=<span class="code-quote">"traceFormatter"</span>
class=<span class="code-quote">"org.apache.camel.processor.interceptor.DefaultTraceFormatter"</span>&gt;</span>
    <span class="code-tag">&lt;property name=<span class="code-quote">"showBody"</span>
value=<span class="code-quote">"true"</span>/&gt;</span>
    <span class="code-tag">&lt;property name=<span class="code-quote">"showBodyType"</span>
value=<span class="code-quote">"false"</span>/&gt;</span>
    <span class="code-tag">&lt;property name=<span class="code-quote">"showBreadCrumb"</span>
value=<span class="code-quote">"false"</span>/&gt;</span>
    <span class="code-tag">&lt;property name=<span class="code-quote">"maxChars"</span>
value=<span class="code-quote">"100"</span>/&gt;</span>
<span class="code-tag">&lt;/bean&gt;</span>

<span class="code-tag">&lt;camelContext trace=<span class="code-quote">"true"</span>
xmlns=<span class="code-quote">"http://camel.apache.org/schema/spring"</span>&gt;</span>
    <span class="code-tag">&lt;route&gt;</span>
        <span class="code-tag">&lt;from uri=<span class="code-quote">"direct:start"</span>/&gt;</span>
        <span class="code-tag">&lt;to uri=<span class="code-quote">"mock:result"</span>/&gt;</span>
    <span class="code-tag">&lt;/route&gt;</span>
<span class="code-tag">&lt;/camelContext&gt;</span>
</pre>
</div></div>

<h3><a name="Tracer-Enabletracingofoutmessages"></a>Enable tracing of out
messages</h3>

<p>You can trace messages coming out of processing steps. To enable this, configure
the tracer as follows</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>Java DSL</b></div><div class="codeContent
panelContent">
<pre class="code-java">Tracer tracer = <span class="code-keyword">new</span>
Tracer();
tracer.setTraceOutExchanges(<span class="code-keyword">true</span>);

<span class="code-comment">// we configure the <span class="code-keyword">default</span>
trace formatter where we can
</span><span class="code-comment">// specify which fields we want in the output
</span>DefaultTraceFormatter formatter = <span class="code-keyword">new</span>
DefaultTraceFormatter();
formatter.setShowOutBody(<span class="code-keyword">true</span>);
formatter.setShowOutBodyType(<span class="code-keyword">true</span>);

<span class="code-comment">// set to use our formatter
</span>tracer.setFormatter(formatter);

getContext().addInterceptStrategy(tracer);
</pre>
</div></div>
<p>or</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>Spring DSL</b></div><div class="codeContent
panelContent">
<pre class="code-xml"><span class="code-tag">&lt;bean id=<span class="code-quote">"camelTracer"</span>
class=<span class="code-quote">"org.apache.camel.processor.interceptor.Tracer"</span>&gt;</span>
  <span class="code-tag">&lt;property name=<span class="code-quote">"traceOutExchanges"</span>
value=<span class="code-quote">"true"</span> /&gt;</span>
<span class="code-tag">&lt;/bean&gt;</span>

<span class="code-tag">&lt;bean id=<span class="code-quote">"traceFormatter"</span>
class=<span class="code-quote">"org.apache.camel.processor.interceptor.DefaultTraceFormatter"</span>&gt;</span>
  <span class="code-tag">&lt;property name=<span class="code-quote">"showOutBody"</span>
value=<span class="code-quote">"true"</span> /&gt;</span>
  <span class="code-tag">&lt;property name=<span class="code-quote">"showOutBodyType"</span>
value=<span class="code-quote">"true"</span> /&gt;</span>
<span class="code-tag">&lt;/bean&gt;</span>
</pre>
</div></div>

<p>Running with these options, you'll get output similar to:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
INFO  TraceInterceptor - ID-mojo/59899-1225474989226/2-0 -&gt; transform(body) , Pattern:InOnly
, Headers:{to=James} , BodyType:<span class="code-object">String</span> , Body:Hello
London
INFO  TraceInterceptor - transform(body) -&gt; ID-mojo/59899-1225474989226/2-0 , Pattern:InOnly
, Headers:{to=James} , BodyType:<span class="code-object">String</span> , Body:Hello
London , OutBodyType:<span class="code-object">String</span> , OutBody:Hello London
</pre>
</div></div>

<h3><a name="Tracer-UsingCustomFormatter"></a>Using Custom Formatter</h3>

<p>You can now implement your own <tt>org.apache.camel.processor.interceptor.TraceFormatter</tt>
to be used for logging trace messages to the log. </p>

<p>The sample below shows how to configure a Tracer from Java DSL using custom formatter:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"><span class="code-comment">// we create a tracer where
we want to use our own formatter instead of the <span class="code-keyword">default</span>
one
</span>Tracer tracer = <span class="code-keyword">new</span> Tracer();

<span class="code-comment">// use our own formatter instead of the <span class="code-keyword">default</span>
one
</span>MyTraceFormatter formatter = <span class="code-keyword">new</span>
MyTraceFormatter();
tracer.setFormatter(formatter);

<span class="code-comment">// and we must remeber to add the tracer to Camel
</span>getContext().addInterceptStrategy(tracer);
</pre>
</div></div>

<p>And here we have our custom logger that implements the <tt>TraceFormatter</tt>
interface where we can construct the log message how we like:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"><span class="code-comment">// here we have out own formatter
where we can create the output we want <span class="code-keyword">for</span> trace
logs
</span><span class="code-comment">// as <span class="code-keyword">this</span>
is a test we just create a simple string with * around the body
</span>class MyTraceFormatter <span class="code-keyword">implements</span>
TraceFormatter {

    <span class="code-keyword">public</span> <span class="code-object">Object</span>
format(TraceInterceptor interceptor, ProcessorDefinition&lt;?&gt; node, Exchange exchange)
{
        <span class="code-keyword">return</span> <span class="code-quote">"***"</span>
+ exchange.getIn().getBody(<span class="code-object">String</span>.class) + <span
class="code-quote">"***"</span>;
    }
}
</pre>
</div></div>

<h3><a name="Tracer-UsingDestinationforcustomprocessingandrouting"></a>Using
Destination for custom processing and routing</h3>

<p>Tracer supports custom processing of trace events. This can be used to route a trace
event to a <a href="/confluence/display/CAMEL/JPA" title="JPA">JPA</a> endpoint
for persistence in a database.</p>

<p>This works by Camel creates a new <a href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/interceptor/TraceEventExchange.html"
class="external-link" rel="nofollow">TraceEventExchange</a> containing:</p>
<ul class="alternate" type="square">
	<li>snapshot of the original traced Exchange as a immutable <a href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/interceptor/TraceEventMessage.html"
class="external-link" rel="nofollow">TraceEventMessage</a> containing String values
of the fields, when the interception occurred. This ensures the fields contains the exact
data at the given time of interception.</li>
	<li>the original Exchange can be accessed using <tt>getTracedExchange()</tt></li>
</ul>


<div class='panelMacro'><table class='warningMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/forbidden.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td>Beware to access the
original Exchange to avoid causing any side effects or alter its state. Prefer to access the
information from <a href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/interceptor/TraceEventMessage.html"
class="external-link" rel="nofollow">TraceEventMessage</a></td></tr></table></div>

<p>Camel routes the TraceEventExchange synchronously from the point of interception.
When its completed Camel will continue routing the original Exchange.</p>

<p>The sample below demonstrates this feature, where we route traced Exchanges to the
<tt>direct:traced</tt> route:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"><span class="code-comment">// we create a tracer where
we want to send TraveEvents to an endpoint
</span><span class="code-comment">// <span class="code-quote">"direct:traced"</span>
where we can <span class="code-keyword">do</span> some custom processing such
as storing
</span><span class="code-comment">// it in a file or a database
</span>Tracer tracer = <span class="code-keyword">new</span> Tracer();
tracer.setDestinationUri(<span class="code-quote">"direct:traced"</span>);
<span class="code-comment">// we disable regular trace logging in the log file. You
can omit <span class="code-keyword">this</span> and
</span><span class="code-comment">// have both.
</span>tracer.setLogLevel(LoggingLevel.OFF);
<span class="code-comment">// and we must remember to add the tracer to Camel
</span>getContext().addInterceptStrategy(tracer);
</pre>
</div></div>

<p>Then we can configure a route for the traced messages:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
   from(<span class="code-quote">"direct:traced"</span>).process(<span class="code-keyword">new</span>
MyTraceMessageProcessor()).to("file:<span class="code-comment">//myapp/logs/trace);</span>
</pre>
</div></div>

<p>And our processor where we can process the TraceEventMessage. Here we want to create
a CSV format of the trace event to be stored as a file. We do this by constructing the CSV
String and the replace the IN body with our String instead of the <tt>TraceEventMessage</tt>.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">class MyTraceMessageProcessor <span class="code-keyword">implements</span>
Processor {

    <span class="code-keyword">public</span> void process(Exchange exchange) <span
class="code-keyword">throws</span> Exception {
        <span class="code-comment">// here we can transform the message how we like
want it
</span>        TraceEventMessage msg = exchange.getIn().getBody(DefaultTraceEventMessage.class);

        <span class="code-comment">// we want to store it as a CSV with from;to;exchangeId;body
</span>        <span class="code-object">String</span> s = msg.getFromEndpointUri()
+ <span class="code-quote">";"</span> + msg.getToNode() + <span class="code-quote">";"</span>
+ msg.getExchangeId() + <span class="code-quote">";"</span> + msg.getBody();

        <span class="code-comment">// so we replace the IN body with our CSV string
</span>        exchange.getIn().setBody(s);
    }
}
</pre>
</div></div>

<h3><a name="Tracer-UsingJPAasdatastorefortracemessages"></a>Using <a
href="/confluence/display/CAMEL/JPA" title="JPA">JPA</a> as datastore for trace messages</h3>

<p>See <a href="/confluence/display/CAMEL/Tracer+Example" title="Tracer Example">Tracer
Example</a> for complete documentation and how to use this feature.</p>

<h3><a name="Tracer-Tracedroutepathduringruntime"></a>Traced route path
during runtime</h3>

<p><a href="/confluence/display/CAMEL/Tracer" title="Tracer">Tracer</a>
also traces the actual route path taken during runtime. Camel will store the route path taken
on the UnitOfWork when <a href="/confluence/display/CAMEL/Tracer" title="Tracer">Tracer</a>
is enabled. </p>

<p>The example below demonstrates how we can use that for error handling where we can
determine at which node in the route graph the error triggered.<br/>
First we define our route:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">protected</span> RouteBuilder
createRouteBuilder() <span class="code-keyword">throws</span> Exception {
    <span class="code-keyword">return</span> <span class="code-keyword">new</span>
RouteBuilder() {
        <span class="code-keyword">public</span> void configure() <span class="code-keyword">throws</span>
Exception {
            errorHandler(deadLetterChannel(<span class="code-quote">"mock:error"</span>).redeliveryDelay(0).maximumRedeliveries(3));

            <span class="code-comment">// must enable tracer to trace the route path
taken during runtime
</span>            context.setTracing(<span class="code-keyword">true</span>);

            <span class="code-comment">// let our my error processor handle all exceptions
</span>            onException(Exception.class).handled(<span class="code-keyword">true</span>).process(<span
class="code-keyword">new</span> MyErrorProcessor());

            <span class="code-comment">// our route where an exception can be thrown
from either foo or bar bean
</span>            <span class="code-comment">// so we have enable tracing so
we can check it at runtime to get the actual
</span>            <span class="code-comment">// node path taken
</span>            from(<span class="code-quote">"direct:start"</span>).to(<span
class="code-quote">"bean:foo"</span>).to(<span class="code-quote">"bean:bar"</span>);
        }
    };
}
</pre>
</div></div>

<p>And then our custom error processor where we can handle the exception and figure
out at which node the exception occurred.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">private</span> <span
class="code-keyword">static</span> class MyErrorProcessor <span class="code-keyword">implements</span>
Processor {
    <span class="code-keyword">public</span> void process(Exchange exchange) <span
class="code-keyword">throws</span> Exception {
        TracedRouteNodes traced = exchange.getUnitOfWork().getTracedRouteNodes();

        <span class="code-comment">// get the list of intercepted nodes
</span>        List&lt;RouteNode&gt; list = traced.getNodes();
        <span class="code-comment">// get the 3rd last as its the bean
</span>        Processor last = list.get(list.size() - 3).getProcessor();

        <span class="code-comment">// wrapped by JMX
</span>        <span class="code-keyword">if</span> (last <span class="code-keyword">instanceof</span>
InstrumentationProcessor) {
            InstrumentationProcessor ip = (InstrumentationProcessor) last;
            last = ip.getProcessor();
        }

        <span class="code-comment">// set error message
</span>        exchange.getOut().setFault(<span class="code-keyword">true</span>);
        exchange.getOut().setBody(<span class="code-quote">"Failed at: "</span>
+ last.toString());
    }

    <span class="code-keyword">public</span> <span class="code-object">String</span>
toString() {
        <span class="code-keyword">return</span> <span class="code-quote">"MyErrorProcessor"</span>;
    }
}
</pre>
</div></div>

<h3><a name="Tracer-SeeAlso"></a>See Also</h3>
<ul class="alternate" type="square">
	<li><a href="/confluence/display/CAMEL/Tracer+Example" title="Tracer Example">Tracer
Example</a></li>
	<li><a href="/confluence/display/CAMEL/Debugger" title="Debugger">Debugger</a></li>
	<li><a href="/confluence/display/CAMEL/Delay+Interceptor" title="Delay Interceptor">Delay
Interceptor</a></li>
	<li><a href="/confluence/display/CAMEL/Log" title="Log">Log</a></li>
</ul>

    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/Tracer">View Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=89192&revisedVersion=46&originalVersion=45">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/Tracer?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message