This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch sandbox/camel-3.x
in repository https://gitbox.apache.org/repos/asf/camel.git
commit cec9ef0e6bf4d7ef40d46495dd67723977ba7d28
Author: Guillaume Nodet <gnodet@gmail.com>
AuthorDate: Thu Nov 22 16:02:37 2018 +0100
Fix camel-aws-xray for async engine
---
.../org/apache/camel/reifier/WireTapReifier.java | 2 +-
.../camel/component/aws/xray/XRayTracer.java | 127 +++++++++------------
.../camel/component/aws/xray/ABCRouteTest.java | 11 +-
.../aws/xray/ComprehensiveTrackingTest.java | 22 ++--
.../component/aws/xray/CustomComponentTest.java | 5 +-
.../aws/xray/SpringAwsXRaySimpleRouteTest.java | 25 ++--
.../camel/component/aws/xray/TwoService2Test.java | 7 +-
.../camel/component/aws/xray/TwoServiceTest.java | 5 +-
.../src/test/resources/log4j2.properties | 39 +++++++
9 files changed, 128 insertions(+), 115 deletions(-)
diff --git a/camel-core/src/main/java/org/apache/camel/reifier/WireTapReifier.java b/camel-core/src/main/java/org/apache/camel/reifier/WireTapReifier.java
index f60f31a..4a37801 100644
--- a/camel-core/src/main/java/org/apache/camel/reifier/WireTapReifier.java
+++ b/camel-core/src/main/java/org/apache/camel/reifier/WireTapReifier.java
@@ -57,7 +57,7 @@ class WireTapReifier extends ToDynamicReifier<WireTapDefinition<?>>
{
CamelInternalProcessor internal = new CamelInternalProcessor(target);
internal.addAdvice(new CamelInternalProcessor.UnitOfWorkProcessorAdvice(routeContext));
- // is true bt default
+ // is true by default
boolean isCopy = definition.getCopy() == null || definition.getCopy();
WireTapProcessor answer = new WireTapProcessor(dynamicTo, internal, definition.getPattern(),
threadPool, shutdownThreadPool, definition.isDynamic());
diff --git a/components/camel-aws-xray/src/main/java/org/apache/camel/component/aws/xray/XRayTracer.java
b/components/camel-aws-xray/src/main/java/org/apache/camel/component/aws/xray/XRayTracer.java
index af584d9..20c118b 100644
--- a/components/camel-aws-xray/src/main/java/org/apache/camel/component/aws/xray/XRayTracer.java
+++ b/components/camel-aws-xray/src/main/java/org/apache/camel/component/aws/xray/XRayTracer.java
@@ -16,18 +16,15 @@
*/
package org.apache.camel.component.aws.xray;
-import java.lang.invoke.MethodHandles;
import java.net.URI;
-import java.util.EventObject;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
-import java.util.Optional;
+import java.util.Objects;
import java.util.ServiceLoader;
import java.util.Set;
import com.amazonaws.xray.AWSXRay;
-import com.amazonaws.xray.AWSXRayRecorder;
import com.amazonaws.xray.entities.Entity;
import com.amazonaws.xray.entities.Segment;
import com.amazonaws.xray.entities.Subsegment;
@@ -79,7 +76,6 @@ public class XRayTracer extends ServiceSupport implements RoutePolicyFactory,
St
// Note that the Entity itself is not serializable, so don't share this object among
different VMs!
public static final String XRAY_TRACE_ENTITY = "Camel-AWS-XRay-Trace-Entity";
- private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static Map<String, SegmentDecorator> decorators = new HashMap<>();
@@ -98,7 +94,8 @@ public class XRayTracer extends ServiceSupport implements RoutePolicyFactory,
St
// Add segment decorator only if no existing decorator for the component exists
yet or if we have have a
// derived one. This allows custom decorators to be added if they extend the
standard decorators
if (existing == null || existing.getClass().isInstance(d)) {
- LOG.trace("Adding segment decorator {}", d.getComponent());
+ Logger log = LoggerFactory.getLogger(XRayTracer.class);
+ log.trace("Adding segment decorator {}", d.getComponent());
decorators.put(d.getComponent(), d);
}
});
@@ -130,13 +127,13 @@ public class XRayTracer extends ServiceSupport implements RoutePolicyFactory,
St
}
if (null == tracingStrategy) {
- LOG.info("No tracing strategy available. Defaulting to no-op strategy");
+ log.info("No tracing strategy available. Defaulting to no-op strategy");
tracingStrategy = new NoopTracingStrategy();
}
camelContext.addInterceptStrategy(tracingStrategy);
- LOG.debug("Starting XRay tracer");
+ log.debug("Starting XRay tracer");
}
@Override
@@ -146,7 +143,7 @@ public class XRayTracer extends ServiceSupport implements RoutePolicyFactory,
St
ServiceHelper.stopAndShutdownService(eventNotifier);
camelContext.getRoutePolicyFactories().remove(this);
- LOG.debug("XRay tracer stopped");
+ log.debug("XRay tracer stopped");
}
/**
@@ -157,7 +154,7 @@ public class XRayTracer extends ServiceSupport implements RoutePolicyFactory,
St
public void init(CamelContext camelContext) {
if (!camelContext.hasService(this)) {
try {
- LOG.debug("Initializing XRay tracer");
+ log.debug("Initializing XRay tracer");
// start this service eager so we init before Camel is starting up
camelContext.addService(this, true, true);
} catch (Exception e) {
@@ -220,7 +217,7 @@ public class XRayTracer extends ServiceSupport implements RoutePolicyFactory,
St
if (!excludePatterns.isEmpty()) {
for (String pattern : excludePatterns) {
if (pattern.equals(routeId)) {
- LOG.debug("Ignoring route with ID {}", routeId);
+ log.debug("Ignoring route with ID {}", routeId);
return true;
}
}
@@ -236,6 +233,14 @@ public class XRayTracer extends ServiceSupport implements RoutePolicyFactory,
St
return sd;
}
+ protected Entity getTraceEntityFromExchange(Exchange exchange) {
+ Entity entity = exchange.getIn().getHeader(XRAY_TRACE_ENTITY, Entity.class);
+ if (entity == null) {
+ entity = (Entity) exchange.getProperty(CURRENT_SEGMENT);
+ }
+ return entity;
+ }
+
/**
* Custom camel event handler that will create a new {@link Subsegment XRay subsegment}
in case
* the current exchange is forwarded via <code>.to(someEndpoint)</code> to
some endpoint and
@@ -264,32 +269,28 @@ public class XRayTracer extends ServiceSupport implements RoutePolicyFactory,
St
event.getClass().getSimpleName(), ese.getEndpoint(),
ese.getExchange().getFromRouteId());
- if (Thread.currentThread().getName().contains("Multicast")) {
- // copy the segment from the exchange to the thread (local) context
- Segment segment = (Segment) ese.getExchange().getProperty(CURRENT_SEGMENT);
- log.trace("Copying over segment {}/{} from exchange received from {}
to exchange processing {}",
- segment.getId(), segment.getName(), ese.getExchange().getFromEndpoint(),
- ese.getEndpoint());
- AWSXRay.setTraceEntity(segment);
- }
-
SegmentDecorator sd = getSegmentDecorator(ese.getEndpoint());
if (!sd.newSegment()) {
return;
}
- if (AWSXRay.getCurrentSegmentOptional().isPresent()) {
+ Entity entity = getTraceEntityFromExchange(ese.getExchange());
+ if (entity != null) {
+ AWSXRay.setTraceEntity(entity);
// AWS XRay does only allow a certain set of characters to appear within
a name
// Allowed characters: a-z, A-Z, 0-9, _, ., :, /, %, &, #, =, +,
\, -, @
String name = sd.getOperationName(ese.getExchange(), ese.getEndpoint());
if (sd.getComponent() != null) {
name = sd.getComponent() + ":" + name;
}
+ name = sanitizeName(name);
try {
- Subsegment subsegment = AWSXRay.beginSubsegment(sanitizeName(name));
+ Subsegment subsegment = AWSXRay.beginSubsegment(name);
sd.pre(subsegment, ese.getExchange(), ese.getEndpoint());
- log.trace("Creating new subsegment with ID {} and name {}",
- subsegment.getId(), subsegment.getName());
+ log.trace("Creating new subsegment with ID {} and name {} (parent
{}, references: {})",
+ subsegment.getId(), subsegment.getName(),
+ subsegment.getParentSegment().getId(), subsegment.getParentSegment().getReferenceCount());
+ ese.getExchange().setProperty(CURRENT_SEGMENT, subsegment);
} catch (AlreadyEmittedException aeEx) {
log.warn("Ignoring starting of subsegment " + name + " as its parent
segment"
+ " was already emitted to AWS.");
@@ -303,18 +304,20 @@ public class XRayTracer extends ServiceSupport implements RoutePolicyFactory,
St
log.trace("-> {} - target: {} (routeId: {})",
event.getClass().getSimpleName(), ese.getEndpoint(), ese.getExchange().getFromRouteId());
- SegmentDecorator sd = getSegmentDecorator(ese.getEndpoint());
-
- if (AWSXRay.getCurrentSubsegmentOptional().isPresent()) {
- String name = sd.getOperationName(ese.getExchange(), ese.getEndpoint());
+ Entity entity = getTraceEntityFromExchange(ese.getExchange());
+ if (entity instanceof Subsegment) {
+ AWSXRay.setTraceEntity(entity);
+ SegmentDecorator sd = getSegmentDecorator(ese.getEndpoint());
try {
- Subsegment subsegment = AWSXRay.getCurrentSubsegment();
+ Subsegment subsegment = (Subsegment) entity;
sd.post(subsegment, ese.getExchange(), ese.getEndpoint());
subsegment.close();
log.trace("Closing down subsegment with ID {} and name {}",
subsegment.getId(), subsegment.getName());
+ log.trace("Setting trace entity for exchange {} to {}", ese.getExchange(),
subsegment.getParent());
+ ese.getExchange().setProperty(CURRENT_SEGMENT, subsegment.getParent());
} catch (AlreadyEmittedException aeEx) {
- log.warn("Ignoring close of subsegment " + name
+ log.warn("Ignoring close of subsegment " + entity.getName()
+ " as its parent segment was already emitted to AWS");
}
}
@@ -368,6 +371,9 @@ public class XRayTracer extends ServiceSupport implements RoutePolicyFactory,
St
log.trace("=> RoutePolicy-Begin: Route: {} - RouteId: {}", routeId, route.getId());
+ Entity entity = getTraceEntityFromExchange(exchange);
+ boolean createSegment = (entity == null || !Objects.equals(entity.getName(),
routeId));
+
TraceID traceID;
if (exchange.getIn().getHeaders().containsKey(XRAY_TRACE_ID)) {
traceID = TraceID.fromString(exchange.getIn().getHeader(XRAY_TRACE_ID, String.class));
@@ -376,41 +382,25 @@ public class XRayTracer extends ServiceSupport implements RoutePolicyFactory,
St
exchange.getIn().setHeader(XRAY_TRACE_ID, traceID.toString());
}
- // copy over any available trace entity (i.e. Segment) from the old thread to
the new one
- // according to AWS XRay documentation on multithreading:
-
- // https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java-multithreading.html
- //
- // > If you use multiple threads to handle incoming requests, you can pass
the current segment or subsegment
- // > to the new thread and provide it to the global recorder. This ensures
that the information recorded
- // > within the new thread is associated with the same segment as the rest
of the information recorded about
- // > that request.
- Entity entity = null;
- if (exchange.getIn().getHeaders().containsKey(XRAY_TRACE_ENTITY)) {
- entity = exchange.getIn().getHeader(XRAY_TRACE_ENTITY, Entity.class);
- }
-
- if (null != entity) {
- AWSXRayRecorder recorder = AWSXRay.getGlobalRecorder();
- recorder.setTraceEntity(entity);
- }
+ AWSXRay.setTraceEntity(entity);
SegmentDecorator sd = getSegmentDecorator(route.getEndpoint());
- Optional<Segment> curSegment = AWSXRay.getCurrentSegmentOptional();
- if (!curSegment.isPresent()) {
+ if (createSegment) {
Segment segment = AWSXRay.beginSegment(sanitizeName(route.getId()));
+ segment.setParent(entity);
segment.setTraceId(traceID);
sd.pre(segment, exchange, route.getEndpoint());
- log.trace("Created new XRay segment {} with name {}",
- segment.getId(), segment.getName());
+ log.trace("Created new XRay segment {} with name {}", segment.getId(), segment.getName());
exchange.setProperty(CURRENT_SEGMENT, segment);
} else {
- String segmentName = curSegment.get().getId();
+ String segmentName = entity.getId();
try {
Subsegment subsegment = AWSXRay.beginSubsegment(route.getId());
sd.pre(subsegment, exchange, route.getEndpoint());
- log.trace("Created new XRay subsegment {} with name {}",
- subsegment.getId(), subsegment.getName());
+ log.trace("Creating new subsegment with ID {} and name {} (parent {},
references: {})",
+ subsegment.getId(), subsegment.getName(),
+ subsegment.getParentSegment().getId(), subsegment.getParentSegment().getReferenceCount());
+ exchange.setProperty(CURRENT_SEGMENT, subsegment);
} catch (AlreadyEmittedException aeEx) {
log.warn("Ignoring opening of subsegment " + route.getId() + " as its
parent segment "
+ segmentName + " was already emitted before.");
@@ -427,25 +417,22 @@ public class XRayTracer extends ServiceSupport implements RoutePolicyFactory,
St
log.trace("=> RoutePolicy-Done: Route: {} - RouteId: {}", routeId, route.getId());
+ Entity entity = getTraceEntityFromExchange(exchange);
+ AWSXRay.setTraceEntity(entity);
try {
SegmentDecorator sd = getSegmentDecorator(route.getEndpoint());
- Optional<Segment> curSegment = AWSXRay.getCurrentSegmentOptional();
- Optional<Subsegment> curSubSegment = AWSXRay.getCurrentSubsegmentOptional();
- if (curSubSegment.isPresent()) {
- Subsegment subsegment = curSubSegment.get();
- sd.post(subsegment, exchange, route.getEndpoint());
- subsegment.close();
- log.trace("Closing down Subsegment {} with name {}",
- subsegment.getId(), subsegment.getName());
- } else if (curSegment.isPresent()) {
- Segment segment = curSegment.get();
- sd.post(segment, exchange, route.getEndpoint());
- segment.close();
- log.trace("Closing down Segment {} with name {}",
- segment.getId(), segment.getName());
- }
+ sd.post(entity, exchange, route.getEndpoint());
+ entity.close();
+ log.trace("Closing down (sub)segment {} with name {} (parent {}, references:
{})",
+ entity.getId(), entity.getName(),
+ entity.getParentSegment().getId(), entity.getParentSegment().getReferenceCount());
+ exchange.setProperty(CURRENT_SEGMENT, entity.getParent());
} catch (AlreadyEmittedException aeEx) {
log.warn("Ignoring closing of (sub)segment {} as the segment was already
emitted.", route.getId());
+ } catch (Exception e) {
+ log.warn("Error closing entity");
+ } finally {
+ AWSXRay.setTraceEntity(null);
}
}
diff --git a/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/ABCRouteTest.java
b/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/ABCRouteTest.java
index bbc1d89..04b99dc 100644
--- a/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/ABCRouteTest.java
+++ b/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/ABCRouteTest.java
@@ -31,12 +31,11 @@ public class ABCRouteTest extends CamelAwsXRayTestSupport {
super(
TestDataBuilder.createTrace().inRandomOrder()
.withSegment(TestDataBuilder.createSegment("start")
- .withSubsegment(TestDataBuilder.createSubsegment("direct:a")
- .withSubsegment(TestDataBuilder.createSubsegment("a")
- .withSubsegment(TestDataBuilder.createSubsegment("seda:b"))
- .withSubsegment(TestDataBuilder.createSubsegment("seda:c"))
- )
- )
+ .withSubsegment(TestDataBuilder.createSubsegment("direct:a"))
+ )
+ .withSegment(TestDataBuilder.createSegment("a")
+ .withSubsegment(TestDataBuilder.createSubsegment("seda:b"))
+ .withSubsegment(TestDataBuilder.createSubsegment("seda:c"))
)
.withSegment(TestDataBuilder.createSegment("b"))
.withSegment(TestDataBuilder.createSegment("c")
diff --git a/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/ComprehensiveTrackingTest.java
b/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/ComprehensiveTrackingTest.java
index 8d02ee2..8a8843c 100644
--- a/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/ComprehensiveTrackingTest.java
+++ b/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/ComprehensiveTrackingTest.java
@@ -34,17 +34,15 @@ public class ComprehensiveTrackingTest extends CamelAwsXRayTestSupport
{
public ComprehensiveTrackingTest() {
super(
TestDataBuilder.createTrace().inRandomOrder()
- .withSegment(TestDataBuilder.createSegment("start")
- .withSubsegment(TestDataBuilder.createSubsegment("direct:a")
- .withSubsegment(TestDataBuilder.createSubsegment("a")
- .withSubsegment(TestDataBuilder.createSubsegment("seda:b"))
- .withSubsegment(TestDataBuilder.createSubsegment("seda:c"))
- // note that the subsegment name matches
the routeId
- .withSubsegment(TestDataBuilder.createSubsegment("test"))
- // no tracing of the invoke checker bean
as it wasn't annotated with
- // @XRayTrace
- )
- )
+ .withSegment(TestDataBuilder.createSegment("start").inRandomOrder()
+ .withSubsegment(TestDataBuilder.createSubsegment("seda:d"))
+ .withSubsegment(TestDataBuilder.createSubsegment("direct:a"))
+ )
+ .withSegment(TestDataBuilder.createSegment("a")
+ .withSubsegment(TestDataBuilder.createSubsegment("seda:b"))
+ .withSubsegment(TestDataBuilder.createSubsegment("seda:c"))
+ // no tracing of the invoke checker bean as it wasn't annotated
with
+ // @XRayTrace
)
.withSegment(TestDataBuilder.createSegment("b"))
.withSegment(TestDataBuilder.createSegment("c")
@@ -52,7 +50,7 @@ public class ComprehensiveTrackingTest extends CamelAwsXRayTestSupport {
//.withSubsegment(TestDataBuilder.createSubsegment("log:test"))
)
.withSegment(TestDataBuilder.createSegment("d"))
- // note no test-segment here!
+ .withSegment(TestDataBuilder.createSegment("test"))
);
}
diff --git a/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/CustomComponentTest.java
b/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/CustomComponentTest.java
index ec2d0a9..c311a6c 100644
--- a/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/CustomComponentTest.java
+++ b/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/CustomComponentTest.java
@@ -67,9 +67,8 @@ public class CustomComponentTest extends CamelAwsXRayTestSupport {
)
.withSegment(createSegment("delivery")
.withSubsegment(createSubsegment(CommonEndpoints.RECEIVED)
- .withSubsegment(createSubsegment("backingTask")
- .withSubsegment(createSubsegment("bean:ProcessingCamelBean"))
- )
+ .withSubsegment(createSubsegment("seda:backingTask"))
+ .withSubsegment(createSubsegment("seda:backingTask"))
.withMetadata("state", "received")
)
.withSubsegment(createSubsegment(IN_QUEUE))
diff --git a/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/SpringAwsXRaySimpleRouteTest.java
b/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/SpringAwsXRaySimpleRouteTest.java
index ec8e25b..f8f0977 100644
--- a/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/SpringAwsXRaySimpleRouteTest.java
+++ b/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/SpringAwsXRaySimpleRouteTest.java
@@ -54,25 +54,20 @@ public class SpringAwsXRaySimpleRouteTest extends CamelSpringTestSupport
{
List<TestTrace> testData = Arrays.asList(
TestDataBuilder.createTrace()
- .withSegment(TestDataBuilder.createSegment("dude")
- .withSubsegment(TestDataBuilder.createSubsegment("car"))
- ),
+ .withSegment(TestDataBuilder.createSegment("dude"))
+ .withSegment(TestDataBuilder.createSegment("car")),
TestDataBuilder.createTrace()
- .withSegment(TestDataBuilder.createSegment("dude")
- .withSubsegment(TestDataBuilder.createSubsegment("car"))
- ),
+ .withSegment(TestDataBuilder.createSegment("dude"))
+ .withSegment(TestDataBuilder.createSegment("car")),
TestDataBuilder.createTrace()
- .withSegment(TestDataBuilder.createSegment("dude")
- .withSubsegment(TestDataBuilder.createSubsegment("car"))
- ),
+ .withSegment(TestDataBuilder.createSegment("dude"))
+ .withSegment(TestDataBuilder.createSegment("car")),
TestDataBuilder.createTrace()
- .withSegment(TestDataBuilder.createSegment("dude")
- .withSubsegment(TestDataBuilder.createSubsegment("car"))
- ),
+ .withSegment(TestDataBuilder.createSegment("dude"))
+ .withSegment(TestDataBuilder.createSegment("car")),
TestDataBuilder.createTrace()
- .withSegment(TestDataBuilder.createSegment("dude")
- .withSubsegment(TestDataBuilder.createSubsegment("car"))
- )
+ .withSegment(TestDataBuilder.createSegment("dude"))
+ .withSegment(TestDataBuilder.createSegment("car"))
);
Thread.sleep(2000);
diff --git a/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/TwoService2Test.java
b/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/TwoService2Test.java
index 913bf7d..390de07 100644
--- a/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/TwoService2Test.java
+++ b/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/TwoService2Test.java
@@ -31,11 +31,8 @@ public class TwoService2Test extends CamelAwsXRayTestSupport {
public TwoService2Test() {
super(
TestDataBuilder.createTrace().inRandomOrder()
- .withSegment(TestDataBuilder.createSegment("route1")
- .withSubsegment(TestDataBuilder.createSubsegment("direct:ServiceB")
- .withSubsegment(TestDataBuilder.createSubsegment("route2"))
- )
- )
+ .withSegment(TestDataBuilder.createSegment("route1"))
+ .withSegment(TestDataBuilder.createSegment("route2"))
);
}
diff --git a/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/TwoServiceTest.java
b/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/TwoServiceTest.java
index 6c21700..ad08573 100644
--- a/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/TwoServiceTest.java
+++ b/components/camel-aws-xray/src/test/java/org/apache/camel/component/aws/xray/TwoServiceTest.java
@@ -32,10 +32,9 @@ public class TwoServiceTest extends CamelAwsXRayTestSupport {
super(
TestDataBuilder.createTrace().inRandomOrder()
.withSegment(TestDataBuilder.createSegment("ServiceA")
- .withSubsegment(TestDataBuilder.createSubsegment("direct:ServiceB")
- .withSubsegment(TestDataBuilder.createSubsegment("ServiceB"))
- )
+ .withSubsegment(TestDataBuilder.createSubsegment("direct:ServiceB"))
)
+ .withSegment(TestDataBuilder.createSegment("ServiceB"))
);
}
diff --git a/components/camel-aws-xray/src/test/resources/log4j2.properties b/components/camel-aws-xray/src/test/resources/log4j2.properties
new file mode 100644
index 0000000..e685fc4
--- /dev/null
+++ b/components/camel-aws-xray/src/test/resources/log4j2.properties
@@ -0,0 +1,39 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+appender.console.type = Console
+appender.console.name = console
+appender.console.layout.type = PatternLayout
+appender.console.layout.pattern = [%-30.30t] %d %-5p %-30.30c{1} - %m%n
+
+appender.file.type = File
+appender.file.name = file
+appender.file.fileName = target/camel-aws-xray-test.log
+appender.file.append = true
+appender.file.layout.type = PatternLayout
+appender.file.layout.pattern = [%-30.30t] %d %-5p %-30.30c{1} - %m%n
+
+rootLogger.level = INFO
+
+rootLogger.appenderRef.file.ref = file
+#rootLogger.appenderRef.console.ref = console
+
+logger.camel-core.name = org.apache.camel
+logger.camel-core.level = INFO
+logger.camel-xray.name = org.apache.camel.component.aws.xray
+logger.camel-xray.level = TRACE
+logger.xray.name = com.amazonaws.xray
+logger.xray.level = TRACE
|