diff --git a/base/service/pom.xml b/base/service/pom.xml index 13254eebca..566bbb9f20 100644 --- a/base/service/pom.xml +++ b/base/service/pom.xml @@ -67,6 +67,11 @@ ch.qos.logback logback-classic + + net.logstash.logback + logstash-logback-encoder + provided + org.apache.pekko pekko-actor_${scala.version} diff --git a/base/service/src/main/java/org/eclipse/ditto/base/service/devops/DevOpsCommandsActor.java b/base/service/src/main/java/org/eclipse/ditto/base/service/devops/DevOpsCommandsActor.java index a2cd2f4c19..872ef05222 100644 --- a/base/service/src/main/java/org/eclipse/ditto/base/service/devops/DevOpsCommandsActor.java +++ b/base/service/src/main/java/org/eclipse/ditto/base/service/devops/DevOpsCommandsActor.java @@ -522,8 +522,7 @@ private DevOpsCommandResponseCorrelationActor(final ActorRef devOpsCommandSender final var dittoHeaders = devOpsCommand.getDittoHeaders(); aggregateResults = isAggregateResults(dittoHeaders); this.expectedResponses = expectedResponses; - logger = DittoLoggerFactory.getDiagnosticLoggingAdapter(this); - logger.setCorrelationId(dittoHeaders); + logger = DittoLoggerFactory.getDiagnosticLoggingAdapter(this).withCorrelationId(dittoHeaders); } private static boolean isAggregateResults(final DittoHeaders dittoHeaders) { diff --git a/base/service/src/main/java/org/eclipse/ditto/base/service/logging/IntLevelJsonProvider.java b/base/service/src/main/java/org/eclipse/ditto/base/service/logging/IntLevelJsonProvider.java new file mode 100644 index 0000000000..d88d7cb1e9 --- /dev/null +++ b/base/service/src/main/java/org/eclipse/ditto/base/service/logging/IntLevelJsonProvider.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.ditto.base.service.logging; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonGenerator; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.spi.ILoggingEvent; +import net.logstash.logback.composite.AbstractFieldJsonProvider; +import net.logstash.logback.composite.JsonWritingUtils; + +/** + * Logstash logback provider for providing a field {@code intLevel} for each log entry with the values, depending on + * the log level, being: + * + * To be used in {@code logback.xml} as: + *
{@code
+ * 
+ *    
+ * 
+ * }
+ * 
+ * + * @since 3.4.0 + */ +public final class IntLevelJsonProvider extends AbstractFieldJsonProvider { + + @Override + public void writeTo(final JsonGenerator generator, final ILoggingEvent event) throws IOException { + JsonWritingUtils.writeNumberField( + generator, + "intLevel", + mapFromLevelToIntLevel(event.getLevel()) + ); + } + + private int mapFromLevelToIntLevel(final Level level) { + if (level.equals(Level.OFF)) { + return 0; + } else if (level.equals(Level.TRACE)) { + return 1; + } else if (level.equals(Level.DEBUG)) { + return 2; + } else if (level.equals(Level.INFO)) { + return 3; + } else if (level.equals(Level.WARN)) { + return 4; + } else if (level.equals(Level.ERROR)) { + return 5; + } else if (level.equals(Level.ALL)) { + // should not be able to happen for a single log entry: + return Integer.MAX_VALUE; + } else { + // should not be able to happen at all: + return Integer.MIN_VALUE; + } + } +} diff --git a/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/BasePublisherActor.java b/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/BasePublisherActor.java index 2495efae03..fb61b75620 100644 --- a/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/BasePublisherActor.java +++ b/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/BasePublisherActor.java @@ -13,7 +13,6 @@ package org.eclipse.ditto.connectivity.service.messaging; import static org.eclipse.ditto.base.model.common.ConditionChecker.checkNotNull; -import static org.eclipse.ditto.base.model.headers.DittoHeaderDefinition.CORRELATION_ID; import java.nio.ByteBuffer; import java.nio.charset.Charset; @@ -314,11 +313,10 @@ private Stream sendMappedOutboundSignal(final OutboundSignal.M final int maxPayloadBytesForSignal) { final var message = outbound.getExternalMessage(); - final String correlationId = message.getHeaders().get(CORRELATION_ID.getKey()); final Signal outboundSource = outbound.getSource(); final List outboundTargets = outbound.getTargets(); - final ThreadSafeDittoLoggingAdapter l = logger.withCorrelationId(correlationId); + final ThreadSafeDittoLoggingAdapter l = logger.withCorrelationId(message.getHeaders()); final Optional replyTargetSendingContext = getSendingContext(outbound); final List sendingContexts = replyTargetSendingContext diff --git a/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/InboundDispatchingSink.java b/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/InboundDispatchingSink.java index a9c5de41d7..87f6d07661 100644 --- a/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/InboundDispatchingSink.java +++ b/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/InboundDispatchingSink.java @@ -329,11 +329,8 @@ public Optional> onMapped(final String mapperId, @Override public Optional> onDropped(final String mapperId, @Nullable final ExternalMessage incomingMessage) { - logger.withCorrelationId(Optional.ofNullable(incomingMessage) - .map(ExternalMessage::getHeaders) - .map(h -> h.get(DittoHeaderDefinition.CORRELATION_ID.getKey())) - .orElse(null) - ).debug("Message mapping returned null, message is dropped."); + logger.withCorrelationId(incomingMessage != null ? incomingMessage.getHeaders() : null) + .debug("Message mapping returned null, message is dropped."); if (incomingMessage != null) { final String source = getAddress(incomingMessage); final ConnectionMonitor.InfoProvider infoProvider = InfoProviderFactory.forExternalMessage(incomingMessage); diff --git a/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/InboundMappingProcessor.java b/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/InboundMappingProcessor.java index 416156c1d1..f1bf699470 100644 --- a/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/InboundMappingProcessor.java +++ b/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/InboundMappingProcessor.java @@ -130,7 +130,7 @@ static InboundMappingProcessor of(final Connection connection, @Override List> process(final ExternalMessage message) { final var mappers = getMappers(message.getPayloadMapping().orElse(null)); - logger.withCorrelationId(message.getHeaders().get(DittoHeaderDefinition.CORRELATION_ID.getKey())) + logger.withCorrelationId(message.getHeaders()) .debug("Mappers resolved for message: {}", mappers); final var mappingTimer = MappingTimer.inbound(connectionId, connectionType, message.getHeaders()); return mappingTimer.overall(() -> mappers.stream() diff --git a/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/InboundMappingSink.java b/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/InboundMappingSink.java index 24d1a766b1..85b70b28b4 100644 --- a/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/InboundMappingSink.java +++ b/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/InboundMappingSink.java @@ -21,7 +21,6 @@ import javax.annotation.Nullable; import org.eclipse.ditto.base.model.exceptions.DittoRuntimeException; -import org.eclipse.ditto.base.model.headers.DittoHeaderDefinition; import org.eclipse.ditto.base.service.config.ThrottlingConfig; import org.eclipse.ditto.connectivity.model.ConnectionId; import org.eclipse.ditto.connectivity.service.config.mapping.MappingConfig; @@ -169,14 +168,12 @@ private InboundMappingOutcomes mapInboundMessage(final ExternalMessageWithSender final InboundMappingProcessor inboundMappingProcessor) { final var externalMessage = withSender.externalMessage(); - @Nullable final var correlationId = - externalMessage.findHeaderIgnoreCase(DittoHeaderDefinition.CORRELATION_ID.getKey()).orElse(null); - logger.withCorrelationId(correlationId) + logger.withCorrelationId(externalMessage.getHeaders()) .debug("Handling ExternalMessage: {}", externalMessage); try { return mapExternalMessageToSignal(withSender, inboundMappingProcessor); } catch (final Exception e) { - logger.withCorrelationId(correlationId) + logger.withCorrelationId(externalMessage.getHeaders()) .error("Handling exception when mapping external message: {}", e.getMessage()); return InboundMappingOutcomes.of(withSender.externalMessage(), e, withSender.sender()); } diff --git a/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/Sending.java b/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/Sending.java index e1783ed69c..3f22f4bc58 100644 --- a/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/Sending.java +++ b/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/Sending.java @@ -13,8 +13,9 @@ package org.eclipse.ditto.connectivity.service.messaging; import static org.eclipse.ditto.base.model.common.ConditionChecker.checkNotNull; -import static org.eclipse.ditto.base.model.headers.DittoHeaderDefinition.CORRELATION_ID; +import java.util.HashMap; +import java.util.Map; import java.util.Optional; import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionStage; @@ -29,7 +30,6 @@ import org.eclipse.ditto.base.model.entity.id.EntityId; import org.eclipse.ditto.base.model.entity.id.WithEntityId; import org.eclipse.ditto.base.model.exceptions.DittoRuntimeException; -import org.eclipse.ditto.base.model.headers.DittoHeaders; import org.eclipse.ditto.base.model.signals.Signal; import org.eclipse.ditto.base.model.signals.acks.Acknowledgement; import org.eclipse.ditto.base.model.signals.commands.CommandResponse; @@ -217,10 +217,9 @@ private void updateSendMonitor(@Nullable final Exception exception) { dittoRuntimeException.getClass().getSimpleName(), dittoRuntimeException.getMessage()); } else { publishedMonitor.exception(message, exception); - final DittoHeaders internalHeaders = message.getInternalHeaders(); - @Nullable final String correlationId = internalHeaders.getCorrelationId() - .orElseGet(() -> message.findHeaderIgnoreCase(CORRELATION_ID.getKey()).orElse(null)); - logger.withCorrelationId(correlationId) + final Map combinedHeaders = new HashMap<>(message.getHeaders()); + combinedHeaders.putAll(message.getInternalHeaders()); + logger.withCorrelationId(combinedHeaders) .info("Unexpected failure when publishing signal - {}: {}", exception.getClass().getSimpleName(), exception.getMessage()); } diff --git a/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/amqp/AmqpConsumerActor.java b/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/amqp/AmqpConsumerActor.java index dcfd02e1d8..c015a43e33 100644 --- a/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/amqp/AmqpConsumerActor.java +++ b/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/amqp/AmqpConsumerActor.java @@ -365,7 +365,7 @@ private void handleJmsMessage(final JmsMessage message) { .start(); headers = startedSpan.propagateContext(headers); final ExternalMessageBuilder builder = ExternalMessageFactory.newExternalMessageBuilder(headers); - final ExternalMessage externalMessage = extractPayloadFromMessage(message, builder, correlationId) + final ExternalMessage externalMessage = extractPayloadFromMessage(message, builder) .withAuthorizationContext(source.getAuthorizationContext()) .withEnforcement(headerEnforcementFilterFactory.getFilter(headers)) .withHeaderMapping(source.getHeaderMapping()) @@ -374,10 +374,10 @@ private void handleJmsMessage(final JmsMessage message) { .build(); inboundMonitor.success(externalMessage); final Map externalMessageHeaders = externalMessage.getHeaders(); - logger.withCorrelationId(correlationId) + logger.withCorrelationId(headers) .info("Received message from AMQP 1.0 with externalMessageHeaders: {}", externalMessageHeaders); if (logger.isDebugEnabled()) { - logger.withCorrelationId(correlationId).debug("Received message from AMQP 1.0 with payload: {}", + logger.withCorrelationId(headers).debug("Received message from AMQP 1.0 with payload: {}", externalMessage.getTextPayload().orElse("binary")); } forwardToMapping(externalMessage, @@ -404,7 +404,7 @@ private void handleJmsMessage(final JmsMessage message) { inboundMonitor.exception(e); } startedSpan.tagAsFailed(e); - logger.withCorrelationId(correlationId) + logger.withCorrelationId(headers) .error(e, "Unexpected {}: {}", e.getClass().getName(), e.getMessage()); } finally { startedSpan.finish(); @@ -422,8 +422,6 @@ private void handleJmsMessage(final JmsMessage message) { private void acknowledge(final JmsMessage message, final boolean isSuccess, final boolean redeliver, final Map externalMessageHeaders) { - final Optional correlationId = Optional.ofNullable( - externalMessageHeaders.get(DittoHeaderDefinition.CORRELATION_ID.getKey())); try { final String messageId = message.getJMSMessageID(); recordAckForRateLimit(messageId, isSuccess, redeliver); @@ -437,8 +435,7 @@ private void acknowledge(final JmsMessage message, final boolean isSuccess, fina ackType = redeliver ? MODIFIED_FAILED : REJECTED; ackTypeName = redeliver ? "modified[delivery-failed]" : "rejected"; } - final String jmsCorrelationID = message.getJMSCorrelationID(); - logger.withCorrelationId(correlationId.orElse(jmsCorrelationID)) + logger.withCorrelationId(externalMessageHeaders) .info(MessageFormat.format( "Acking <{0}> with original external message headers=<{1}>, isSuccess=<{2}>, ackType=<{3} {4}>", messageId, @@ -457,15 +454,15 @@ private void acknowledge(final JmsMessage message, final boolean isSuccess, fina "Sending negative acknowledgement: <{0}>", ackTypeName); } } catch (final IllegalStateException e) { - logger.withCorrelationId(correlationId.orElse(null)) + logger.withCorrelationId(externalMessageHeaders) .warning(e, "Failed to ack an AMQP message because of server side issues"); } catch (final Exception e) { - logger.withCorrelationId(correlationId.orElse(null)).error(e, "Failed to ack an AMQP message"); + logger.withCorrelationId(externalMessageHeaders).error(e, "Failed to ack an AMQP message"); } } private ExternalMessageBuilder extractPayloadFromMessage(final JmsMessage message, - final ExternalMessageBuilder builder, @Nullable final String correlationId) throws JMSException { + final ExternalMessageBuilder builder) throws JMSException { if (message instanceof TextMessage textMessage) { final String payload = textMessage.getText(); if (payload == null) { @@ -487,7 +484,7 @@ private ExternalMessageBuilder extractPayloadFromMessage(final JmsMessage messag if (logger.isDebugEnabled()) { final Destination destination = message.getJMSDestination(); final Map headersMapFromJmsMessage = extractHeadersMapFromJmsMessage(message); - logger.withCorrelationId(correlationId) + logger.withCorrelationId(headersMapFromJmsMessage) .debug("Received message at '{}' of unsupported type ({}) with headers: {}", destination, message.getClass().getName(), headersMapFromJmsMessage); } diff --git a/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/kafka/KafkaMessageTransformer.java b/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/kafka/KafkaMessageTransformer.java index 0e2ea29e16..8c2e6ea4a8 100644 --- a/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/kafka/KafkaMessageTransformer.java +++ b/connectivity/service/src/main/java/org/eclipse/ditto/connectivity/service/messaging/kafka/KafkaMessageTransformer.java @@ -117,7 +117,7 @@ public TransformationResult transform(final ConsumerRecord c try { final String key = consumerRecord.key(); final ByteBuffer value = consumerRecord.value(); - final ThreadSafeDittoLogger correlationIdScopedLogger = LOGGER.withCorrelationId(correlationId); + final ThreadSafeDittoLogger correlationIdScopedLogger = LOGGER.withCorrelationId(messageHeaders); correlationIdScopedLogger.debug( "Transforming incoming kafka message <{}> with headers <{}> and key <{}>.", value, messageHeaders, key @@ -148,7 +148,7 @@ public TransformationResult transform(final ConsumerRecord c return TransformationResult.failed(e.setDittoHeaders(DittoHeaders.of(messageHeaders))); } catch (final Exception e) { inboundMonitor.exception(messageHeaders, e); - LOGGER.withCorrelationId(correlationId) + LOGGER.withCorrelationId(messageHeaders) .error(String.format("Unexpected {%s}: {%s}", e.getClass().getName(), e.getMessage()), e); startedSpan.tagAsFailed(e); return null; // Drop message diff --git a/connectivity/service/src/main/resources/logback.xml b/connectivity/service/src/main/resources/logback.xml index 46ae52471b..43f8d573ea 100644 --- a/connectivity/service/src/main/resources/logback.xml +++ b/connectivity/service/src/main/resources/logback.xml @@ -16,14 +16,14 @@ - %date{ISO8601} %-5level [%X{x-correlation-id}] %logger{20} %X{pekkoSource} - %msg%n + %date{ISO8601} %-5level [%X{correlation-id}][%X{traceparent-trace-id}] %logger{20} %X{pekkoSource} - %msg%n System.err - %date{ISO8601} %-5level [%X{x-correlation-id}] %logger{20} %X{pekkoSource} - %msg%n + %date{ISO8601} %-5level [%X{correlation-id}][%X{traceparent-trace-id}] %logger{20} %X{pekkoSource} - %msg%n ERROR diff --git a/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/AbstractConsumerActorTest.java b/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/AbstractConsumerActorTest.java index 65ce9c76b7..f100160382 100644 --- a/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/AbstractConsumerActorTest.java +++ b/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/AbstractConsumerActorTest.java @@ -254,6 +254,7 @@ protected Sink setupInboundMappingSink(final ActorRef clientAct .thenReturn(logger); when(logger.withCorrelationId(Mockito.any(WithDittoHeaders.class))) .thenReturn(logger); + when(logger.withCorrelationId(Mockito.any(Map.class))).thenReturn(logger); final ProtocolAdapter protocolAdapter = protocolAdapterProvider.getProtocolAdapter(null); final var connection = CONNECTION.toBuilder().payloadMappingDefinition(payloadMappingDefinition).build(); final InboundMappingProcessor inboundMappingProcessor = diff --git a/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/AbstractMessageMappingProcessorActorTest.java b/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/AbstractMessageMappingProcessorActorTest.java index 551cabd1ec..31d90ea532 100644 --- a/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/AbstractMessageMappingProcessorActorTest.java +++ b/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/AbstractMessageMappingProcessorActorTest.java @@ -349,6 +349,7 @@ ActorRef createInboundMappingProcessorActor(final ActorRef proxyActor, final var logger = Mockito.mock(ThreadSafeDittoLoggingAdapter.class); Mockito.when(logger.withCorrelationId(Mockito.any(DittoHeaders.class))) .thenReturn(logger); + Mockito.when(logger.withCorrelationId(Mockito.any(Map.class))).thenReturn(logger); Mockito.when(logger.withCorrelationId(Mockito.nullable(CharSequence.class))) .thenReturn(logger); Mockito.when(logger.withCorrelationId(Mockito.any(WithDittoHeaders.class))) diff --git a/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/InboundMappingProcessorActorTest.java b/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/InboundMappingProcessorActorTest.java index 6f1390faf0..20ca8b00c5 100644 --- a/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/InboundMappingProcessorActorTest.java +++ b/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/InboundMappingProcessorActorTest.java @@ -125,6 +125,7 @@ private static InboundMappingProcessor createThrowingProcessor() { final ThreadSafeDittoLoggingAdapter logger = Mockito.mock(ThreadSafeDittoLoggingAdapter.class); Mockito.doAnswer(inv -> logger).when(logger).withCorrelationId(Mockito.any()); Mockito.doAnswer(inv -> logger).when(logger).withCorrelationId(Mockito.any()); + Mockito.doAnswer(inv -> logger).when(logger).withCorrelationId(Mockito.any()); final Connection connection = TestConstants.createConnection(ConnectionId.of("connectionId"), ConnectionType.MQTT); return InboundMappingProcessor.of(connection, diff --git a/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/OutboundMappingProcessorTest.java b/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/OutboundMappingProcessorTest.java index e8bc29ffc5..890706d698 100644 --- a/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/OutboundMappingProcessorTest.java +++ b/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/OutboundMappingProcessorTest.java @@ -112,6 +112,7 @@ public static void setUp() { when(logger.withCorrelationId(Mockito.nullable(String.class))).thenReturn(logger); when(logger.withCorrelationId(Mockito.nullable(WithDittoHeaders.class))).thenReturn(logger); when(logger.withCorrelationId(Mockito.nullable(DittoHeaders.class))).thenReturn(logger); + when(logger.withCorrelationId(Mockito.nullable(Map.class))).thenReturn(logger); when(logger.withCorrelationId(Mockito.nullable(CharSequence.class))).thenReturn(logger); protocolAdapterProvider = new DittoProtocolAdapterProvider(Mockito.mock(ProtocolConfig.class)); diff --git a/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/SendingTest.java b/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/SendingTest.java index 290e94652f..6174e19861 100644 --- a/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/SendingTest.java +++ b/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/SendingTest.java @@ -17,6 +17,7 @@ import static org.mockito.Mockito.eq; import static org.mockito.Mockito.withSettings; +import java.util.Map; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; @@ -92,8 +93,8 @@ public void setUp() { .build(); Mockito.when(externalMessage.getInternalHeaders()).thenReturn(dittoHeaders); - Mockito.when(logger.withCorrelationId(Mockito.nullable(CharSequence.class))).thenReturn(logger); Mockito.when(logger.withCorrelationId(Mockito.any(WithDittoHeaders.class))).thenReturn(logger); + Mockito.when(logger.withCorrelationId(Mockito.any(Map.class))).thenReturn(logger); exceptionConverter = DefaultExceptionToAcknowledgementConverter.getInstance(); } @@ -313,7 +314,7 @@ public void monitorAndAcknowledgeWhenFutureResponseTerminatedExceptionallyAndNoA Mockito.verifyNoInteractions(acknowledgedMonitor); Mockito.verify(publishedMonitor).exception(eq(externalMessage), eq(rootCause)); - Mockito.verify(logger).withCorrelationId(testName.getMethodName()); + Mockito.verify(logger).withCorrelationId(Map.of("correlation-id", testName.getMethodName())); assertThat(result).hasValueSatisfying(resultFuture -> assertThat(resultFuture).isCompletedWithValue(null)); } diff --git a/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/TestConstants.java b/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/TestConstants.java index 7d54c8ef84..9a56539328 100644 --- a/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/TestConstants.java +++ b/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/TestConstants.java @@ -245,6 +245,7 @@ public static ThreadSafeDittoLoggingAdapter mockThreadSafeDittoLoggingAdapter() when(logger.withCorrelationId(Mockito.nullable(String.class))).thenReturn(logger); when(logger.withCorrelationId(Mockito.nullable(WithDittoHeaders.class))).thenReturn(logger); when(logger.withCorrelationId(Mockito.nullable(DittoHeaders.class))).thenReturn(logger); + when(logger.withCorrelationId(Mockito.nullable(Map.class))).thenReturn(logger); when(logger.withCorrelationId(Mockito.nullable(CharSequence.class))).thenReturn(logger); return logger; } diff --git a/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/amqp/AmqpConsumerActorTest.java b/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/amqp/AmqpConsumerActorTest.java index 71788ff9f7..cb91f5b481 100644 --- a/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/amqp/AmqpConsumerActorTest.java +++ b/connectivity/service/src/test/java/org/eclipse/ditto/connectivity/service/messaging/amqp/AmqpConsumerActorTest.java @@ -360,6 +360,7 @@ private Sink setupMappingSink(final ActorRef testRef, final ThreadSafeDittoLoggingAdapter logger = mock(ThreadSafeDittoLoggingAdapter.class); when(logger.withCorrelationId(any(DittoHeaders.class))) .thenReturn(logger); + when(logger.withCorrelationId(any(Map.class))).thenReturn(logger); when(logger.withCorrelationId(Mockito.nullable(CharSequence.class))) .thenReturn(logger); when(logger.withCorrelationId(any(WithDittoHeaders.class))) diff --git a/edge/service/src/main/java/org/eclipse/ditto/edge/service/acknowledgements/AcknowledgementAggregatorActor.java b/edge/service/src/main/java/org/eclipse/ditto/edge/service/acknowledgements/AcknowledgementAggregatorActor.java index 49c2343e19..e9a76dde4d 100644 --- a/edge/service/src/main/java/org/eclipse/ditto/edge/service/acknowledgements/AcknowledgementAggregatorActor.java +++ b/edge/service/src/main/java/org/eclipse/ditto/edge/service/acknowledgements/AcknowledgementAggregatorActor.java @@ -104,7 +104,7 @@ private AcknowledgementAggregatorActor(final EntityId entityId, final var acknowledgementRequests = signalDittoHeaders.getAcknowledgementRequests(); ackregator = AcknowledgementAggregator.getInstance(entityId, correlationId, timeout, headerTranslator); ackregator.addAcknowledgementRequests(acknowledgementRequests); - log.withCorrelationId(correlationId) + log.withCorrelationId(signalDittoHeaders) .info("Starting to wait for all requested acknowledgements <{}> for a maximum duration of <{}>.", acknowledgementRequests, timeout); diff --git a/edge/service/src/test/resources/logback-test.xml b/edge/service/src/test/resources/logback-test.xml index 8fb7948912..b7360bc0f1 100644 --- a/edge/service/src/test/resources/logback-test.xml +++ b/edge/service/src/test/resources/logback-test.xml @@ -19,7 +19,7 @@ - %d{HH:mm:ss.SSS} [%-5level] [%X{x-correlation-id}] %logger{15} - %msg%n%rEx + %d{HH:mm:ss.SSS} [%-5level] [%X{correlation-id}] %logger{15} - %msg%n%rEx diff --git a/gateway/api/src/main/java/org/eclipse/ditto/gateway/api/GatewayDuplicateHeaderException.java b/gateway/api/src/main/java/org/eclipse/ditto/gateway/api/GatewayDuplicateHeaderException.java index 693f59312b..d12119888b 100755 --- a/gateway/api/src/main/java/org/eclipse/ditto/gateway/api/GatewayDuplicateHeaderException.java +++ b/gateway/api/src/main/java/org/eclipse/ditto/gateway/api/GatewayDuplicateHeaderException.java @@ -12,7 +12,10 @@ */ package org.eclipse.ditto.gateway.api; +import static java.util.Objects.requireNonNull; + import java.net.URI; +import java.text.MessageFormat; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; @@ -38,7 +41,10 @@ public final class GatewayDuplicateHeaderException extends DittoRuntimeException public static final String ERROR_CODE = ERROR_CODE_PREFIX + "duplicate.header.field"; private static final String DEFAULT_MESSAGE = - "The send request contains headers which include a duplicate header field!"; + "The message contains headers which include a duplicate header field!"; + + private static final String MESSAGE_TEMPLATE_WITH_KNOWN_DUPLICATED_HEADERNAME = + "The message contains headers which include a duplicate header field: ''{0}''"; private static final String DEFAULT_DESCRIPTION = "A request must not contain multiple header fields with the same field name. " + @@ -65,6 +71,17 @@ public static Builder newBuilder() { return new Builder(); } + /** + * A mutable builder for a {@code GatewayDuplicateHeaderException} with a known duplicated header key. + * + * @param duplicatedHeaderName the name of the duplicated header. + * @throws NullPointerException if {@code duplicatedHeaderName} parameter is null. + * @return the builder. + */ + public static Builder newBuilder(final CharSequence duplicatedHeaderName) { + return new Builder(requireNonNull(duplicatedHeaderName)); + } + /** * Constructs a new {@code GatewayDuplicateHeaderException} object with given message. * @@ -118,6 +135,12 @@ private Builder() { href(DEFAULT_HREF); } + private Builder(final CharSequence duplicatedHeaderName) { + description(DEFAULT_DESCRIPTION); + message(MessageFormat.format(MESSAGE_TEMPLATE_WITH_KNOWN_DUPLICATED_HEADERNAME, duplicatedHeaderName)); + href(DEFAULT_HREF); + } + @Override protected GatewayDuplicateHeaderException doBuild(final DittoHeaders dittoHeaders, @Nullable final String message, diff --git a/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/endpoints/actors/AbstractHttpRequestActor.java b/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/endpoints/actors/AbstractHttpRequestActor.java index 9ad9f8a955..445022ef34 100644 --- a/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/endpoints/actors/AbstractHttpRequestActor.java +++ b/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/endpoints/actors/AbstractHttpRequestActor.java @@ -267,7 +267,6 @@ public void serviceRequestsDone(final Control serviceRequestsDone) { private void handleCommand(final Command command) { try { - logger.setCorrelationId(command); receivedCommand = command; setDefaultTimeoutExceptionSupplier(command); final var timeoutOverride = getReceiveTimeout(command, commandConfig); @@ -528,8 +527,8 @@ private void handleReceiveTimeout() { final var actorContext = getContext(); final var receiveTimeout = actorContext.getReceiveTimeout(); - logger.setCorrelationId(WithDittoHeaders.getCorrelationId(receivedCommand).orElse(null)); - logger.info("Got <{}> after <{}> before an appropriate response arrived.", + logger.withCorrelationId(receivedCommand) + .info("Got <{}> after <{}> before an appropriate response arrived.", ReceiveTimeout.class.getSimpleName(), receiveTimeout); if (null != timeoutExceptionSupplier) { @@ -539,8 +538,9 @@ private void handleReceiveTimeout() { } else { actorContext.cancelReceiveTimeout(); // This case is a programming error that should not happen at all. - logger.error("Actor does not have a timeout exception supplier." + - " Thus, no DittoRuntimeException could be handled."); + logger.withCorrelationId(receivedCommand) + .error("Actor does not have a timeout exception supplier. " + + "Thus, no DittoRuntimeException could be handled."); stop(); } } diff --git a/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/endpoints/directives/CorrelationIdEnsuringDirective.java b/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/endpoints/directives/CorrelationIdEnsuringDirective.java index f3d2cbf5be..f42cb015a9 100755 --- a/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/endpoints/directives/CorrelationIdEnsuringDirective.java +++ b/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/endpoints/directives/CorrelationIdEnsuringDirective.java @@ -14,9 +14,12 @@ import static org.apache.pekko.http.javadsl.server.Directives.extractRequestContext; +import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; import javax.annotation.concurrent.Immutable; @@ -53,7 +56,8 @@ private CorrelationIdEnsuringDirective() { public static Route ensureCorrelationId(final Function inner) { return extractRequestContext(requestContext -> { final String correlationId = getCorrelationIdFromHeaders(requestContext.getRequest()) - .orElseGet(CorrelationIdEnsuringDirective::createNewCorrelationId); + .orElseGet(() -> + CorrelationIdEnsuringDirective.createNewCorrelationId(requestContext.getRequest())); return inner.apply(correlationId); }); } @@ -64,19 +68,25 @@ private static Optional getCorrelationIdFromHeaders(final HttpRequest re .map(HttpHeader::value); if (LOGGER.isDebugEnabled()) { - result.ifPresent(correlationId -> LOGGER.withCorrelationId(correlationId) + result.ifPresent(correlationId -> LOGGER.withCorrelationId(headersAsMap(request)) .debug("Correlation ID <{}> already exists in request.", correlationId)); } return result; } - private static String createNewCorrelationId() { + private static String createNewCorrelationId(final HttpRequest request) { final String result = String.valueOf(UUID.randomUUID()); if (LOGGER.isDebugEnabled()) { - LOGGER.withCorrelationId(result).debug("Created new correlation ID <{}>.", result); + LOGGER.withCorrelationId(headersAsMap(request)) + .debug("Created new correlation ID <{}>.", result); } return result; } + private static Map headersAsMap(final HttpRequest request) { + return StreamSupport.stream(request.getHeaders().spliterator(), false) + .collect(Collectors.toMap(HttpHeader::name, HttpHeader::value)); + } + } diff --git a/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/endpoints/directives/RequestResultLoggingDirective.java b/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/endpoints/directives/RequestResultLoggingDirective.java index 4311ba825e..749f0a21ec 100755 --- a/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/endpoints/directives/RequestResultLoggingDirective.java +++ b/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/endpoints/directives/RequestResultLoggingDirective.java @@ -20,12 +20,18 @@ import static org.eclipse.ditto.gateway.service.endpoints.directives.RequestLoggingFilter.filterRawUri; import static org.eclipse.ditto.gateway.service.endpoints.directives.RequestLoggingFilter.filterUri; +import java.util.Map; import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; +import org.eclipse.ditto.base.model.headers.DittoHeaderDefinition; import org.eclipse.ditto.gateway.service.endpoints.utils.HttpUtils; import org.eclipse.ditto.internal.utils.pekko.logging.DittoLoggerFactory; import org.eclipse.ditto.internal.utils.pekko.logging.ThreadSafeDittoLogger; +import org.apache.pekko.http.javadsl.model.HttpHeader; +import org.apache.pekko.http.javadsl.model.HttpRequest; import org.apache.pekko.http.javadsl.server.Complete; import org.apache.pekko.http.javadsl.server.Route; @@ -62,7 +68,9 @@ public static Route logRequestResult(final CharSequence correlationId, final Sup final String requestMethod = request.method().name(); final String filteredRelativeRequestUri = filterUri(request.getUri().toRelative()).toString(); return mapRouteResult(routeResult -> { - final ThreadSafeDittoLogger logger = LOGGER.withCorrelationId(correlationId); + final Map headers = headersAsMap(request); + headers.put(DittoHeaderDefinition.CORRELATION_ID.getKey(), correlationId.toString()); + final ThreadSafeDittoLogger logger = LOGGER.withCorrelationId(headers); if (routeResult instanceof Complete complete) { final int statusCode = complete.getResponse().status().intValue(); logger.info("StatusCode of request {} '{}' was: {}", requestMethod, filteredRelativeRequestUri, @@ -73,7 +81,7 @@ public static Route logRequestResult(final CharSequence correlationId, final Sup } request.getHeader(DITTO_TRACE_HEADERS) .filter(unused -> TRACE_LOGGER.isDebugEnabled()) - .ifPresent(unused -> TRACE_LOGGER.withCorrelationId(correlationId) + .ifPresent(unused -> TRACE_LOGGER.withCorrelationId(headers) .debug("Request headers: {}", filterHeaders(request.getHeaders()))); } else { /* routeResult could be Rejected, if no route is able to handle the request -> but this should @@ -88,4 +96,8 @@ public static Route logRequestResult(final CharSequence correlationId, final Sup }); } + private static Map headersAsMap(final HttpRequest request) { + return StreamSupport.stream(request.getHeaders().spliterator(), false) + .collect(Collectors.toMap(HttpHeader::name, HttpHeader::value)); + } } diff --git a/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/endpoints/directives/RequestTracingDirective.java b/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/endpoints/directives/RequestTracingDirective.java index e9cf739aec..d13624b0d5 100644 --- a/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/endpoints/directives/RequestTracingDirective.java +++ b/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/endpoints/directives/RequestTracingDirective.java @@ -19,6 +19,7 @@ import java.net.URI; import java.text.MessageFormat; +import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.function.Supplier; @@ -32,6 +33,8 @@ import org.eclipse.ditto.base.model.common.HttpStatus; import org.eclipse.ditto.base.model.common.HttpStatusCodeOutOfRangeException; import org.eclipse.ditto.base.model.headers.DittoHeaderDefinition; +import org.eclipse.ditto.base.model.headers.DittoHeaders; +import org.eclipse.ditto.gateway.api.GatewayDuplicateHeaderException; import org.eclipse.ditto.internal.utils.pekko.logging.DittoLogger; import org.eclipse.ditto.internal.utils.pekko.logging.DittoLoggerFactory; import org.eclipse.ditto.internal.utils.tracing.DittoTracing; @@ -149,7 +152,29 @@ private static Route getRouteWithEnabledTracing( @Nullable final CharSequence correlationId ) { return mapRequest( - req -> adjustSpanContextHeadersOfRequest(req, startedSpan.propagateContext(Map.of())), + req -> { + final Set headerNames = new HashSet<>(); + return adjustSpanContextHeadersOfRequest(req, startedSpan.propagateContext( + StreamSupport.stream(httpRequest.getHeaders().spliterator(), false) + .map(httpHeader -> { + if (!headerNames.add(httpHeader.name())) { + throw GatewayDuplicateHeaderException.newBuilder(httpHeader.name()) + .dittoHeaders(DittoHeaders.newBuilder() + .correlationId(correlationId) + .build() + ).build(); + } + return httpHeader; + }) + .collect(Collectors.toMap(HttpHeader::name, HttpHeader::value, (dv1, dv2) -> { + throw GatewayDuplicateHeaderException.newBuilder() + .dittoHeaders(DittoHeaders.newBuilder() + .correlationId(correlationId) + .build() + ).build(); + })) + )); + }, () -> mapRouteResult( routeResult -> tryToHandleRouteResult(routeResult, httpRequest, startedSpan, correlationId), innerRouteSupplier diff --git a/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/endpoints/routes/RootRouteHeadersStepBuilder.java b/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/endpoints/routes/RootRouteHeadersStepBuilder.java index 624e2a8e4e..35cca7f8ff 100644 --- a/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/endpoints/routes/RootRouteHeadersStepBuilder.java +++ b/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/endpoints/routes/RootRouteHeadersStepBuilder.java @@ -15,7 +15,9 @@ import static org.eclipse.ditto.base.model.common.ConditionChecker.checkNotNull; import java.text.MessageFormat; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.concurrent.CompletionStage; import java.util.stream.Collectors; import java.util.stream.StreamSupport; @@ -122,7 +124,16 @@ QueryParametersStep withRequestContext(final RequestContext requestContext) { private Map getFilteredExternalHeaders(final HttpMessage httpRequest) { final Iterable headers = httpRequest.getHeaders(); + final Set headerNames = new HashSet<>(); final Map externalHeaders = StreamSupport.stream(headers.spliterator(), false) + .map(httpHeader -> { + if (!headerNames.add(httpHeader.name())) { + throw GatewayDuplicateHeaderException.newBuilder(httpHeader.name()) + .dittoHeaders(dittoHeadersBuilder.build()) + .build(); + } + return httpHeader; + }) .collect(Collectors.toMap(HttpHeader::lowercaseName, HttpHeader::value, (dv1, dv2) -> { throw GatewayDuplicateHeaderException.newBuilder() .dittoHeaders(dittoHeadersBuilder.build()) @@ -184,7 +195,7 @@ private void avoidConflictingHeaders(final Map headersFromQueryP private GatewayDuplicateHeaderException getDuplicateHeaderException(final String headerKey) { final String msgPattern = "<{0}> was provided as header as well as query parameter with divergent values!"; - return GatewayDuplicateHeaderException.newBuilder() + return GatewayDuplicateHeaderException.newBuilder(headerKey) .message(MessageFormat.format(msgPattern, headerKey)) .dittoHeaders(dittoHeadersBuilder.build()) .build(); diff --git a/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/security/authentication/preauth/PreAuthenticatedAuthenticationProvider.java b/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/security/authentication/preauth/PreAuthenticatedAuthenticationProvider.java index dd6bcf7de4..b2b972fd42 100644 --- a/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/security/authentication/preauth/PreAuthenticatedAuthenticationProvider.java +++ b/gateway/service/src/main/java/org/eclipse/ditto/gateway/service/security/authentication/preauth/PreAuthenticatedAuthenticationProvider.java @@ -14,13 +14,20 @@ import java.text.MessageFormat; import java.util.Arrays; +import java.util.HashMap; import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; import javax.annotation.concurrent.Immutable; +import org.apache.pekko.http.javadsl.model.HttpRequest; +import org.apache.pekko.http.javadsl.model.Query; +import org.apache.pekko.http.javadsl.model.Uri; +import org.apache.pekko.http.javadsl.server.RequestContext; import org.eclipse.ditto.base.model.auth.AuthorizationContext; import org.eclipse.ditto.base.model.auth.AuthorizationContextType; import org.eclipse.ditto.base.model.auth.AuthorizationModelFactory; @@ -38,11 +45,6 @@ import org.eclipse.ditto.internal.utils.pekko.logging.ThreadSafeDittoLogger; import org.eclipse.ditto.utils.jsr305.annotations.AllValuesAreNonnullByDefault; -import org.apache.pekko.http.javadsl.model.HttpRequest; -import org.apache.pekko.http.javadsl.model.Query; -import org.apache.pekko.http.javadsl.model.Uri; -import org.apache.pekko.http.javadsl.server.RequestContext; - /** * Handles authentication by using a defined header field {@link org.eclipse.ditto.gateway.service.security.HttpHeader#X_DITTO_PRE_AUTH} which proxies in front * of Ditto may set to inject authenticated subjects into a HTTP request. @@ -120,7 +122,14 @@ protected CompletableFuture tryToAuthenticate(final Reques AuthorizationModelFactory.newAuthContext(DittoAuthorizationContextType.PRE_AUTHENTICATED_HTTP, authorizationSubjects); - LOGGER.withCorrelationId(dittoHeaders) + final var combinedHeaders = new HashMap<>(dittoHeaders); + combinedHeaders.putAll(StreamSupport.stream(requestContext.getRequest().getHeaders().spliterator(), false) + .collect(Collectors.toMap( + org.apache.pekko.http.javadsl.model.HttpHeader::name, + org.apache.pekko.http.javadsl.model.HttpHeader::value + )) + ); + LOGGER.withCorrelationId(combinedHeaders) .info("Pre-authentication has been applied resulting in AuthorizationContext <{}>.", authContext); return CompletableFuture.completedFuture(DefaultAuthenticationResult.successful(dittoHeaders, authContext)); diff --git a/gateway/service/src/main/resources/logback.xml b/gateway/service/src/main/resources/logback.xml index 0dadcbcefa..de70c86ed3 100755 --- a/gateway/service/src/main/resources/logback.xml +++ b/gateway/service/src/main/resources/logback.xml @@ -16,14 +16,14 @@ - %date{ISO8601} %-5level [%X{x-correlation-id}] %logger{20} %X{pekkoSource} - %msg%n + %date{ISO8601} %-5level [%X{correlation-id}][%X{traceparent-trace-id}] %logger{20} %X{pekkoSource} - %msg%n System.err - %date{ISO8601} %-5level [%X{x-correlation-id}] %logger{20} %X{pekkoSource} - %msg%n + %date{ISO8601} %-5level [%X{correlation-id}][%X{traceparent-trace-id}] %logger{20} %X{pekkoSource} - %msg%n ERROR diff --git a/gateway/service/src/test/java/org/eclipse/ditto/gateway/service/endpoints/directives/RequestTracingDirectiveTest.java b/gateway/service/src/test/java/org/eclipse/ditto/gateway/service/endpoints/directives/RequestTracingDirectiveTest.java index d0726f9547..aa472317f9 100644 --- a/gateway/service/src/test/java/org/eclipse/ditto/gateway/service/endpoints/directives/RequestTracingDirectiveTest.java +++ b/gateway/service/src/test/java/org/eclipse/ditto/gateway/service/endpoints/directives/RequestTracingDirectiveTest.java @@ -143,7 +143,7 @@ public void traceRequestCallsDittoTracingIfTracingIsEnabledForResolvedSpanOperat } @Test - public void traceRequestWithExistingW3cTracingHeadersReplacesThoseHeadersWithCurrentSpanContextHeaders() { + public void traceRequestWithExistingW3cTracingHeadersKeepThisHeaders() { final var expectedStatus = StatusCodes.NO_CONTENT; final var effectiveHttpRequestHeader = new CompletableFuture>(); final var routeFactory = new AllDirectives() { @@ -162,7 +162,7 @@ public Route createRoute() { ); } }; - final var tracestateHeaderValue = ";"; + final var tracestateHeaderValue = "cogo=uhu"; final var traceparentHeaderValue = "00-00000000000000002d773e5f58ee5636-28cae4bd320cbc11-0"; final var fooHeaderValue = "bar"; final var testRoute = testRoute( @@ -182,8 +182,8 @@ public Route createRoute() { .satisfies(httpRequestHeaders -> assertThat(httpRequestHeaders) .containsEntry("foo", fooHeaderValue) .containsKeys(W3C_TRACEPARENT.getKey(), W3C_TRACESTATE.getKey()) - .doesNotContainValue(tracestateHeaderValue) - .doesNotContainValue(traceparentHeaderValue)); + .containsValue(tracestateHeaderValue) + .containsValue(traceparentHeaderValue)); } } diff --git a/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/CommonMdcEntryKey.java b/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/CommonMdcEntryKey.java index b4597a5924..e63492dbf7 100644 --- a/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/CommonMdcEntryKey.java +++ b/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/CommonMdcEntryKey.java @@ -12,6 +12,18 @@ */ package org.eclipse.ditto.internal.utils.pekko.logging; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Stream; + +import javax.annotation.Nullable; + +import org.eclipse.ditto.base.model.headers.DittoHeaderDefinition; + /** * An enumeration of commonly known MDC entry keys. * @@ -19,8 +31,12 @@ */ public enum CommonMdcEntryKey implements CharSequence { - CORRELATION_ID("x-correlation-id"), - DITTO_LOG_TAG("ditto-log-tag"); + CORRELATION_ID(DittoHeaderDefinition.CORRELATION_ID.getKey()), + DITTO_LOG_TAG("ditto-log-tag"), + TRACE_PARENT(DittoHeaderDefinition.W3C_TRACEPARENT.getKey()); + + private static final String TRACE_ID = TRACE_PARENT.key + "-trace-id"; + private static final String SPAN_ID = TRACE_PARENT.key + "-span-id"; private final String key; @@ -48,4 +64,57 @@ public String toString() { return key; } + /** + * Returns the {@code CommonMdcEntryKey} with the given name. + * + * @param name the name of the common MDC entry to get. + * @return the common MDC entry with the given name or an empty optional. + */ + public static Optional forName(@Nullable final CharSequence name) { + return Stream.of(values()) + .filter(l -> Objects.equals(l.key, String.valueOf(name))) + .findAny(); + } + + /** + * Extracts a list of MdcEntries based on the given {@code headers} map, picking out explicitly headers which should + * be added to the MDC. + *

+ * This method is called a lot of times in Ditto's codebase and therefore better be fast. This was achieved by not + * iterating over all headers, but to accessing the passed {@code HashMap} for picking out only the supported + * headers. + *

+ * + * @param headers the headers to look into for extracting the MDC worthy headers to log. + * @return a list of MDC entries to add to the MDC. + */ + public static List extractMdcEntriesFromHeaders(@Nullable final Map headers) { + + if (null == headers || headers.isEmpty()) { + return Collections.emptyList(); + } + return Stream.of(CORRELATION_ID, TRACE_PARENT) + .flatMap(mdcEntryKey -> extractValue(headers, mdcEntryKey)) + .toList(); + } + + private static Stream extractValue(final Map headers, + final CommonMdcEntryKey mdcEntryKey) { + + if (mdcEntryKey == TRACE_PARENT) { + return Optional.ofNullable(headers.get(mdcEntryKey.key)) + .filter(traceParent -> traceParent.charAt(2) == '-' && traceParent.length() == 55) + .map(traceParent -> Stream.of( + // positions defined by https://www.w3.org/TR/trace-context/#traceparent-header-field-values to contain the "trace-id" + MdcEntry.of(TRACE_ID, traceParent.substring(3, 35)), + MdcEntry.of(SPAN_ID, traceParent.substring(36, 52)) + )).stream() + .flatMap(Function.identity()); + } else { + return Optional.ofNullable(headers.get(mdcEntryKey.key)) + .map(value -> MdcEntry.of(mdcEntryKey.key, value)) + .stream(); + } + } + } diff --git a/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/DefaultDittoDiagnosticLoggingAdapter.java b/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/DefaultDittoDiagnosticLoggingAdapter.java index d38376690a..a142456169 100644 --- a/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/DefaultDittoDiagnosticLoggingAdapter.java +++ b/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/DefaultDittoDiagnosticLoggingAdapter.java @@ -24,7 +24,6 @@ import org.eclipse.ditto.base.model.headers.WithDittoHeaders; import org.apache.pekko.event.DiagnosticLoggingAdapter; -import scala.collection.JavaConverters; import scala.collection.immutable.Seq; /** @@ -73,29 +72,18 @@ public DefaultDittoDiagnosticLoggingAdapter withCorrelationId(@Nullable final Ch } @Override - public DefaultDittoDiagnosticLoggingAdapter withCorrelationId(@Nullable final WithDittoHeaders withDittoHeaders) { - return withCorrelationId(null != withDittoHeaders ? withDittoHeaders.getDittoHeaders() : null); - } - - @Override - public DefaultDittoDiagnosticLoggingAdapter withCorrelationId(@Nullable final DittoHeaders dittoHeaders) { - return withCorrelationId(null != dittoHeaders ? dittoHeaders.getCorrelationId().orElse(null) : null); - } - - @Override - public DefaultDittoDiagnosticLoggingAdapter setCorrelationId(@Nullable final CharSequence correlationId) { - return setMdcEntry(CommonMdcEntryKey.CORRELATION_ID, correlationId); + public DefaultDittoDiagnosticLoggingAdapter withCorrelationId(@Nullable final Map headers) { + return withMdcEntries(CommonMdcEntryKey.extractMdcEntriesFromHeaders(headers)); } @Override - public DefaultDittoDiagnosticLoggingAdapter setCorrelationId(final WithDittoHeaders withDittoHeaders) { - return setCorrelationId(checkNotNull(withDittoHeaders, "withDittoHeaders").getDittoHeaders()); + public DefaultDittoDiagnosticLoggingAdapter withCorrelationId(@Nullable final WithDittoHeaders withDittoHeaders) { + return withCorrelationId(null != withDittoHeaders ? withDittoHeaders.getDittoHeaders() : null); } @Override - public DefaultDittoDiagnosticLoggingAdapter setCorrelationId(final DittoHeaders dittoHeaders) { - checkNotNull(dittoHeaders, "dittoHeaders"); - return setCorrelationId(dittoHeaders.getCorrelationId().orElse(null)); + public DefaultDittoDiagnosticLoggingAdapter withCorrelationId(@Nullable final DittoHeaders dittoHeaders) { + return withCorrelationId(null != dittoHeaders ? dittoHeaders : Map.of()); } @Override @@ -150,30 +138,6 @@ private void removeFromMdcOfAllLoggerStates(final CharSequence key) { autoDiscardingLoggingAdapter.removeMdcEntry(key); } - @Override - public DefaultDittoDiagnosticLoggingAdapter setMdcEntry(final MdcEntry mdcEntry, - final Seq furtherMdcEntries) { - - currentLogger = loggingAdapter; - putToMdcOfAllLoggerStates(mdcEntry.getKey(), mdcEntry.getValueOrNull()); - final Collection furtherMdcEntriesCollection = JavaConverters.asJavaCollection(furtherMdcEntries); - furtherMdcEntriesCollection.forEach(furtherMdcEntry -> putToMdcOfAllLoggerStates(furtherMdcEntry.getKey(), - furtherMdcEntry.getValueOrNull())); - return this; - } - - @Override - public DefaultDittoDiagnosticLoggingAdapter setMdcEntry(final MdcEntry mdcEntry, - final MdcEntry... furtherMdcEntries) { - - currentLogger = loggingAdapter; - putToMdcOfAllLoggerStates(mdcEntry.getKey(), mdcEntry.getValueOrNull()); - for (final MdcEntry furtherMdcEntry : furtherMdcEntries) { - putToMdcOfAllLoggerStates(furtherMdcEntry.getKey(), furtherMdcEntry.getValueOrNull()); - } - return this; - } - @Override public DefaultDittoDiagnosticLoggingAdapter putMdcEntry(final CharSequence key, @Nullable final CharSequence value) { @@ -226,6 +190,15 @@ public DittoDiagnosticLoggingAdapter withMdcEntry(final MdcEntry mdcEntry, final return this; } + @Override + public DefaultDittoDiagnosticLoggingAdapter withMdcEntries(final Collection mdcEntries) { + checkNotNull(mdcEntries, "mdcEntries"); + + currentLogger = autoDiscardingLoggingAdapter; + mdcEntries.forEach(mdcEntry -> currentLogger.putMdcEntry(mdcEntry.getKey(), mdcEntry.getValueOrNull())); + return this; + } + @Override public DefaultDittoDiagnosticLoggingAdapter withMdcEntry(final MdcEntry mdcEntry, final Seq furtherMdcEntries) { diff --git a/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/DefaultDittoLogger.java b/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/DefaultDittoLogger.java index 86e9461372..cafb20b2e1 100644 --- a/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/DefaultDittoLogger.java +++ b/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/DefaultDittoLogger.java @@ -14,6 +14,9 @@ import static org.eclipse.ditto.base.model.common.ConditionChecker.checkNotNull; +import java.util.Collection; +import java.util.Map; + import javax.annotation.Nullable; import javax.annotation.concurrent.NotThreadSafe; @@ -60,6 +63,11 @@ public DefaultDittoLogger withCorrelationId(@Nullable final CharSequence correla return this; } + @Override + public DefaultDittoLogger withCorrelationId(@Nullable final Map headers) { + return withMdcEntries(CommonMdcEntryKey.extractMdcEntriesFromHeaders(headers)); + } + @Override public DefaultDittoLogger withCorrelationId(@Nullable final WithDittoHeaders withDittoHeaders) { return withCorrelationId(null != withDittoHeaders ? withDittoHeaders.getDittoHeaders() : null); @@ -67,7 +75,7 @@ public DefaultDittoLogger withCorrelationId(@Nullable final WithDittoHeaders wit @Override public DefaultDittoLogger withCorrelationId(@Nullable final DittoHeaders dittoHeaders) { - return withCorrelationId(null != dittoHeaders ? dittoHeaders.getCorrelationId().orElse(null) : null); + return withCorrelationId(null != dittoHeaders ? dittoHeaders : Map.of()); } @Override @@ -77,17 +85,6 @@ public DefaultDittoLogger setCorrelationId(@Nullable final CharSequence correlat return this; } - @Override - public DefaultDittoLogger setCorrelationId(final WithDittoHeaders withDittoHeaders) { - return setCorrelationId(checkNotNull(withDittoHeaders, "withDittoHeaders").getDittoHeaders()); - } - - @Override - public DefaultDittoLogger setCorrelationId(final DittoHeaders dittoHeaders) { - checkNotNull(dittoHeaders, "dittoHeaders"); - return setCorrelationId(dittoHeaders.getCorrelationId().orElse(null)); - } - @Override public void discardCorrelationId() { currentLogger.discardCorrelationId(); @@ -141,6 +138,15 @@ public DefaultDittoLogger withMdcEntry(final MdcEntry mdcEntry, final MdcEntry.. return this; } + @Override + public DefaultDittoLogger withMdcEntries(final Collection mdcEntries) { + checkNotNull(mdcEntries, "mdcEntries"); + + currentLogger = autoClosingSlf4jLogger; + mdcEntries.forEach(mdcEntry -> currentLogger.putMdcEntry(mdcEntry.getKey(), mdcEntry.getValueOrNull())); + return this; + } + @Override public DefaultDittoLogger removeMdcEntry(final CharSequence key) { currentLogger.removeMdcEntry(key); diff --git a/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/DittoLogger.java b/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/DittoLogger.java index 12ec9a5d23..0566d7ed7c 100644 --- a/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/DittoLogger.java +++ b/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/DittoLogger.java @@ -12,6 +12,8 @@ */ package org.eclipse.ditto.internal.utils.pekko.logging; +import java.util.Map; + import javax.annotation.Nullable; import javax.annotation.concurrent.NotThreadSafe; @@ -95,48 +97,28 @@ public interface DittoLogger extends Logger, WithMdcEntry { DittoLogger withCorrelationId(@Nullable CharSequence correlationId); /** - * Derives the correlation ID from the given WithDittoHeaders for the subsequent log operation. - * - * @param withDittoHeaders provides DittoHeaders which might contain the correlation ID to be put to the MDC. - * @return this DittoLogger instance to allow method chaining. - */ - DittoLogger withCorrelationId(@Nullable WithDittoHeaders withDittoHeaders); - - /** - * Obtains the correlation ID from the given DittoHeaders for the subsequent log operation. - * - * @param dittoHeaders might contain the correlation ID to be put to the MDC. - * @return this DittoLogger instance to allow method chaining. - */ - DittoLogger withCorrelationId(@Nullable DittoHeaders dittoHeaders); - - /** - * Sets the given correlation ID for all subsequent log operations until it gets manually discarded. + * Obtains the correlation ID from the given Headers for the subsequent log operation. * - * @param correlationId the correlation ID to be put to the MDC. + * @param headers might contain the correlation ID to be put to the MDC. * @return this DittoLogger instance to allow method chaining. */ - AutoCloseableSlf4jLogger setCorrelationId(@Nullable CharSequence correlationId); + DittoLogger withCorrelationId(@Nullable Map headers); /** - * Derives the correlation ID from the given WithDittoHeaders for all subsequent log operations until it gets - * manually discarded. + * Derives the correlation ID from the given WithDittoHeaders for the subsequent log operation. * * @param withDittoHeaders provides DittoHeaders which might contain the correlation ID to be put to the MDC. * @return this DittoLogger instance to allow method chaining. - * @throws NullPointerException if {@code withDittoHeaders} is {@code null}. */ - AutoCloseableSlf4jLogger setCorrelationId(WithDittoHeaders withDittoHeaders); + DittoLogger withCorrelationId(@Nullable WithDittoHeaders withDittoHeaders); /** - * Obtains the correlation ID from the given DittoHeaders for all subsequent log operations until it gets manually - * discarded. + * Obtains the correlation ID from the given DittoHeaders for the subsequent log operation. * * @param dittoHeaders might contain the correlation ID to be put to the MDC. * @return this DittoLogger instance to allow method chaining. - * @throws NullPointerException if {@code dittoHeaders} is {@code null}. */ - AutoCloseableSlf4jLogger setCorrelationId(DittoHeaders dittoHeaders); + DittoLogger withCorrelationId(@Nullable DittoHeaders dittoHeaders); /** * Removes the currently set correlation ID from the MDC. diff --git a/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/ImmutableDittoLogger.java b/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/ImmutableDittoLogger.java index 631519a006..72c518d47e 100644 --- a/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/ImmutableDittoLogger.java +++ b/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/ImmutableDittoLogger.java @@ -15,6 +15,7 @@ import static org.eclipse.ditto.base.model.common.ConditionChecker.argumentNotEmpty; import static org.eclipse.ditto.base.model.common.ConditionChecker.checkNotNull; +import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -363,6 +364,11 @@ public ImmutableDittoLogger withCorrelationId(@Nullable final CharSequence corre return withMdcEntry(CommonMdcEntryKey.CORRELATION_ID, correlationId); } + @Override + public ImmutableDittoLogger withCorrelationId(@Nullable final Map headers) { + return withMdcEntries(CommonMdcEntryKey.extractMdcEntriesFromHeaders(headers)); + } + @Override public ImmutableDittoLogger withCorrelationId(@Nullable final WithDittoHeaders withDittoHeaders) { return withCorrelationId(null != withDittoHeaders ? withDittoHeaders.getDittoHeaders() : null); @@ -370,7 +376,7 @@ public ImmutableDittoLogger withCorrelationId(@Nullable final WithDittoHeaders w @Override public ImmutableDittoLogger withCorrelationId(@Nullable final DittoHeaders dittoHeaders) { - return withCorrelationId(null != dittoHeaders ? dittoHeaders.getCorrelationId().orElse(null) : null); + return withCorrelationId(null != dittoHeaders ? dittoHeaders : Map.of()); } @Override @@ -467,6 +473,16 @@ public ImmutableDittoLogger withMdcEntry(final MdcEntry mdcEntry, final MdcEntry return new ImmutableDittoLogger(plainSlf4jLogger, newLocalMdc); } + @Override + public ImmutableDittoLogger withMdcEntries(final Collection mdcEntries) { + checkNotNull(mdcEntries, "mdcEntries"); + + final Map newLocalMdc = copyLocalMdc(); + mdcEntries.forEach(mdcEntry -> newLocalMdc.put(mdcEntry.getKey(), mdcEntry.getValueOrNull())); + + return new ImmutableDittoLogger(plainSlf4jLogger, newLocalMdc); + } + @Override public ImmutableDittoLogger removeMdcEntry(final CharSequence key) { validateMdcEntryKey(key, "key"); diff --git a/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/ImmutableDittoLoggingAdapter.java b/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/ImmutableDittoLoggingAdapter.java index d68b07fd14..68655198d2 100644 --- a/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/ImmutableDittoLoggingAdapter.java +++ b/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/ImmutableDittoLoggingAdapter.java @@ -15,6 +15,7 @@ import static org.eclipse.ditto.base.model.common.ConditionChecker.argumentNotEmpty; import static org.eclipse.ditto.base.model.common.ConditionChecker.checkNotNull; +import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.function.Supplier; @@ -75,14 +76,19 @@ public ImmutableDittoLoggingAdapter withCorrelationId(@Nullable final CharSequen return withMdcEntry(CommonMdcEntryKey.CORRELATION_ID, correlationId); } + @Override + public ImmutableDittoLoggingAdapter withCorrelationId(@Nullable final Map headers) { + return withMdcEntries(CommonMdcEntryKey.extractMdcEntriesFromHeaders(headers)); + } + @Override public ImmutableDittoLoggingAdapter withCorrelationId(@Nullable final WithDittoHeaders withDittoHeaders) { - return withCorrelationId(null != withDittoHeaders ? withDittoHeaders.getDittoHeaders() : null); + return withCorrelationId(withDittoHeaders != null ? withDittoHeaders.getDittoHeaders() : null); } @Override public ImmutableDittoLoggingAdapter withCorrelationId(@Nullable final DittoHeaders dittoHeaders) { - return withCorrelationId(null != dittoHeaders ? dittoHeaders.getCorrelationId().orElse(null) : null); + return withCorrelationId(null != dittoHeaders ? dittoHeaders : Map.of()); } @Override @@ -187,6 +193,16 @@ public ImmutableDittoLoggingAdapter withMdcEntry(final MdcEntry mdcEntry, final return newInstance(diagnosticLoggingAdapterFactory, mdcCopy); } + @Override + public ImmutableDittoLoggingAdapter withMdcEntries(final Collection mdcEntries) { + checkNotNull(mdcEntries, "mdcEntries"); + + final Map newLocalMdc = getCopyOfMdc(); + mdcEntries.forEach(mdcEntry -> newLocalMdc.put(mdcEntry.getKey(), mdcEntry.getValueOrNull())); + + return newInstance(diagnosticLoggingAdapterFactory, newLocalMdc); + } + @Override public ImmutableDittoLoggingAdapter withMdcEntry(final MdcEntry mdcEntry, final MdcEntry... furtherMdcEntries) { checkNotNull(mdcEntry, "mdcEntry"); diff --git a/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/ThreadSafeDittoLogger.java b/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/ThreadSafeDittoLogger.java index 8bf408288e..0fa0484bda 100644 --- a/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/ThreadSafeDittoLogger.java +++ b/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/ThreadSafeDittoLogger.java @@ -12,6 +12,8 @@ */ package org.eclipse.ditto.internal.utils.pekko.logging; +import java.util.Map; + import javax.annotation.Nullable; import javax.annotation.concurrent.ThreadSafe; @@ -76,6 +78,16 @@ public interface ThreadSafeDittoLogger extends Logger, WithMdcEntry headers); + /** * Derives the correlation ID from the given WithDittoHeaders for the log operations on the returned logger. * If no or an empty correlation ID can be derived, this method has the same effect like diff --git a/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/WithMdcEntry.java b/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/WithMdcEntry.java index 74d5b1fb8e..14bb8376d6 100644 --- a/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/WithMdcEntry.java +++ b/internal/utils/pekko/src/main/java/org/eclipse/ditto/internal/utils/pekko/logging/WithMdcEntry.java @@ -12,6 +12,8 @@ */ package org.eclipse.ditto.internal.utils.pekko.logging; +import java.util.Collection; + import javax.annotation.Nullable; import org.slf4j.Logger; @@ -84,6 +86,14 @@ L withMdcEntries(CharSequence k1, @Nullable CharSequence v1, CharSequence k2, @N */ L withMdcEntry(MdcEntry mdcEntry, MdcEntry... furtherMdcEntries); + /** + * Puts the given entries to the MDC of this logger. + * + * @return this or a new logger instance for method chaining. + * @throws NullPointerException if any argument is {@code null}. + */ + L withMdcEntries(Collection mdcEntries); + /** * Removes the diagnostic context value identified by the specified key. * This method does nothing if there is no previous value associated with the specified key. diff --git a/internal/utils/pekko/src/main/scala/org/eclipse/ditto/internal/utils/pekko/logging/DittoDiagnosticLoggingAdapter.scala b/internal/utils/pekko/src/main/scala/org/eclipse/ditto/internal/utils/pekko/logging/DittoDiagnosticLoggingAdapter.scala index bdab0b8e18..6718362e0a 100644 --- a/internal/utils/pekko/src/main/scala/org/eclipse/ditto/internal/utils/pekko/logging/DittoDiagnosticLoggingAdapter.scala +++ b/internal/utils/pekko/src/main/scala/org/eclipse/ditto/internal/utils/pekko/logging/DittoDiagnosticLoggingAdapter.scala @@ -14,6 +14,7 @@ package org.eclipse.ditto.internal.utils.pekko.logging import org.eclipse.ditto.base.model.headers.{DittoHeaders, WithDittoHeaders} +import java.util import javax.annotation.Nullable import javax.annotation.concurrent.NotThreadSafe import scala.annotation.varargs @@ -62,6 +63,13 @@ abstract class DittoDiagnosticLoggingAdapter extends AbstractDiagnosticLoggingAd */ def withCorrelationId(@Nullable correlationId: CharSequence): DittoDiagnosticLoggingAdapter + /** Obtains the correlation ID from the given headers for the subsequent log operation. + * + * @param headers might contain the correlation ID to be put to the MDC. + * @return this DittoLogger instance to allow method chaining. + */ + def withCorrelationId(@Nullable headers: util.Map[String, String]): DittoDiagnosticLoggingAdapter + /** Derives the correlation ID from the given WithDittoHeaders for the subsequent log operation. * * @param withDittoHeaders provides DittoHeaders which might contain the correlation ID to be put to the MDC. @@ -76,31 +84,6 @@ abstract class DittoDiagnosticLoggingAdapter extends AbstractDiagnosticLoggingAd */ def withCorrelationId(@Nullable dittoHeaders: DittoHeaders): DittoDiagnosticLoggingAdapter - /** Sets the given correlation ID for all subsequent log operations until it gets manually discarded. - * - * @param correlationId the correlation ID to be put to the MDC. - * @return this logger instance to allow method chaining. - */ - def setCorrelationId(@Nullable correlationId: CharSequence): DittoDiagnosticLoggingAdapter - - /** Derives the correlation ID from the given WithDittoHeaders for all subsequent log operations until it gets - * manually discarded. - * - * @param withDittoHeaders provides DittoHeaders which might contain the correlation ID to be put to the MDC. - * @return this logger instance to allow method chaining. - * @throws NullPointerException if `withDittoHeaders` is `null`. - */ - def setCorrelationId(withDittoHeaders: WithDittoHeaders): DittoDiagnosticLoggingAdapter - - /** Obtains the correlation ID from the given DittoHeaders for all subsequent log operations until it gets manually - * discarded. - * - * @param dittoHeaders might contain the correlation ID to be put to the MDC. - * @return this logger instance to allow method chaining. - * @throws NullPointerException if `dittoHeaders` is `null`. - */ - def setCorrelationId(dittoHeaders: DittoHeaders): DittoDiagnosticLoggingAdapter - /** Removes the correlation ID from the MDC for all subsequent log operations. */ def discardCorrelationId(): Unit @@ -164,14 +147,6 @@ abstract class DittoDiagnosticLoggingAdapter extends AbstractDiagnosticLoggingAd */ def discardMdcEntry(key: CharSequence): Unit - /** Sets the specified diagnostic context values as identified by the specified keys to this logger's MDC for all - * subsequent log operations until it gets manually discarded. - * - * @return this logger instance to allow method chaining. - * @throws NullPointerException if any argument is `null`. - */ - @annotation.varargs def setMdcEntry(mdcEntry: MdcEntry, furtherMdcEntries: MdcEntry*): DittoDiagnosticLoggingAdapter - /** Message template with > 4 replacement arguments. */ @varargs def error(throwable: Throwable, template: String, arg1: Any, arg2: Any, arg3: Any, arg4: Any, moreArgs: Any*): Unit = { if (isErrorEnabled) { diff --git a/internal/utils/pekko/src/main/scala/org/eclipse/ditto/internal/utils/pekko/logging/MdcEntrySettable.scala b/internal/utils/pekko/src/main/scala/org/eclipse/ditto/internal/utils/pekko/logging/MdcEntrySettable.scala index 0d2dde2344..4b19fc0227 100644 --- a/internal/utils/pekko/src/main/scala/org/eclipse/ditto/internal/utils/pekko/logging/MdcEntrySettable.scala +++ b/internal/utils/pekko/src/main/scala/org/eclipse/ditto/internal/utils/pekko/logging/MdcEntrySettable.scala @@ -12,6 +12,7 @@ */ package org.eclipse.ditto.internal.utils.pekko.logging +import java.util import javax.annotation.Nullable /** This trait defines the means to put and remove entries to or from the MDC of a logger. @@ -78,6 +79,14 @@ trait MdcEntrySettable[L] { */ @annotation.varargs def withMdcEntry(mdcEntry: MdcEntry, furtherMdcEntries: MdcEntry*): L + /** Puts the given entries to the MDC of this logger. + * + * @param mdcEntries the MDC entries to set. + * @return this or a new logger instance for method chaining. + * @throws NullPointerException if any argument is `null`. + */ + def withMdcEntries(mdcEntries: util.Collection[MdcEntry]): L + /** Removes the diagnostic context value identified by the specified key. * This method does nothing if there is no previous value associated with the specified key. * diff --git a/internal/utils/pekko/src/main/scala/org/eclipse/ditto/internal/utils/pekko/logging/ThreadSafeDittoLoggingAdapter.scala b/internal/utils/pekko/src/main/scala/org/eclipse/ditto/internal/utils/pekko/logging/ThreadSafeDittoLoggingAdapter.scala index 89a578601c..3870820a24 100644 --- a/internal/utils/pekko/src/main/scala/org/eclipse/ditto/internal/utils/pekko/logging/ThreadSafeDittoLoggingAdapter.scala +++ b/internal/utils/pekko/src/main/scala/org/eclipse/ditto/internal/utils/pekko/logging/ThreadSafeDittoLoggingAdapter.scala @@ -15,6 +15,7 @@ package org.eclipse.ditto.internal.utils.pekko.logging import org.apache.pekko.event.LoggingAdapter import org.eclipse.ditto.base.model.headers.{DittoHeaders, WithDittoHeaders} +import java.util import javax.annotation.Nullable import javax.annotation.concurrent.ThreadSafe @@ -77,6 +78,14 @@ abstract class ThreadSafeDittoLoggingAdapter extends LoggingAdapter */ def withCorrelationId(@Nullable correlationId: CharSequence): ThreadSafeDittoLoggingAdapter + /** Obtains the correlation ID from the given headers for the log operations on the returned logger. + * + * @param headers might contain the correlation ID to be put to the MDC. + * @return a ThreadSafeDittoLoggingAdapter which appends the derived correlation ID to all of its log operations. + * @see #withCorrelationId(DittoHeaders) + */ + def withCorrelationId(@Nullable headers: util.Map[String, String]): ThreadSafeDittoLoggingAdapter + /** Derives the correlation ID from the given WithDittoHeaders for the log operations on the returned logger. * If no or an empty correlation ID can be derived, this method has the same effect like * [[ThreadSafeDittoLoggingAdapter discardCorrelationId()]]. diff --git a/internal/utils/pekko/src/test/java/org/eclipse/ditto/internal/utils/pekko/logging/DefaultAutoCloseableSlf4jLoggerTest.java b/internal/utils/pekko/src/test/java/org/eclipse/ditto/internal/utils/pekko/logging/DefaultAutoCloseableSlf4jLoggerTest.java index 93141e4998..d8e4e6f846 100644 --- a/internal/utils/pekko/src/test/java/org/eclipse/ditto/internal/utils/pekko/logging/DefaultAutoCloseableSlf4jLoggerTest.java +++ b/internal/utils/pekko/src/test/java/org/eclipse/ditto/internal/utils/pekko/logging/DefaultAutoCloseableSlf4jLoggerTest.java @@ -132,7 +132,7 @@ public void logDebugAndWarnWithTwoMdcValuesThenClose() { entry(CORRELATION_ID_KEY, correlationId), entry(CONNECTION_ID_KEY, connectionId)); softly.assertThat(mdcObserver.getAllRemovedKeys()) .as("Removed MDC entries") - .containsExactly(CORRELATION_ID_KEY, CONNECTION_ID_KEY); + .contains(CORRELATION_ID_KEY, CONNECTION_ID_KEY); } @Test diff --git a/internal/utils/pekko/src/test/java/org/eclipse/ditto/internal/utils/pekko/logging/DefaultDittoDiagnosticLoggingAdapterTest.java b/internal/utils/pekko/src/test/java/org/eclipse/ditto/internal/utils/pekko/logging/DefaultDittoDiagnosticLoggingAdapterTest.java index adffaae9c8..20b8ac1d76 100644 --- a/internal/utils/pekko/src/test/java/org/eclipse/ditto/internal/utils/pekko/logging/DefaultDittoDiagnosticLoggingAdapterTest.java +++ b/internal/utils/pekko/src/test/java/org/eclipse/ditto/internal/utils/pekko/logging/DefaultDittoDiagnosticLoggingAdapterTest.java @@ -170,20 +170,6 @@ public void withTwoMdcEntriesLogWarning() { Mockito.verify(plainLoggingAdapter).setMDC(Map.of()); } - @Test - public void putNothingToMdcAndDoNotLogAsInfoIsDisabled() { - final String msg = "Foo!"; - Mockito.when(plainLoggingAdapter.isInfoEnabled()).thenReturn(false); - - final DefaultDittoDiagnosticLoggingAdapter underTest = - DefaultDittoDiagnosticLoggingAdapter.of(plainLoggingAdapter, LOGGER_NAME); - underTest.setCorrelationId(getCorrelationId()); - underTest.info(msg); - - Mockito.verify(plainLoggingAdapter, Mockito.times(0)).info(msg); - Mockito.verify(plainLoggingAdapter, Mockito.times(0)).setMDC(Mockito.anyMap()); - } - @Test public void logDebugAndWarnWithTwoMdcValuesThenDiscardMdcEntries() { final String correlationId = getCorrelationId(); @@ -246,62 +232,6 @@ public void removeMdcEntryViaNullValue() { Mockito.verify(plainLoggingAdapter).setMDC(Map.of(CONNECTION_ID_KEY, connectionId)); } - @Test - public void setCorrelationIdLogErrorDoNotDiscard() { - final String correlationId = getCorrelationId(); - final String msg = "Foo!"; - Mockito.when(plainLoggingAdapter.isErrorEnabled()).thenReturn(true); - - final DefaultDittoDiagnosticLoggingAdapter underTest = - DefaultDittoDiagnosticLoggingAdapter.of(plainLoggingAdapter, LOGGER_NAME); - underTest.setCorrelationId(correlationId); - underTest.error(msg); - - Mockito.verify(plainLoggingAdapter).isErrorEnabled(); - Mockito.verify(plainLoggingAdapter).getMDC(); - Mockito.verify(plainLoggingAdapter).setMDC(Map.of(CORRELATION_ID_KEY, correlationId)); - Mockito.verify(plainLoggingAdapter).notifyError(msg); - Mockito.verifyNoMoreInteractions(plainLoggingAdapter); - } - - @Test - public void setCorrelationIdLogErrorDoNotClose() { - final String correlationId = getCorrelationId(); - final String msg = "Foo!"; - Mockito.when(plainLoggingAdapter.isErrorEnabled()).thenReturn(true); - - final DefaultDittoDiagnosticLoggingAdapter underTest = - DefaultDittoDiagnosticLoggingAdapter.of(plainLoggingAdapter, LOGGER_NAME); - underTest.setCorrelationId(correlationId); - underTest.error(msg); - - Mockito.verify(plainLoggingAdapter).isErrorEnabled(); - Mockito.verify(plainLoggingAdapter).getMDC(); - Mockito.verify(plainLoggingAdapter).setMDC(Map.of(CORRELATION_ID_KEY, correlationId)); - Mockito.verify(plainLoggingAdapter).notifyError(msg); - Mockito.verifyNoMoreInteractions(plainLoggingAdapter); - } - - @Test - public void setCorrelationIdLogInfoThenDiscardCorrelationId() { - final String correlationId = getCorrelationId(); - final String msg1 = "Foo!"; - final String msg2 = "No correlation ID in MDC."; - Mockito.when(plainLoggingAdapter.isInfoEnabled()).thenReturn(true); - - final DefaultDittoDiagnosticLoggingAdapter underTest = - DefaultDittoDiagnosticLoggingAdapter.of(plainLoggingAdapter, LOGGER_NAME); - underTest.setCorrelationId(correlationId); - underTest.info(msg1); - underTest.discardCorrelationId(); - underTest.info(msg2); - - Mockito.verify(plainLoggingAdapter).setMDC(Map.of(CORRELATION_ID_KEY, correlationId)); - Mockito.verify(plainLoggingAdapter).notifyInfo(msg1); - Mockito.verify(plainLoggingAdapter).setMDC(Map.of()); - Mockito.verify(plainLoggingAdapter).notifyInfo(msg2); - } - @Test public void logMoreThan4LoggingArgsError() { final String template = "one: {}, two: {}, three: {}, four: {}, five: {}, six: {}"; diff --git a/internal/utils/persistence/src/test/resources/logback-test.xml b/internal/utils/persistence/src/test/resources/logback-test.xml index 01dc8d2353..95a966715a 100644 --- a/internal/utils/persistence/src/test/resources/logback-test.xml +++ b/internal/utils/persistence/src/test/resources/logback-test.xml @@ -5,14 +5,14 @@ - %date{ISO8601} %-5level [%X{x-correlation-id}] %logger{20} %X{pekkoSource} - %msg%n + %date{ISO8601} %-5level [%X{correlation-id}] %logger{20} %X{pekkoSource} - %msg%n System.err - %date{ISO8601} %-5level [%X{x-correlation-id}] %logger{20} %X{pekkoSource} - %msg%n + %date{ISO8601} %-5level [%X{correlation-id}] %logger{20} %X{pekkoSource} - %msg%n ERROR diff --git a/internal/utils/tracing/src/main/java/org/eclipse/ditto/internal/utils/tracing/span/KamonHttpContextPropagation.java b/internal/utils/tracing/src/main/java/org/eclipse/ditto/internal/utils/tracing/span/KamonHttpContextPropagation.java index 9fac417620..aa68cf1c96 100644 --- a/internal/utils/tracing/src/main/java/org/eclipse/ditto/internal/utils/tracing/span/KamonHttpContextPropagation.java +++ b/internal/utils/tracing/src/main/java/org/eclipse/ditto/internal/utils/tracing/span/KamonHttpContextPropagation.java @@ -99,7 +99,7 @@ public Context getContextFromHeaders(final Map headers) { public Map propagateContextToHeaders(final Context context, final Map headers) { checkNotNull(context, "context"); final var result = getMutableCopyOfMap(checkNotNull(headers, "headers")); - propagation.write(context, result::put); + propagation.write(context, result::putIfAbsent); return result; } diff --git a/policies/service/src/main/java/org/eclipse/ditto/policies/service/persistence/actors/announcements/PolicyAnnouncementAcknowledgementAggregatorActor.java b/policies/service/src/main/java/org/eclipse/ditto/policies/service/persistence/actors/announcements/PolicyAnnouncementAcknowledgementAggregatorActor.java index e2db7b7556..06bb50ba5b 100644 --- a/policies/service/src/main/java/org/eclipse/ditto/policies/service/persistence/actors/announcements/PolicyAnnouncementAcknowledgementAggregatorActor.java +++ b/policies/service/src/main/java/org/eclipse/ditto/policies/service/persistence/actors/announcements/PolicyAnnouncementAcknowledgementAggregatorActor.java @@ -64,7 +64,7 @@ private PolicyAnnouncementAcknowledgementAggregatorActor(final PolicyAnnouncemen aggregator = AcknowledgementAggregator.getInstance(policyAnnouncement.getEntityId(), correlationId, timeout, HeaderTranslator.empty()); aggregator.addAcknowledgementRequests(acknowledgementRequests); - log.withCorrelationId(correlationId) + log.withCorrelationId(dittoHeaders) .info("Starting to wait for all requested acknowledgements <{}> for a maximum duration of <{}>.", acknowledgementRequests, timeout); } diff --git a/policies/service/src/main/resources/logback.xml b/policies/service/src/main/resources/logback.xml index 11598d115c..a203eb8171 100755 --- a/policies/service/src/main/resources/logback.xml +++ b/policies/service/src/main/resources/logback.xml @@ -16,14 +16,14 @@ - %date{ISO8601} %-5level [%X{x-correlation-id}] %logger{20} %X{pekkoSource} - %msg%n + %date{ISO8601} %-5level [%X{correlation-id}][%X{traceparent-trace-id}] %logger{20} %X{pekkoSource} - %msg%n System.err - %date{ISO8601} %-5level [%X{x-correlation-id}] %logger{20} %X{pekkoSource} - %msg%n + %date{ISO8601} %-5level [%X{correlation-id}][%X{traceparent-trace-id}] %logger{20} %X{pekkoSource} - %msg%n ERROR diff --git a/things/service/src/main/java/org/eclipse/ditto/things/service/enforcement/PolicyIdReferencePlaceholderResolver.java b/things/service/src/main/java/org/eclipse/ditto/things/service/enforcement/PolicyIdReferencePlaceholderResolver.java index 3b1e3335ec..8238bdcbf8 100644 --- a/things/service/src/main/java/org/eclipse/ditto/things/service/enforcement/PolicyIdReferencePlaceholderResolver.java +++ b/things/service/src/main/java/org/eclipse/ditto/things/service/enforcement/PolicyIdReferencePlaceholderResolver.java @@ -23,7 +23,6 @@ import org.eclipse.ditto.base.model.exceptions.DittoInternalErrorException; import org.eclipse.ditto.base.model.exceptions.DittoRuntimeException; import org.eclipse.ditto.base.model.headers.DittoHeaders; -import org.eclipse.ditto.internal.utils.pekko.logging.AutoCloseableSlf4jLogger; import org.eclipse.ditto.internal.utils.pekko.logging.DittoLogger; import org.eclipse.ditto.internal.utils.pekko.logging.DittoLoggerFactory; import org.eclipse.ditto.internal.utils.cacheloaders.AskWithRetry; @@ -86,15 +85,14 @@ public CompletionStage resolve(final ReferencePlaceholder referencePlace final var resolveEntityReferenceStrategy = supportedEntityTypesToActionMap.get(referencePlaceholder.getReferencedEntityType()); - try (final AutoCloseableSlf4jLogger logger = LOGGER.setCorrelationId(dittoHeaders)) { - if (null == resolveEntityReferenceStrategy) { - final String referencedEntityType = referencePlaceholder.getReferencedEntityType().name(); - logger.info("Could not find a placeholder replacement strategy for entity type <{}> in supported" + - " entity types: {}", referencedEntityType, supportedEntityTypeNames); - throw notSupportedException(referencedEntityType, dittoHeaders); - } - logger.debug("Will resolve entity reference for placeholder: <{}>", referencePlaceholder); + final DittoLogger logger = LOGGER.withCorrelationId(dittoHeaders); + if (null == resolveEntityReferenceStrategy) { + final String referencedEntityType = referencePlaceholder.getReferencedEntityType().name(); + logger.info("Could not find a placeholder replacement strategy for entity type <{}> in supported" + + " entity types: {}", referencedEntityType, supportedEntityTypeNames); + throw notSupportedException(referencedEntityType, dittoHeaders); } + logger.debug("Will resolve entity reference for placeholder: <{}>", referencePlaceholder); return resolveEntityReferenceStrategy.handleEntityPolicyIdReference(referencePlaceholder, dittoHeaders); } diff --git a/things/service/src/main/java/org/eclipse/ditto/things/service/enforcement/ThingEnforcerActor.java b/things/service/src/main/java/org/eclipse/ditto/things/service/enforcement/ThingEnforcerActor.java index 62639c1a91..85067616c2 100644 --- a/things/service/src/main/java/org/eclipse/ditto/things/service/enforcement/ThingEnforcerActor.java +++ b/things/service/src/main/java/org/eclipse/ditto/things/service/enforcement/ThingEnforcerActor.java @@ -231,7 +231,7 @@ private CompletionStage> loadPolicyEnforcerForCreateThi return invalidatable.invalidate(PolicyTag.of(policy.getEntityId().get(), policy.getRevision().get().toLong()), correlationId, askWithRetryConfig.getAskTimeout()) .thenApply(bool -> { - log.withCorrelationId(correlationId) + log.withCorrelationId(createThing) .debug("PolicyEnforcerCache invalidated. Previous entity was present: {}", bool); return policy; diff --git a/things/service/src/main/java/org/eclipse/ditto/things/service/persistence/actors/SupervisorInlinePolicyEnrichment.java b/things/service/src/main/java/org/eclipse/ditto/things/service/persistence/actors/SupervisorInlinePolicyEnrichment.java index c2edcce263..32145855e5 100644 --- a/things/service/src/main/java/org/eclipse/ditto/things/service/persistence/actors/SupervisorInlinePolicyEnrichment.java +++ b/things/service/src/main/java/org/eclipse/ditto/things/service/persistence/actors/SupervisorInlinePolicyEnrichment.java @@ -18,8 +18,6 @@ import java.util.UUID; import java.util.concurrent.CompletionStage; -import javax.annotation.Nullable; - import org.eclipse.ditto.base.model.exceptions.DittoRuntimeException; import org.eclipse.ditto.base.model.headers.DittoHeaders; import org.eclipse.ditto.base.model.headers.WithDittoHeaders; @@ -189,21 +187,20 @@ private CompletionStage> retrieveInlinedPolicyF if (response instanceof RetrievePolicyResponse retrievePolicyResponse) { return Optional.of(retrievePolicyResponse); } else { - log.withCorrelationId(getCorrelationIdOrNull(response, retrievePolicy)) + log.withCorrelationId(getEffectiveHeaders(response, retrievePolicy)) .info("No authorized response when retrieving inlined policy <{}> for thing <{}>: {}", retrievePolicy.getEntityId(), thingId, response); return Optional.empty(); } } ).exceptionally(error -> { - log.withCorrelationId(getCorrelationIdOrNull(error, retrievePolicy)) + log.withCorrelationId(getEffectiveHeaders(error, retrievePolicy)) .error(error, "Retrieving inlined policy after RetrieveThing"); return Optional.empty(); }); } - @Nullable - private static CharSequence getCorrelationIdOrNull(final Object signal, final WithDittoHeaders fallBackSignal) { + private static DittoHeaders getEffectiveHeaders(final Object signal, final WithDittoHeaders fallBackSignal) { final WithDittoHeaders withDittoHeaders; if (isWithDittoHeaders(signal)) { @@ -211,8 +208,7 @@ private static CharSequence getCorrelationIdOrNull(final Object signal, final Wi } else { withDittoHeaders = fallBackSignal; } - final var dittoHeaders = withDittoHeaders.getDittoHeaders(); - return dittoHeaders.getCorrelationId().orElse(null); + return withDittoHeaders.getDittoHeaders(); } private static boolean isWithDittoHeaders(final Object o) { diff --git a/things/service/src/main/java/org/eclipse/ditto/things/service/persistence/actors/ThingSupervisorActor.java b/things/service/src/main/java/org/eclipse/ditto/things/service/persistence/actors/ThingSupervisorActor.java index 76b8db7835..6cd73ae28a 100755 --- a/things/service/src/main/java/org/eclipse/ditto/things/service/persistence/actors/ThingSupervisorActor.java +++ b/things/service/src/main/java/org/eclipse/ditto/things/service/persistence/actors/ThingSupervisorActor.java @@ -355,7 +355,7 @@ private void handleRollbackCreatedPolicy(final RollbackCreatedPolicy rollback) { final String correlationId = rollback.initialCommand().getDittoHeaders().getCorrelationId() .orElse("unexpected:" + UUID.randomUUID()); if (policyCreatedEvent != null) { - log.withCorrelationId(correlationId) + log.withCorrelationId(rollback.initialCommand()) .warning("Rolling back created policy as consequence of received RollbackCreatedPolicy " + "message: {}", rollback); final DittoHeaders dittoHeaders = DittoHeaders.newBuilder() @@ -366,19 +366,20 @@ private void handleRollbackCreatedPolicy(final RollbackCreatedPolicy rollback) { AskWithRetry.askWithRetry(policiesShardRegion, deletePolicy, enforcementConfig.getAskWithRetryConfig(), getContext().system(), response -> { - log.withCorrelationId(correlationId) + log.withCorrelationId(rollback.initialCommand()) .info("Policy <{}> deleted after rolling back it's creation. " + "Policies shard region response: <{}>", deletePolicy.getEntityId(), response); rollback.completeInitialResponse(); return response; }).exceptionally(throwable -> { - log.withCorrelationId(correlationId).error(throwable, "Failed to rollback Policy Create"); + log.withCorrelationId(rollback.initialCommand()) + .error(throwable, "Failed to rollback Policy Create"); rollback.completeInitialResponse(); return null; }); } else { - log.withCorrelationId(correlationId) + log.withCorrelationId(rollback.initialCommand()) .debug("Not initiating policy rollback as none was created."); rollback.completeInitialResponse(); } diff --git a/things/service/src/main/resources/logback.xml b/things/service/src/main/resources/logback.xml index 49aa8b4f82..4f6086340b 100755 --- a/things/service/src/main/resources/logback.xml +++ b/things/service/src/main/resources/logback.xml @@ -16,14 +16,14 @@ - %date{ISO8601} %-5level [%X{x-correlation-id}] %logger{20} %X{pekkoSource} - %msg%n + %date{ISO8601} %-5level [%X{correlation-id}][%X{traceparent-trace-id}] %logger{20} %X{pekkoSource} - %msg%n System.err - %date{ISO8601} %-5level [%X{x-correlation-id}] %logger{20} %X{pekkoSource} - %msg%n + %date{ISO8601} %-5level [%X{correlation-id}][%X{traceparent-trace-id}] %logger{20} %X{pekkoSource} - %msg%n ERROR diff --git a/things/service/src/test/resources/logback-test.xml b/things/service/src/test/resources/logback-test.xml index 129c7339d0..8f07693a11 100644 --- a/things/service/src/test/resources/logback-test.xml +++ b/things/service/src/test/resources/logback-test.xml @@ -20,7 +20,7 @@ - %date{ISO8601} %-5level [%X{x-correlation-id}] %logger{20‚} - %msg%n%rEx + %date{ISO8601} %-5level [%X{correlation-id}] %logger{20‚} - %msg%n%rEx diff --git a/thingsearch/service/src/main/resources/logback.xml b/thingsearch/service/src/main/resources/logback.xml index 9874fe302b..bf25257f5e 100755 --- a/thingsearch/service/src/main/resources/logback.xml +++ b/thingsearch/service/src/main/resources/logback.xml @@ -16,14 +16,14 @@ - %date{ISO8601} %-5level [%X{x-correlation-id}] %logger{20} %X{pekkoSource} - %msg%n + %date{ISO8601} %-5level [%X{correlation-id}][%X{traceparent-trace-id}] %logger{20} %X{pekkoSource} - %msg%n System.err - %date{ISO8601} %-5level [%X{x-correlation-id}] %logger{20} %X{pekkoSource} - %msg%n + %date{ISO8601} %-5level [%X{correlation-id}][%X{traceparent-trace-id}] %logger{20} %X{pekkoSource} - %msg%n ERROR diff --git a/thingsearch/service/src/test/resources/logback-test.xml b/thingsearch/service/src/test/resources/logback-test.xml index 9ab0e39ae3..63e44eb30e 100644 --- a/thingsearch/service/src/test/resources/logback-test.xml +++ b/thingsearch/service/src/test/resources/logback-test.xml @@ -17,14 +17,14 @@ - %date{ISO8601} %-5level [%X{x-correlation-id}] %logger{20} %X{pekkoSource} - %msg%n + %date{ISO8601} %-5level [%X{correlation-id}] %logger{20} %X{pekkoSource} - %msg%n System.err - %date{ISO8601} %-5level [%X{x-correlation-id}] %logger{20} %X{pekkoSource} - %msg%n + %date{ISO8601} %-5level [%X{correlation-id}] %logger{20} %X{pekkoSource} - %msg%n ERROR