Repository: camel Updated Branches: refs/heads/master 97f442c6d -> a88c016a2
Fixed CamelContext.addLogListener wrong case, added support for log component and log eip Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/a88c016a Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/a88c016a Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/a88c016a Branch: refs/heads/master Commit: a88c016a20c48a979a00d7e346e7edfd63695af6 Parents: 97f442c Author: Gary Brown <g...@brownuk.com> Authored: Thu Apr 6 20:14:48 2017 +0100 Committer: Claus Ibsen <davscl...@apache.org> Committed: Fri Apr 7 12:01:39 2017 +0200 ---------------------------------------------------------------------- .../java/org/apache/camel/CamelContext.java | 4 +-- .../apache/camel/impl/DefaultCamelContext.java | 2 +- .../camel/component/log/LogListenerTest.java | 2 +- .../camel/processor/LogEipListenerTest.java | 2 +- .../camel/opentracing/OpenTracingTracer.java | 33 ++++++++++++++++- .../apache/camel/opentracing/SpanDecorator.java | 8 +++++ .../decorators/AbstractSpanDecorator.java | 5 +++ .../decorators/LogSpanDecorator.java | 31 ++++++++++++++++ .../org.apache.camel.opentracing.SpanDecorator | 1 + .../apache/camel/opentracing/ABCRouteTest.java | 8 ++--- .../CamelOpenTracingTestSupport.java | 37 ++++++++++++-------- .../opentracing/MulticastParallelRouteTest.java | 6 ++-- .../apache/camel/opentracing/SpanTestData.java | 12 +++++++ 13 files changed, 124 insertions(+), 27 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/a88c016a/camel-core/src/main/java/org/apache/camel/CamelContext.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/CamelContext.java b/camel-core/src/main/java/org/apache/camel/CamelContext.java index 8aec529..b0789c4 100644 --- a/camel-core/src/main/java/org/apache/camel/CamelContext.java +++ b/camel-core/src/main/java/org/apache/camel/CamelContext.java @@ -1975,6 +1975,6 @@ public interface CamelContext extends SuspendableService, RuntimeConfiguration { /** * Adds a {@link LogListener}. */ - void addlogListener(LogListener listener); + void addLogListener(LogListener listener); -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/camel/blob/a88c016a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java index f16de74..bea497d 100644 --- a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java +++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java @@ -2691,7 +2691,7 @@ public class DefaultCamelContext extends ServiceSupport implements ModelCamelCon return logListeners; } - public void addlogListener(LogListener listener) { + public void addLogListener(LogListener listener) { logListeners.add(listener); } http://git-wip-us.apache.org/repos/asf/camel/blob/a88c016a/camel-core/src/test/java/org/apache/camel/component/log/LogListenerTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/component/log/LogListenerTest.java b/camel-core/src/test/java/org/apache/camel/component/log/LogListenerTest.java index dbdaf12..4b506e7 100644 --- a/camel-core/src/test/java/org/apache/camel/component/log/LogListenerTest.java +++ b/camel-core/src/test/java/org/apache/camel/component/log/LogListenerTest.java @@ -35,7 +35,7 @@ public class LogListenerTest { CamelContext context = createCamelContext(); MockEndpoint mock = context.getEndpoint("mock:foo", MockEndpoint.class); mock.expectedMessageCount(1); - context.addlogListener((exchange, camelLogger, message) -> { + context.addLogListener((exchange, camelLogger, message) -> { Assert.assertEquals("Exchange[ExchangePattern: InOnly, BodyType: String, Body: hello]", message); listenerFired = true; return message + " - modified by listener"; http://git-wip-us.apache.org/repos/asf/camel/blob/a88c016a/camel-core/src/test/java/org/apache/camel/processor/LogEipListenerTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/processor/LogEipListenerTest.java b/camel-core/src/test/java/org/apache/camel/processor/LogEipListenerTest.java index 0e52fde..dbebc66 100644 --- a/camel-core/src/test/java/org/apache/camel/processor/LogEipListenerTest.java +++ b/camel-core/src/test/java/org/apache/camel/processor/LogEipListenerTest.java @@ -35,7 +35,7 @@ public class LogEipListenerTest { CamelContext context = createCamelContext(); MockEndpoint mock = context.getEndpoint("mock:foo", MockEndpoint.class); mock.expectedMessageCount(1); - context.addlogListener((exchange, camelLogger, message) -> { + context.addLogListener((exchange, camelLogger, message) -> { Assert.assertEquals("Got hello", message); listenerFired = true; return message + " - modified by listener"; http://git-wip-us.apache.org/repos/asf/camel/blob/a88c016a/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/OpenTracingTracer.java ---------------------------------------------------------------------- diff --git a/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/OpenTracingTracer.java b/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/OpenTracingTracer.java index de95244..e1a130f 100644 --- a/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/OpenTracingTracer.java +++ b/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/OpenTracingTracer.java @@ -45,11 +45,13 @@ import org.apache.camel.opentracing.concurrent.CamelSpanManager; import org.apache.camel.opentracing.concurrent.OpenTracingExecutorServiceManager; import org.apache.camel.opentracing.propagation.CamelHeadersExtractAdapter; import org.apache.camel.opentracing.propagation.CamelHeadersInjectAdapter; +import org.apache.camel.spi.LogListener; import org.apache.camel.spi.RoutePolicy; import org.apache.camel.spi.RoutePolicyFactory; import org.apache.camel.support.EventNotifierSupport; import org.apache.camel.support.RoutePolicySupport; import org.apache.camel.support.ServiceSupport; +import org.apache.camel.util.CamelLogger; import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.ServiceHelper; import org.slf4j.Logger; @@ -72,6 +74,7 @@ public class OpenTracingTracer extends ServiceSupport implements RoutePolicyFact private static Map<String, SpanDecorator> decorators = new HashMap<>(); private final OpenTracingEventNotifier eventNotifier = new OpenTracingEventNotifier(); + private final OpenTracingLogListener logListener = new OpenTracingLogListener(); private final CamelSpanManager spanManager = CamelSpanManager.getInstance(); private Tracer tracer; private CamelContext camelContext; @@ -111,6 +114,7 @@ public class OpenTracingTracer extends ServiceSupport implements RoutePolicyFact // Wrap the ExecutorServiceManager with a SpanManager aware version camelContext.setExecutorServiceManager( new OpenTracingExecutorServiceManager(camelContext.getExecutorServiceManager(), spanManager)); + } catch (Exception e) { throw ObjectHelper.wrapRuntimeCamelException(e); } @@ -143,6 +147,7 @@ public class OpenTracingTracer extends ServiceSupport implements RoutePolicyFact if (!camelContext.getRoutePolicyFactories().contains(this)) { camelContext.addRoutePolicyFactory(this); } + camelContext.addLogListener(logListener); if (tracer == null) { Set<Tracer> tracers = camelContext.getRegistry().findByType(Tracer.class); @@ -196,6 +201,9 @@ public class OpenTracingTracer extends ServiceSupport implements RoutePolicyFact ExchangeSendingEvent ese = (ExchangeSendingEvent) event; SpanManager.ManagedSpan parent = spanManager.current(); SpanDecorator sd = getSpanDecorator(ese.getEndpoint()); + if (!sd.newSpan()) { + return; + } SpanBuilder spanBuilder = tracer.buildSpan(sd.getOperationName(ese.getExchange(), ese.getEndpoint())) .withTag(Tags.SPAN_KIND.getKey(), sd.getInitiatorSpanKind()); // Temporary workaround to avoid adding 'null' span as a parent @@ -213,6 +221,10 @@ public class OpenTracingTracer extends ServiceSupport implements RoutePolicyFact } } else if (event instanceof ExchangeSentEvent) { ExchangeSentEvent ese = (ExchangeSentEvent) event; + SpanDecorator sd = getSpanDecorator(ese.getEndpoint()); + if (!sd.newSpan()) { + return; + } SpanManager.ManagedSpan managedSpan = (SpanManager.ManagedSpan) ese.getExchange().getProperty(MANAGED_SPAN_PROPERTY); if (managedSpan != null) { @@ -224,7 +236,6 @@ public class OpenTracingTracer extends ServiceSupport implements RoutePolicyFact if (LOG.isTraceEnabled()) { LOG.trace("OpenTracing: start client span=" + managedSpan.getSpan()); } - SpanDecorator sd = getSpanDecorator(ese.getEndpoint()); sd.post(managedSpan.getSpan(), ese.getExchange(), ese.getEndpoint()); managedSpan.getSpan().finish(); managedSpan.deactivate(); @@ -285,4 +296,24 @@ public class OpenTracingTracer extends ServiceSupport implements RoutePolicyFact } } + private final class OpenTracingLogListener implements LogListener { + + @Override + public String onLog(Exchange exchange, CamelLogger camelLogger, String message) { + SpanManager.ManagedSpan managedSpan = (SpanManager.ManagedSpan) + exchange.getProperty(MANAGED_SPAN_PROPERTY); + Span span = null; + if (managedSpan != null) { + span = managedSpan.getSpan(); + } else { + span = spanManager.current().getSpan(); + } + if (span != null) { + Map<String, Object> fields = new HashMap<>(); + fields.put("message", message); + span.log(fields); + } + return message; + } + } } http://git-wip-us.apache.org/repos/asf/camel/blob/a88c016a/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/SpanDecorator.java ---------------------------------------------------------------------- diff --git a/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/SpanDecorator.java b/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/SpanDecorator.java index 5d0445a..54414cf 100644 --- a/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/SpanDecorator.java +++ b/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/SpanDecorator.java @@ -40,6 +40,14 @@ public interface SpanDecorator { }; /** + * This method indicates whether the component associated with the SpanDecorator + * should result in a new span being created. + * + * @return Whether a new span should be created + */ + boolean newSpan(); + + /** * The camel component associated with the decorator. * * @return The camel component name http://git-wip-us.apache.org/repos/asf/camel/blob/a88c016a/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/decorators/AbstractSpanDecorator.java ---------------------------------------------------------------------- diff --git a/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/decorators/AbstractSpanDecorator.java b/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/decorators/AbstractSpanDecorator.java index 55efc4c..74d42a0 100644 --- a/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/decorators/AbstractSpanDecorator.java +++ b/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/decorators/AbstractSpanDecorator.java @@ -34,6 +34,11 @@ import org.apache.camel.util.URISupport; public abstract class AbstractSpanDecorator implements SpanDecorator { @Override + public boolean newSpan() { + return true; + } + + @Override public String getOperationName(Exchange exchange, Endpoint endpoint) { // OpenTracing aims to use low cardinality operation names. Ideally a specific // span decorator should be defined for all relevant Camel components that http://git-wip-us.apache.org/repos/asf/camel/blob/a88c016a/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/decorators/LogSpanDecorator.java ---------------------------------------------------------------------- diff --git a/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/decorators/LogSpanDecorator.java b/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/decorators/LogSpanDecorator.java new file mode 100644 index 0000000..1b08b7d --- /dev/null +++ b/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/decorators/LogSpanDecorator.java @@ -0,0 +1,31 @@ +/** + * 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. + */ +package org.apache.camel.opentracing.decorators; + +public class LogSpanDecorator extends AbstractSpanDecorator { + + @Override + public String getComponent() { + return "log"; + } + + @Override + public boolean newSpan() { + return false; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/a88c016a/components/camel-opentracing/src/main/resources/META-INF/services/org.apache.camel.opentracing.SpanDecorator ---------------------------------------------------------------------- diff --git a/components/camel-opentracing/src/main/resources/META-INF/services/org.apache.camel.opentracing.SpanDecorator b/components/camel-opentracing/src/main/resources/META-INF/services/org.apache.camel.opentracing.SpanDecorator index 36c2805..835743a 100644 --- a/components/camel-opentracing/src/main/resources/META-INF/services/org.apache.camel.opentracing.SpanDecorator +++ b/components/camel-opentracing/src/main/resources/META-INF/services/org.apache.camel.opentracing.SpanDecorator @@ -34,6 +34,7 @@ org.apache.camel.opentracing.decorators.JdbcSpanDecorator org.apache.camel.opentracing.decorators.JettySpanDecorator org.apache.camel.opentracing.decorators.JmsSpanDecorator org.apache.camel.opentracing.decorators.KafkaSpanDecorator +org.apache.camel.opentracing.decorators.LogSpanDecorator org.apache.camel.opentracing.decorators.MongoDBSpanDecorator org.apache.camel.opentracing.decorators.MqttSpanDecorator org.apache.camel.opentracing.decorators.NettyHttp4SpanDecorator http://git-wip-us.apache.org/repos/asf/camel/blob/a88c016a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/ABCRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/ABCRouteTest.java b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/ABCRouteTest.java index 0f67f57..babf9a1 100644 --- a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/ABCRouteTest.java +++ b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/ABCRouteTest.java @@ -25,15 +25,15 @@ public class ABCRouteTest extends CamelOpenTracingTestSupport { private static SpanTestData[] testdata = { new SpanTestData().setLabel("seda:b server").setUri("seda://b").setOperation("b") - .setKind(Tags.SPAN_KIND_SERVER).setParentId(1), + .setKind(Tags.SPAN_KIND_SERVER).setParentId(1).addLogMessage("routing at b"), new SpanTestData().setLabel("seda:b client").setUri("seda://b").setOperation("b") .setKind(Tags.SPAN_KIND_CLIENT).setParentId(4), new SpanTestData().setLabel("seda:c server").setUri("seda://c").setOperation("c") - .setKind(Tags.SPAN_KIND_SERVER).setParentId(3), + .setKind(Tags.SPAN_KIND_SERVER).setParentId(3).addLogMessage("Exchange[ExchangePattern: InOut, BodyType: String, Body: Hello]"), new SpanTestData().setLabel("seda:c client").setUri("seda://c").setOperation("c") .setKind(Tags.SPAN_KIND_CLIENT).setParentId(4), new SpanTestData().setLabel("seda:a server").setUri("seda://a").setOperation("a") - .setKind(Tags.SPAN_KIND_SERVER).setParentId(5), + .setKind(Tags.SPAN_KIND_SERVER).setParentId(5).addLogMessage("routing at a").addLogMessage("End of routing"), new SpanTestData().setLabel("seda:a client").setUri("seda://a").setOperation("a") .setKind(Tags.SPAN_KIND_CLIENT).setParentId(6), new SpanTestData().setLabel("direct:start server").setUri("direct://start").setOperation("start") @@ -72,7 +72,7 @@ public class ABCRouteTest extends CamelOpenTracingTestSupport { .delay(simple("${random(1000,2000)}")); from("seda:c").routeId("c") - .log("routing at ${routeId}") + .to("log:test") .delay(simple("${random(0,100)}")); } }; http://git-wip-us.apache.org/repos/asf/camel/blob/a88c016a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/CamelOpenTracingTestSupport.java ---------------------------------------------------------------------- diff --git a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/CamelOpenTracingTestSupport.java b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/CamelOpenTracingTestSupport.java index a48cee0..4b87ab5 100644 --- a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/CamelOpenTracingTestSupport.java +++ b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/CamelOpenTracingTestSupport.java @@ -22,7 +22,6 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.stream.Collectors; import io.opentracing.Span; @@ -95,28 +94,38 @@ public class CamelOpenTracingTestSupport extends CamelTestSupport { } protected void verifySpan(int index, SpanTestData[] testdata, List<MockSpan> spans) { - String component = (String) spans.get(index).tags().get(Tags.COMPONENT.getKey()); + MockSpan span = spans.get(index); + SpanTestData td = testdata[index]; + + String component = (String) span.tags().get(Tags.COMPONENT.getKey()); assertNotNull(component); - assertEquals(testdata[index].getLabel(), - SpanDecorator.CAMEL_COMPONENT + URI.create((String) testdata[index].getUri()).getScheme(), + assertEquals(td.getLabel(), + SpanDecorator.CAMEL_COMPONENT + URI.create((String) td.getUri()).getScheme(), component); - assertEquals(testdata[index].getLabel(), testdata[index].getUri(), spans.get(index).tags().get("camel.uri")); + assertEquals(td.getLabel(), td.getUri(), span.tags().get("camel.uri")); // If span associated with TestSEDASpanDecorator, check that pre/post tags have been defined if ("camel-seda".equals(component)) { - assertTrue(spans.get(index).tags().containsKey("pre")); - assertTrue(spans.get(index).tags().containsKey("post")); + assertTrue(span.tags().containsKey("pre")); + assertTrue(span.tags().containsKey("post")); } - assertEquals(testdata[index].getLabel(), testdata[index].getOperation(), spans.get(index).operationName()); + assertEquals(td.getLabel(), td.getOperation(), span.operationName()); + + assertEquals(td.getLabel(), td.getKind(), + span.tags().get(Tags.SPAN_KIND.getKey())); - assertEquals(testdata[index].getLabel(), testdata[index].getKind(), - spans.get(index).tags().get(Tags.SPAN_KIND.getKey())); + if (td.getParentId() != -1) { + assertEquals(td.getLabel(), + spans.get(td.getParentId()).context().spanId(), + span.parentId()); + } - if (testdata[index].getParentId() != -1) { - assertEquals(testdata[index].getLabel(), - spans.get(testdata[index].getParentId()).context().spanId(), - spans.get(index).parentId()); + if (!td.getLogMessages().isEmpty()) { + assertEquals("Number of log messages", td.getLogMessages().size(), span.logEntries().size()); + for (int i = 0; i < td.getLogMessages().size(); i++) { + assertEquals(td.getLogMessages().get(i), span.logEntries().get(i).fields().get("message")); + } } } http://git-wip-us.apache.org/repos/asf/camel/blob/a88c016a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/MulticastParallelRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/MulticastParallelRouteTest.java b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/MulticastParallelRouteTest.java index 856f931..ce20b30 100644 --- a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/MulticastParallelRouteTest.java +++ b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/MulticastParallelRouteTest.java @@ -25,15 +25,15 @@ public class MulticastParallelRouteTest extends CamelOpenTracingTestSupport { private static SpanTestData[] testdata = { new SpanTestData().setLabel("seda:b server").setUri("seda://b").setOperation("b") - .setKind(Tags.SPAN_KIND_SERVER).setParentId(1), + .setKind(Tags.SPAN_KIND_SERVER).setParentId(1).addLogMessage("routing at b"), new SpanTestData().setLabel("seda:b client").setUri("seda://b").setOperation("b") .setKind(Tags.SPAN_KIND_CLIENT).setParentId(4), new SpanTestData().setLabel("seda:c server").setUri("seda://c").setOperation("c") - .setKind(Tags.SPAN_KIND_SERVER).setParentId(3), + .setKind(Tags.SPAN_KIND_SERVER).setParentId(3).addLogMessage("routing at c"), new SpanTestData().setLabel("seda:c client").setUri("seda://c").setOperation("c") .setKind(Tags.SPAN_KIND_CLIENT).setParentId(4), new SpanTestData().setLabel("seda:a server").setUri("seda://a").setOperation("a") - .setKind(Tags.SPAN_KIND_SERVER).setParentId(5), + .setKind(Tags.SPAN_KIND_SERVER).setParentId(5).addLogMessage("routing at a").addLogMessage("End of routing"), new SpanTestData().setLabel("seda:a client").setUri("seda://a").setOperation("a") .setKind(Tags.SPAN_KIND_CLIENT).setParentId(6), new SpanTestData().setLabel("direct:start server").setUri("direct://start").setOperation("start") http://git-wip-us.apache.org/repos/asf/camel/blob/a88c016a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/SpanTestData.java ---------------------------------------------------------------------- diff --git a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/SpanTestData.java b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/SpanTestData.java index 6f532ce..eccc00c 100644 --- a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/SpanTestData.java +++ b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/SpanTestData.java @@ -16,6 +16,9 @@ */ package org.apache.camel.opentracing; +import java.util.ArrayList; +import java.util.List; + public class SpanTestData { private String label; @@ -23,6 +26,7 @@ public class SpanTestData { private String operation; private String kind; private int parentId = -1; + private List<String> logMessages = new ArrayList<>(); public String getLabel() { return label; @@ -69,4 +73,12 @@ public class SpanTestData { return this; } + public SpanTestData addLogMessage(String mesg) { + logMessages.add(mesg); + return this; + } + + public List<String> getLogMessages() { + return logMessages; + } }