From 21e0ed55a86f058a5d646b007a094e61aa569ecf Mon Sep 17 00:00:00 2001 From: Juergen Fickel Date: Wed, 27 Nov 2019 10:22:18 +0100 Subject: [PATCH] Introduced `DittoLogger` and `DittoDiagnosticLoggingAdapter` for making it more easy to enhance log messages with correlation ID than using LogUtil directly. Signed-off-by: Juergen Fickel --- .../logging/AutoCloseableSlf4jLogger.java | 29 ++ .../akka/logging/AutoClosingSlf4jLogger.java | 448 ++++++++++++++++++ ...utoDiscardingDiagnosticLoggingAdapter.java | 416 ++++++++++++++++ .../DefaultAutoCloseableSlf4jLogger.java | 357 ++++++++++++++ .../DefaultDiagnosticLoggingAdapter.java | 305 ++++++++++++ .../DefaultDittoDiagnosticLoggingAdapter.java | 363 ++++++++++++++ .../akka/logging/DefaultDittoLogger.java | 412 ++++++++++++++++ .../utils/akka/logging/DittoLogger.java | 132 ++++++ .../akka/logging/DittoLoggerFactory.java | 74 +++ .../utils/akka/logging/package-info.java | 14 + .../AbstractDiagnosticLoggingAdapter.scala | 28 ++ .../DittoDiagnosticLoggingAdapter.scala | 104 ++++ .../utils/akka/logging/package-info.java | 15 + 13 files changed, 2697 insertions(+) create mode 100644 services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/AutoCloseableSlf4jLogger.java create mode 100644 services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/AutoClosingSlf4jLogger.java create mode 100644 services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/AutoDiscardingDiagnosticLoggingAdapter.java create mode 100644 services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DefaultAutoCloseableSlf4jLogger.java create mode 100644 services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DefaultDiagnosticLoggingAdapter.java create mode 100644 services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DefaultDittoDiagnosticLoggingAdapter.java create mode 100644 services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DefaultDittoLogger.java create mode 100644 services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DittoLogger.java create mode 100644 services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DittoLoggerFactory.java create mode 100644 services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/package-info.java create mode 100644 services/utils/akka/src/main/scala/org/eclipse/ditto/services/utils/akka/logging/AbstractDiagnosticLoggingAdapter.scala create mode 100644 services/utils/akka/src/main/scala/org/eclipse/ditto/services/utils/akka/logging/DittoDiagnosticLoggingAdapter.scala create mode 100644 services/utils/akka/src/main/scala/org/eclipse/ditto/services/utils/akka/logging/package-info.java diff --git a/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/AutoCloseableSlf4jLogger.java b/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/AutoCloseableSlf4jLogger.java new file mode 100644 index 0000000000..e48070c835 --- /dev/null +++ b/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/AutoCloseableSlf4jLogger.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2019 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.services.utils.akka.logging; + +import javax.annotation.concurrent.NotThreadSafe; + +import org.slf4j.Logger; + +/** + * This interface represents a SLF4J {@link Logger} which additionally is {@link AutoCloseable}. + * The semantic of the {@link #close()} method is defined by its implementation. + */ +@NotThreadSafe +public interface AutoCloseableSlf4jLogger extends Logger, AutoCloseable { + + @Override + void close(); + +} diff --git a/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/AutoClosingSlf4jLogger.java b/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/AutoClosingSlf4jLogger.java new file mode 100644 index 0000000000..53dc7d5cc7 --- /dev/null +++ b/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/AutoClosingSlf4jLogger.java @@ -0,0 +1,448 @@ +/* + * Copyright (c) 2019 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.services.utils.akka.logging; + +import static org.eclipse.ditto.model.base.common.ConditionChecker.checkNotNull; + +import javax.annotation.concurrent.NotThreadSafe; + +import org.slf4j.Marker; + +/** + * This implementation of {@link AutoCloseableSlf4jLogger} discards the correlation ID automatically after each log + * operation. + */ +@NotThreadSafe +final class AutoClosingSlf4jLogger implements AutoCloseableSlf4jLogger { + + private final AutoCloseableSlf4jLogger autoCloseableSlf4jLogger; + + private AutoClosingSlf4jLogger(final AutoCloseableSlf4jLogger autoCloseableSlf4jLogger) { + this.autoCloseableSlf4jLogger = autoCloseableSlf4jLogger; + } + + public static AutoClosingSlf4jLogger of(final AutoCloseableSlf4jLogger autoCloseableSlf4jLogger) { + return new AutoClosingSlf4jLogger(checkNotNull(autoCloseableSlf4jLogger, "autoCloseableSlf4jLogger")); + } + + @Override + public String getName() { + return autoCloseableSlf4jLogger.getName(); + } + + @Override + public boolean isTraceEnabled() { + return autoCloseableSlf4jLogger.isTraceEnabled(); + } + + @Override + public void trace(final String msg) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.trace(msg); + } + } + + @Override + public void trace(final String format, final Object arg) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.trace(format, arg); + } + } + + @Override + public void trace(final String format, final Object arg1, final Object arg2) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.trace(format, arg1, arg2); + } + } + + @Override + public void trace(final String format, final Object... arguments) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.trace(format, arguments); + } + } + + @Override + public void trace(final String msg, final Throwable t) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.trace(msg, t); + } + } + + @Override + public boolean isTraceEnabled(final Marker marker) { + return autoCloseableSlf4jLogger.isTraceEnabled(marker); + } + + @Override + public void trace(final Marker marker, final String msg) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.trace(marker, msg); + } + } + + @Override + public void trace(final Marker marker, final String format, final Object arg) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.trace(marker, format, arg); + } + } + + @Override + public void trace(final Marker marker, final String format, final Object arg1, final Object arg2) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.trace(marker, format, arg1, arg2); + } + } + + @Override + public void trace(final Marker marker, final String format, final Object... argArray) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.trace(marker, format, argArray); + } + } + + @Override + public void trace(final Marker marker, final String msg, final Throwable t) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.trace(marker, msg, t); + } + } + + @Override + public boolean isDebugEnabled() { + return autoCloseableSlf4jLogger.isDebugEnabled(); + } + + @Override + public void debug(final String msg) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.debug(msg); + } + } + + @Override + public void debug(final String format, final Object arg) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.debug(format, arg); + } + } + + @Override + public void debug(final String format, final Object arg1, final Object arg2) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.debug(format, arg1, arg2); + } + } + + @Override + public void debug(final String format, final Object... arguments) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.debug(format, arguments); + } + } + + @Override + public void debug(final String msg, final Throwable t) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.debug(msg, t); + } + } + + @Override + public boolean isDebugEnabled(final Marker marker) { + return autoCloseableSlf4jLogger.isDebugEnabled(marker); + } + + @Override + public void debug(final Marker marker, final String msg) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.debug(marker, msg); + } + } + + @Override + public void debug(final Marker marker, final String format, final Object arg) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.debug(marker, format, arg); + } + } + + @Override + public void debug(final Marker marker, final String format, final Object arg1, final Object arg2) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.debug(marker, format, arg1, arg2); + } + } + + @Override + public void debug(final Marker marker, final String format, final Object... arguments) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.debug(marker, format, arguments); + } + } + + @Override + public void debug(final Marker marker, final String msg, final Throwable t) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.debug(marker, msg, t); + } + } + + @Override + public boolean isInfoEnabled() { + return autoCloseableSlf4jLogger.isInfoEnabled(); + } + + @Override + public void info(final String msg) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.info(msg); + } + } + + @Override + public void info(final String format, final Object arg) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.info(format, arg); + } + } + + @Override + public void info(final String format, final Object arg1, final Object arg2) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.info(format, arg1, arg2); + } + } + + @Override + public void info(final String format, final Object... arguments) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.info(format, arguments); + } + } + + @Override + public void info(final String msg, final Throwable t) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.info(msg, t); + } + } + + @Override + public boolean isInfoEnabled(final Marker marker) { + return autoCloseableSlf4jLogger.isInfoEnabled(marker); + } + + @Override + public void info(final Marker marker, final String msg) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.info(marker, msg); + } + } + + @Override + public void info(final Marker marker, final String format, final Object arg) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.info(marker, format, arg); + } + } + + @Override + public void info(final Marker marker, final String format, final Object arg1, final Object arg2) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.info(marker, format, arg1, arg2); + } + } + + @Override + public void info(final Marker marker, final String format, final Object... arguments) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.info(marker, format, arguments); + } + } + + @Override + public void info(final Marker marker, final String msg, final Throwable t) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.info(marker, msg, t); + } + } + + @Override + public boolean isWarnEnabled() { + return autoCloseableSlf4jLogger.isWarnEnabled(); + } + + @Override + public void warn(final String msg) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.warn(msg); + } + } + + @Override + public void warn(final String format, final Object arg) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.warn(format, arg); + } + } + + @Override + public void warn(final String format, final Object... arguments) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.warn(format, arguments); + } + } + + @Override + public void warn(final String format, final Object arg1, final Object arg2) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.warn(format, arg1, arg2); + } + } + + @Override + public void warn(final String msg, final Throwable t) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.warn(msg, t); + } + } + + @Override + public boolean isWarnEnabled(final Marker marker) { + return autoCloseableSlf4jLogger.isWarnEnabled(marker); + } + + @Override + public void warn(final Marker marker, final String msg) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.warn(marker, msg); + } + } + + @Override + public void warn(final Marker marker, final String format, final Object arg) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.warn(marker, format, arg); + } + } + + @Override + public void warn(final Marker marker, final String format, final Object arg1, final Object arg2) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.warn(marker, format, arg1, arg2); + } + } + + @Override + public void warn(final Marker marker, final String format, final Object... arguments) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.warn(marker, format, arguments); + } + } + + @Override + public void warn(final Marker marker, final String msg, final Throwable t) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.warn(marker, msg, t); + } + } + + @Override + public boolean isErrorEnabled() { + return autoCloseableSlf4jLogger.isErrorEnabled(); + } + + @Override + public void error(final String msg) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.error(msg); + } + } + + @Override + public void error(final String format, final Object arg) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.error(format, arg); + } + } + + @Override + public void error(final String format, final Object arg1, final Object arg2) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.error(format, arg1, arg2); + } + } + + @Override + public void error(final String format, final Object... arguments) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.error(format, arguments); + } + } + + @Override + public void error(final String msg, final Throwable t) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.error(msg, t); + } + } + + @Override + public boolean isErrorEnabled(final Marker marker) { + return autoCloseableSlf4jLogger.isErrorEnabled(marker); + } + + @Override + public void error(final Marker marker, final String msg) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.error(marker, msg); + } + } + + @Override + public void error(final Marker marker, final String format, final Object arg) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.error(marker, format, arg); + } + } + + @Override + public void error(final Marker marker, final String format, final Object arg1, final Object arg2) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.error(marker, format, arg1, arg2); + } + } + + @Override + public void error(final Marker marker, final String format, final Object... arguments) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.error(marker, format, arguments); + } + } + + @Override + public void error(final Marker marker, final String msg, final Throwable t) { + try (final AutoCloseableSlf4jLogger l = autoCloseableSlf4jLogger) { + l.error(marker, msg, t); + } + } + + @Override + public void close() { + autoCloseableSlf4jLogger.close(); + } + +} diff --git a/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/AutoDiscardingDiagnosticLoggingAdapter.java b/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/AutoDiscardingDiagnosticLoggingAdapter.java new file mode 100644 index 0000000000..1434a45910 --- /dev/null +++ b/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/AutoDiscardingDiagnosticLoggingAdapter.java @@ -0,0 +1,416 @@ +/* + * Copyright (c) 2019 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.services.utils.akka.logging; + +import static org.eclipse.ditto.model.base.common.ConditionChecker.checkNotNull; + +import java.util.Map; + +import javax.annotation.concurrent.NotThreadSafe; + +import scala.collection.Seq; + +/** + * This implementation of {@link AbstractDiagnosticLoggingAdapter} discards the correlation ID automatically after + * each log operation. + */ +@NotThreadSafe +final class AutoDiscardingDiagnosticLoggingAdapter extends AbstractDiagnosticLoggingAdapter { + + private final AbstractDiagnosticLoggingAdapter loggingAdapter; + + private AutoDiscardingDiagnosticLoggingAdapter(final AbstractDiagnosticLoggingAdapter loggingAdapter) { + this.loggingAdapter = checkNotNull(loggingAdapter, "loggingAdapter"); + } + + public static AutoDiscardingDiagnosticLoggingAdapter of(final AbstractDiagnosticLoggingAdapter loggingAdapter) { + return new AutoDiscardingDiagnosticLoggingAdapter(loggingAdapter); + } + + @Override + public boolean isErrorEnabled() { + return loggingAdapter.isErrorEnabled(); + } + + @Override + public boolean isWarningEnabled() { + return loggingAdapter.isWarningEnabled(); + } + + @Override + public boolean isInfoEnabled() { + return loggingAdapter.isInfoEnabled(); + } + + @Override + public boolean isDebugEnabled() { + return loggingAdapter.isDebugEnabled(); + } + + @Override + public void notifyError(final String message) { + try { + loggingAdapter.notifyError(message); + } finally { + discardCorrelationId(); + } + } + + @Override + public void notifyError(final Throwable cause, final String message) { + try { + loggingAdapter.notifyError(cause, message); + } finally { + discardCorrelationId(); + } + } + + @Override + public void notifyWarning(final String message) { + try { + loggingAdapter.notifyWarning(message); + } finally { + discardCorrelationId(); + } + } + + @Override + public void notifyInfo(final String message) { + try { + loggingAdapter.notifyInfo(message); + } finally { + discardCorrelationId(); + } + } + + @Override + public void notifyDebug(final String message) { + try { + loggingAdapter.notifyDebug(message); + } finally { + discardCorrelationId(); + } + } + + @Override + public void error(final Throwable cause, final String message) { + try { + loggingAdapter.error(cause, message); + } finally { + discardCorrelationId(); + } + } + + @Override + public void error(final Throwable cause, final String template, final Object arg1) { + try { + loggingAdapter.error(cause, template, arg1); + } finally { + discardCorrelationId(); + } + } + + @Override + public void error(final Throwable cause, + final String template, + final Object arg1, + final Object arg2) { + + try { + loggingAdapter.error(cause, template, arg1, arg2); + } finally { + discardCorrelationId(); + } + } + + @Override + public void error(final Throwable cause, + final String template, + final Object arg1, + final Object arg2, + final Object arg3) { + + try { + loggingAdapter.error(cause, template, arg1, arg2, arg3); + } finally { + discardCorrelationId(); + } + } + + @Override + public void error(final Throwable cause, + final String template, + final Object arg1, + final Object arg2, + final Object arg3, + final Object arg4) { + + try { + loggingAdapter.error(cause, template, arg1, arg2, arg3, arg4); + } finally { + discardCorrelationId(); + } + } + + @Override + public void error(final String message) { + try { + loggingAdapter.error(message); + } finally { + discardCorrelationId(); + } + } + + @Override + public void error(final String template, final Object arg1) { + try { + loggingAdapter.error(template, arg1); + } finally { + discardCorrelationId(); + } + } + + @Override + public void error(final String template, final Object arg1, final Object arg2) { + try { + loggingAdapter.error(template, arg1, arg2); + } finally { + discardCorrelationId(); + } + } + + @Override + public void error(final String template, + final Object arg1, + final Object arg2, + final Object arg3) { + + try { + loggingAdapter.error(template, arg1, arg2, arg3); + } finally { + discardCorrelationId(); + } + } + + @Override + public void error(final String template, + final Object arg1, + final Object arg2, + final Object arg3, + final Object arg4) { + + try { + loggingAdapter.error(template, arg1, arg2, arg3, arg4); + } finally { + discardCorrelationId(); + } + } + + @Override + public void warning(final String message) { + try { + loggingAdapter.warning(message); + } finally { + discardCorrelationId(); + } + } + + @Override + public void warning(final String template, final Object arg1) { + try { + loggingAdapter.warning(template, arg1); + } finally { + discardCorrelationId(); + } + } + + @Override + public void warning(final String template, final Object arg1, final Object arg2) { + try { + loggingAdapter.warning(template, arg1, arg2); + } finally { + discardCorrelationId(); + } + } + + @Override + public void warning(final String template, + final Object arg1, + final Object arg2, + final Object arg3) { + + try { + loggingAdapter.warning(template, arg1, arg2, arg3); + } finally { + discardCorrelationId(); + } + } + + @Override + public void warning(final String template, + final Object arg1, + final Object arg2, + final Object arg3, + final Object arg4) { + + try { + loggingAdapter.warning(template, arg1, arg2, arg3, arg4); + } finally { + discardCorrelationId(); + } + } + + @Override + public void info(final String message) { + try { + loggingAdapter.info(message); + } finally { + discardCorrelationId(); + } + } + + @Override + public void info(final String template, final Object arg1) { + try { + loggingAdapter.info(template, arg1); + } finally { + discardCorrelationId(); + } + } + + @Override + public void info(final String template, final Object arg1, final Object arg2) { + try { + loggingAdapter.info(template, arg1, arg2); + } finally { + discardCorrelationId(); + } + } + + @Override + public void info(final String template, + final Object arg1, + final Object arg2, + final Object arg3) { + + try { + loggingAdapter.info(template, arg1, arg2, arg3); + } finally { + discardCorrelationId(); + } + } + + @Override + public void info(final String template, + final Object arg1, + final Object arg2, + final Object arg3, + final Object arg4) { + + try { + loggingAdapter.info(template, arg1, arg2, arg3, arg4); + } finally { + discardCorrelationId(); + } + } + + @Override + public void debug(final String message) { + try { + loggingAdapter.debug(message); + } finally { + discardCorrelationId(); + } + } + + @Override + public void debug(final String template, final Object arg1) { + try { + loggingAdapter.debug(template, arg1); + } finally { + discardCorrelationId(); + } + } + + @Override + public void debug(final String template, final Object arg1, final Object arg2) { + try { + loggingAdapter.debug(template, arg1, arg2); + } finally { + discardCorrelationId(); + } + } + + @Override + public void debug(final String template, + final Object arg1, + final Object arg2, + final Object arg3) { + + try { + loggingAdapter.debug(template, arg1, arg2, arg3); + } finally { + discardCorrelationId(); + } + } + + @Override + public void debug(final String template, + final Object arg1, + final Object arg2, + final Object arg3, + final Object arg4) { + + try { + loggingAdapter.debug(template, arg1, arg2, arg3, arg4); + } finally { + discardCorrelationId(); + } + } + + @Override + public String format(final String t, final Seq arg) { + return loggingAdapter.format(t, arg); + } + + @Override + public scala.collection.immutable.Map mdc() { + return loggingAdapter.mdc(); + } + + @Override + public void mdc(final scala.collection.immutable.Map mdc) { + loggingAdapter.mdc(mdc); + } + + @Override + public Map getMDC() { + return loggingAdapter.getMDC(); + } + + @Override + public void setMDC(final Map jMdc) { + loggingAdapter.setMDC(jMdc); + } + + @Override + public void clearMDC() { + loggingAdapter.clearMDC(); + } + + @Override + public void discardCorrelationId() { + loggingAdapter.discardCorrelationId(); + } + +} diff --git a/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DefaultAutoCloseableSlf4jLogger.java b/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DefaultAutoCloseableSlf4jLogger.java new file mode 100644 index 0000000000..a79f74708a --- /dev/null +++ b/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DefaultAutoCloseableSlf4jLogger.java @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2019 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.services.utils.akka.logging; + +import static org.eclipse.ditto.model.base.common.ConditionChecker.checkNotNull; + +import javax.annotation.concurrent.NotThreadSafe; + +import org.eclipse.ditto.services.utils.akka.LogUtil; +import org.slf4j.Logger; +import org.slf4j.Marker; + +/** + * This implementation of {@link AutoCloseableSlf4jLogger} wraps and delegates to a {@link Logger}. + * Furthermore it provides the means to discard the correlation ID. + */ +@NotThreadSafe +final class DefaultAutoCloseableSlf4jLogger implements AutoCloseableSlf4jLogger { + + private final Logger actualSlf4jLogger; + + private DefaultAutoCloseableSlf4jLogger(final Logger actualSlf4jLogger) { + this.actualSlf4jLogger = actualSlf4jLogger; + } + + /** + * Returns an instance of an auto-closeable SLF4J logger. + * + * @param logger the actual SLF4J logger to delegate all logging to. + * @return the instance + * @throws NullPointerException if {@code logger} is {@code null}. + */ + public static DefaultAutoCloseableSlf4jLogger of(final Logger logger) { + return new DefaultAutoCloseableSlf4jLogger(checkNotNull(logger, "logger")); + } + + @Override + public String getName() { + return actualSlf4jLogger.getName(); + } + + @Override + public boolean isTraceEnabled() { + return actualSlf4jLogger.isTraceEnabled(); + } + + @Override + public void trace(final String msg) { + actualSlf4jLogger.trace(msg); + } + + @Override + public void trace(final String format, final Object arg) { + actualSlf4jLogger.trace(format, arg); + } + + @Override + public void trace(final String format, final Object arg1, final Object arg2) { + actualSlf4jLogger.trace(format, arg1, arg2); + } + + @Override + public void trace(final String format, final Object... arguments) { + actualSlf4jLogger.trace(format, arguments); + } + + @Override + public void trace(final String msg, final Throwable t) { + actualSlf4jLogger.trace(msg, t); + } + + @Override + public boolean isTraceEnabled(final Marker marker) { + return actualSlf4jLogger.isTraceEnabled(marker); + } + + @Override + public void trace(final Marker marker, final String msg) { + actualSlf4jLogger.trace(marker, msg); + } + + @Override + public void trace(final Marker marker, final String format, final Object arg) { + actualSlf4jLogger.trace(marker, format, arg); + } + + @Override + public void trace(final Marker marker, final String format, final Object arg1, final Object arg2) { + actualSlf4jLogger.trace(marker, format, arg1, arg2); + } + + @Override + public void trace(final Marker marker, final String format, final Object... argArray) { + actualSlf4jLogger.trace(marker, format, argArray); + } + + @Override + public void trace(final Marker marker, final String msg, final Throwable t) { + actualSlf4jLogger.trace(marker, msg, t); + } + + @Override + public boolean isDebugEnabled() { + return actualSlf4jLogger.isDebugEnabled(); + } + + @Override + public void debug(final String msg) { + actualSlf4jLogger.debug(msg); + } + + @Override + public void debug(final String format, final Object arg) { + actualSlf4jLogger.debug(format, arg); + } + + @Override + public void debug(final String format, final Object arg1, final Object arg2) { + actualSlf4jLogger.debug(format, arg1, arg2); + } + + @Override + public void debug(final String format, final Object... arguments) { + actualSlf4jLogger.debug(format, arguments); + } + + @Override + public void debug(final String msg, final Throwable t) { + actualSlf4jLogger.debug(msg, t); + } + + @Override + public boolean isDebugEnabled(final Marker marker) { + return actualSlf4jLogger.isDebugEnabled(marker); + } + + @Override + public void debug(final Marker marker, final String msg) { + actualSlf4jLogger.debug(marker, msg); + } + + @Override + public void debug(final Marker marker, final String format, final Object arg) { + actualSlf4jLogger.debug(marker, format, arg); + } + + @Override + public void debug(final Marker marker, final String format, final Object arg1, final Object arg2) { + actualSlf4jLogger.debug(marker, format, arg1, arg2); + } + + @Override + public void debug(final Marker marker, final String format, final Object... arguments) { + actualSlf4jLogger.debug(marker, format, arguments); + } + + @Override + public void debug(final Marker marker, final String msg, final Throwable t) { + actualSlf4jLogger.debug(marker, msg, t); + } + + @Override + public boolean isInfoEnabled() { + return actualSlf4jLogger.isInfoEnabled(); + } + + @Override + public void info(final String msg) { + actualSlf4jLogger.info(msg); + } + + @Override + public void info(final String format, final Object arg) { + actualSlf4jLogger.info(format, arg); + } + + @Override + public void info(final String format, final Object arg1, final Object arg2) { + actualSlf4jLogger.info(format, arg1, arg2); + } + + @Override + public void info(final String format, final Object... arguments) { + actualSlf4jLogger.info(format, arguments); + } + + @Override + public void info(final String msg, final Throwable t) { + actualSlf4jLogger.info(msg, t); + } + + @Override + public boolean isInfoEnabled(final Marker marker) { + return actualSlf4jLogger.isInfoEnabled(marker); + } + + @Override + public void info(final Marker marker, final String msg) { + actualSlf4jLogger.info(marker, msg); + } + + @Override + public void info(final Marker marker, final String format, final Object arg) { + actualSlf4jLogger.info(marker, format, arg); + } + + @Override + public void info(final Marker marker, final String format, final Object arg1, final Object arg2) { + actualSlf4jLogger.info(marker, format, arg1, arg2); + } + + @Override + public void info(final Marker marker, final String format, final Object... arguments) { + actualSlf4jLogger.info(marker, format, arguments); + } + + @Override + public void info(final Marker marker, final String msg, final Throwable t) { + actualSlf4jLogger.info(marker, msg, t); + } + + @Override + public boolean isWarnEnabled() { + return actualSlf4jLogger.isWarnEnabled(); + } + + @Override + public void warn(final String msg) { + actualSlf4jLogger.warn(msg); + } + + @Override + public void warn(final String format, final Object arg) { + actualSlf4jLogger.warn(format, arg); + } + + @Override + public void warn(final String format, final Object... arguments) { + actualSlf4jLogger.warn(format, arguments); + } + + @Override + public void warn(final String format, final Object arg1, final Object arg2) { + actualSlf4jLogger.warn(format, arg1, arg2); + } + + @Override + public void warn(final String msg, final Throwable t) { + actualSlf4jLogger.warn(msg, t); + } + + @Override + public boolean isWarnEnabled(final Marker marker) { + return actualSlf4jLogger.isWarnEnabled(marker); + } + + @Override + public void warn(final Marker marker, final String msg) { + actualSlf4jLogger.warn(marker, msg); + } + + @Override + public void warn(final Marker marker, final String format, final Object arg) { + actualSlf4jLogger.warn(marker, format, arg); + } + + @Override + public void warn(final Marker marker, final String format, final Object arg1, final Object arg2) { + actualSlf4jLogger.warn(marker, format, arg1, arg2); + } + + @Override + public void warn(final Marker marker, final String format, final Object... arguments) { + actualSlf4jLogger.warn(marker, format, arguments); + } + + @Override + public void warn(final Marker marker, final String msg, final Throwable t) { + actualSlf4jLogger.warn(marker, msg, t); + } + + @Override + public boolean isErrorEnabled() { + return actualSlf4jLogger.isErrorEnabled(); + } + + @Override + public void error(final String msg) { + actualSlf4jLogger.error(msg); + } + + @Override + public void error(final String format, final Object arg) { + actualSlf4jLogger.error(format, arg); + } + + @Override + public void error(final String format, final Object arg1, final Object arg2) { + actualSlf4jLogger.error(format, arg1, arg2); + } + + @Override + public void error(final String format, final Object... arguments) { + actualSlf4jLogger.error(format, arguments); + } + + @Override + public void error(final String msg, final Throwable t) { + actualSlf4jLogger.error(msg, t); + } + + @Override + public boolean isErrorEnabled(final Marker marker) { + return actualSlf4jLogger.isErrorEnabled(marker); + } + + @Override + public void error(final Marker marker, final String msg) { + actualSlf4jLogger.error(marker, msg); + } + + @Override + public void error(final Marker marker, final String format, final Object arg) { + actualSlf4jLogger.error(marker, format, arg); + } + + @Override + public void error(final Marker marker, final String format, final Object arg1, final Object arg2) { + actualSlf4jLogger.error(marker, format, arg1, arg2); + } + + @Override + public void error(final Marker marker, final String format, final Object... arguments) { + actualSlf4jLogger.error(marker, format, arguments); + } + + @Override + public void error(final Marker marker, final String msg, final Throwable t) { + actualSlf4jLogger.error(marker, msg, t); + } + + @Override + public void close() { + LogUtil.removeCorrelationId(); + } + +} diff --git a/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DefaultDiagnosticLoggingAdapter.java b/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DefaultDiagnosticLoggingAdapter.java new file mode 100644 index 0000000000..6499a6c57c --- /dev/null +++ b/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DefaultDiagnosticLoggingAdapter.java @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2019 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.services.utils.akka.logging; + +import static org.eclipse.ditto.model.base.common.ConditionChecker.checkNotNull; + +import javax.annotation.concurrent.NotThreadSafe; + +import org.eclipse.ditto.services.utils.akka.LogUtil; + +import akka.event.DiagnosticLoggingAdapter; +import scala.collection.Seq; +import scala.collection.immutable.Map; + +/** + * Wraps and delegates to a {@link DiagnosticLoggingAdapter}. + * Furthermore it provides the means to discard the correlation ID. + */ +@NotThreadSafe +final class DefaultDiagnosticLoggingAdapter extends AbstractDiagnosticLoggingAdapter { + + private final DiagnosticLoggingAdapter loggingAdapter; + + private DefaultDiagnosticLoggingAdapter(final DiagnosticLoggingAdapter loggingAdapter) { + this.loggingAdapter = checkNotNull(loggingAdapter, "loggingAdapter"); + } + + /** + * Returns an instance of this class. + * + * @param loggingAdapter the actual DiagnosticLoggingAdapter to delegate to. + * @return the instance. + * @throws NullPointerException if {@code loggingAdapter} is {@code null}. + */ + public static DefaultDiagnosticLoggingAdapter of(final DiagnosticLoggingAdapter loggingAdapter) { + return new DefaultDiagnosticLoggingAdapter(loggingAdapter); + } + + @Override + public boolean isErrorEnabled() { + return loggingAdapter.isErrorEnabled(); + } + + @Override + public boolean isWarningEnabled() { + return loggingAdapter.isWarningEnabled(); + } + + @Override + public boolean isInfoEnabled() { + return loggingAdapter.isInfoEnabled(); + } + + @Override + public boolean isDebugEnabled() { + return loggingAdapter.isDebugEnabled(); + } + + @Override + public void notifyError(final String message) { + loggingAdapter.notifyError(message); + } + + @Override + public void notifyError(final Throwable cause, final String message) { + loggingAdapter.notifyError(cause, message); + } + + @Override + public void notifyWarning(final String message) { + loggingAdapter.notifyWarning(message); + } + + @Override + public void notifyInfo(final String message) { + loggingAdapter.notifyInfo(message); + } + + @Override + public void notifyDebug(final String message) { + loggingAdapter.notifyDebug(message); + } + + @Override + public void error(final Throwable cause, final String message) { + loggingAdapter.error(cause, message); + } + + @Override + public void error(final Throwable cause, final String template, final Object arg1) { + loggingAdapter.error(cause, template, arg1); + } + + @Override + public void error(final Throwable cause, + final String template, + final Object arg1, + final Object arg2) { + + loggingAdapter.error(cause, template, arg1, arg2); + } + + @Override + public void error(final Throwable cause, + final String template, + final Object arg1, + final Object arg2, + final Object arg3) { + + loggingAdapter.error(cause, template, arg1, arg2, arg3); + } + + @Override + public void error(final Throwable cause, + final String template, + final Object arg1, + final Object arg2, + final Object arg3, + final Object arg4) { + + loggingAdapter.error(cause, template, arg1, arg2, arg3, arg4); + } + + @Override + public void error(final String message) { + loggingAdapter.error(message); + } + + @Override + public void error(final String template, final Object arg1) { + loggingAdapter.error(template, arg1); + } + + @Override + public void error(final String template, final Object arg1, final Object arg2) { + loggingAdapter.error(template, arg1, arg2); + } + + @Override + public void error(final String template, + final Object arg1, + final Object arg2, + final Object arg3) { + + loggingAdapter.error(template, arg1, arg2, arg3); + } + + @Override + public void error(final String template, + final Object arg1, + final Object arg2, + final Object arg3, + final Object arg4) { + + loggingAdapter.error(template, arg1, arg2, arg3, arg4); + } + + @Override + public void warning(final String message) { + loggingAdapter.warning(message); + } + + @Override + public void warning(final String template, final Object arg1) { + loggingAdapter.warning(template, arg1); + } + + @Override + public void warning(final String template, final Object arg1, final Object arg2) { + loggingAdapter.warning(template, arg1, arg2); + } + + @Override + public void warning(final String template, + final Object arg1, + final Object arg2, + final Object arg3) { + + loggingAdapter.warning(template, arg1, arg2, arg3); + } + + @Override + public void warning(final String template, + final Object arg1, + final Object arg2, + final Object arg3, + final Object arg4) { + + loggingAdapter.warning(template, arg1, arg2, arg3, arg4); + } + + @Override + public void info(final String message) { + loggingAdapter.info(message); + } + + @Override + public void info(final String template, final Object arg1) { + loggingAdapter.info(template, arg1); + } + + @Override + public void info(final String template, final Object arg1, final Object arg2) { + loggingAdapter.info(template, arg1, arg2); + } + + @Override + public void info(final String template, + final Object arg1, + final Object arg2, + final Object arg3) { + + loggingAdapter.info(template, arg1, arg2, arg3); + } + + @Override + public void info(final String template, + final Object arg1, + final Object arg2, + final Object arg3, + final Object arg4) { + + loggingAdapter.info(template, arg1, arg2, arg3, arg4); + } + + @Override + public void debug(final String message) { + loggingAdapter.debug(message); + } + + @Override + public void debug(final String template, final Object arg1) { + loggingAdapter.debug(template, arg1); + } + + @Override + public void debug(final String template, final Object arg1, final Object arg2) { + loggingAdapter.debug(template, arg1, arg2); + } + + @Override + public void debug(final String template, + final Object arg1, + final Object arg2, + final Object arg3) { + + loggingAdapter.debug(template, arg1, arg2, arg3); + } + + @Override + public void debug(final String template, + final Object arg1, + final Object arg2, + final Object arg3, + final Object arg4) { + + loggingAdapter.debug(template, arg1, arg2, arg3, arg4); + } + + @Override + public String format(final String t, final Seq arg) { + return loggingAdapter.format(t, arg); + } + + @Override + public Map mdc() { + return loggingAdapter.mdc(); + } + + @Override + public void mdc(final Map mdc) { + loggingAdapter.mdc(mdc); + } + + @Override + public java.util.Map getMDC() { + return loggingAdapter.getMDC(); + } + + @Override + public void setMDC(final java.util.Map jMdc) { + loggingAdapter.setMDC(jMdc); + } + + @Override + public void clearMDC() { + loggingAdapter.clearMDC(); + } + + @Override + public void discardCorrelationId() { + LogUtil.removeCustomField(loggingAdapter, LogUtil.X_CORRELATION_ID); + } + +} diff --git a/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DefaultDittoDiagnosticLoggingAdapter.java b/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DefaultDittoDiagnosticLoggingAdapter.java new file mode 100644 index 0000000000..47d9a4e8ae --- /dev/null +++ b/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DefaultDittoDiagnosticLoggingAdapter.java @@ -0,0 +1,363 @@ +/* + * Copyright (c) 2019 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.services.utils.akka.logging; + +import static org.eclipse.ditto.model.base.common.ConditionChecker.checkNotNull; + +import java.util.Map; + +import javax.annotation.Nullable; +import javax.annotation.concurrent.NotThreadSafe; + +import org.eclipse.ditto.model.base.headers.DittoHeaders; +import org.eclipse.ditto.model.base.headers.WithDittoHeaders; +import org.eclipse.ditto.services.utils.akka.LogUtil; + +import akka.event.DiagnosticLoggingAdapter; +import scala.collection.Seq; + +/** + * Default implementation of {@link DittoDiagnosticLoggingAdapter}. + * It harnesses the state pattern for determining how long a particular correlation ID is valid. + */ +@NotThreadSafe +final class DefaultDittoDiagnosticLoggingAdapter extends DittoDiagnosticLoggingAdapter { + + private final AbstractDiagnosticLoggingAdapter loggingAdapter; + private final AbstractDiagnosticLoggingAdapter autoDiscardingLoggingAdapter; + private AbstractDiagnosticLoggingAdapter currentLogger; + + private DefaultDittoDiagnosticLoggingAdapter(final AbstractDiagnosticLoggingAdapter loggingAdapter, + final AbstractDiagnosticLoggingAdapter autoDiscardingLoggingAdapter) { + + this.loggingAdapter = loggingAdapter; + this.autoDiscardingLoggingAdapter = autoDiscardingLoggingAdapter; + currentLogger = loggingAdapter; + } + + /** + * Returns an instance of the default Ditto DiagnosticLoggingAdapter. + * + * @param diagnosticLoggingAdapter the Akka DiagnosticLoggingAdapter which performs the actual logging. + * @return the instance. + * @throws NullPointerException if {@code diagnosticLoggingAdapter} is {@code null}. + */ + public static DefaultDittoDiagnosticLoggingAdapter of(final DiagnosticLoggingAdapter diagnosticLoggingAdapter) { + final DefaultDiagnosticLoggingAdapter loggingAdapter = + DefaultDiagnosticLoggingAdapter.of(diagnosticLoggingAdapter); + + return new DefaultDittoDiagnosticLoggingAdapter(loggingAdapter, + AutoDiscardingDiagnosticLoggingAdapter.of(loggingAdapter)); + } + + @Override + public DefaultDittoDiagnosticLoggingAdapter withCorrelationId(final CharSequence correlationId) { + currentLogger = autoDiscardingLoggingAdapter; + setCorrelationId(null != correlationId ? correlationId.toString() : null); + return this; + } + + @Override + public DefaultDittoDiagnosticLoggingAdapter withCorrelationId(final WithDittoHeaders withDittoHeaders) { + return withCorrelationId(checkNotNull(withDittoHeaders, "withDittoHeaders").getDittoHeaders()); + } + + @Override + public DefaultDittoDiagnosticLoggingAdapter withCorrelationId(final DittoHeaders dittoHeaders) { + checkNotNull(dittoHeaders, "dittoHeaders"); + currentLogger = autoDiscardingLoggingAdapter; + setCorrelationId(dittoHeaders.getCorrelationId().orElse(null)); + return this; + } + + @Override + public DefaultDittoDiagnosticLoggingAdapter setCorrelationId(final CharSequence correlationId) { + currentLogger = loggingAdapter; + setCorrelationId(null != correlationId ? correlationId.toString() : null); + return this; + } + + private void setCorrelationId(@Nullable final String correlationId) { + LogUtil.enhanceLogWithCustomField(currentLogger, LogUtil.X_CORRELATION_ID, correlationId); + } + + @Override + public DefaultDittoDiagnosticLoggingAdapter setCorrelationId(final WithDittoHeaders withDittoHeaders) { + return setCorrelationId(checkNotNull(withDittoHeaders, "withDittoHeaders").getDittoHeaders()); + } + + @Override + public DefaultDittoDiagnosticLoggingAdapter setCorrelationId(final DittoHeaders dittoHeaders) { + checkNotNull(dittoHeaders, "dittoHeaders"); + currentLogger = loggingAdapter; + setCorrelationId(dittoHeaders.getCorrelationId().orElse(null)); + return this; + } + + @Override + public void discardCorrelationId() { + currentLogger.discardCorrelationId(); + } + + @Override + public boolean isErrorEnabled() { + return currentLogger.isErrorEnabled(); + } + + @Override + public boolean isWarningEnabled() { + return currentLogger.isWarningEnabled(); + } + + @Override + public boolean isInfoEnabled() { + return currentLogger.isInfoEnabled(); + } + + @Override + public boolean isDebugEnabled() { + return currentLogger.isDebugEnabled(); + } + + @Override + public void notifyError(final String message) { + currentLogger.notifyError(message); + } + + @Override + public void notifyError(final Throwable cause, final String message) { + currentLogger.notifyError(cause, message); + } + + @Override + public void notifyWarning(final String message) { + currentLogger.notifyWarning(message); + } + + @Override + public void notifyInfo(final String message) { + currentLogger.notifyInfo(message); + } + + @Override + public void notifyDebug(final String message) { + currentLogger.notifyDebug(message); + } + + @Override + public void error(final Throwable cause, final String message) { + currentLogger.error(cause, message); + } + + @Override + public void error(final Throwable cause, final String template, final Object arg1) { + currentLogger.error(cause, template, arg1); + } + + @Override + public void error(final Throwable cause, + final String template, + final Object arg1, + final Object arg2) { + + currentLogger.error(cause, template, arg1, arg2); + } + + @Override + public void error(final Throwable cause, + final String template, + final Object arg1, + final Object arg2, + final Object arg3) { + + currentLogger.error(cause, template, arg1, arg2, arg3); + } + + @Override + public void error(final Throwable cause, + final String template, + final Object arg1, + final Object arg2, + final Object arg3, + final Object arg4) { + + currentLogger.error(cause, template, arg1, arg2, arg3, arg4); + } + + @Override + public void error(final String message) { + currentLogger.error(message); + } + + @Override + public void error(final String template, final Object arg1) { + currentLogger.error(template, arg1); + } + + @Override + public void error(final String template, final Object arg1, final Object arg2) { + currentLogger.error(template, arg1, arg2); + } + + @Override + public void error(final String template, + final Object arg1, + final Object arg2, + final Object arg3) { + + currentLogger.error(template, arg1, arg2, arg3); + } + + @Override + public void error(final String template, + final Object arg1, + final Object arg2, + final Object arg3, + final Object arg4) { + + currentLogger.error(template, arg1, arg2, arg3, arg4); + } + + @Override + public void warning(final String message) { + currentLogger.warning(message); + } + + @Override + public void warning(final String template, final Object arg1) { + currentLogger.warning(template, arg1); + } + + @Override + public void warning(final String template, final Object arg1, final Object arg2) { + currentLogger.warning(template, arg1, arg2); + } + + @Override + public void warning(final String template, + final Object arg1, + final Object arg2, + final Object arg3) { + + currentLogger.warning(template, arg1, arg2, arg3); + } + + @Override + public void warning(final String template, + final Object arg1, + final Object arg2, + final Object arg3, + final Object arg4) { + + currentLogger.warning(template, arg1, arg2, arg3, arg4); + } + + @Override + public void info(final String message) { + currentLogger.info(message); + } + + @Override + public void info(final String template, final Object arg1) { + currentLogger.info(template, arg1); + } + + @Override + public void info(final String template, final Object arg1, final Object arg2) { + currentLogger.info(template, arg1, arg2); + } + + @Override + public void info(final String template, + final Object arg1, + final Object arg2, + final Object arg3) { + + currentLogger.info(template, arg1, arg2, arg3); + } + + @Override + public void info(final String template, + final Object arg1, + final Object arg2, + final Object arg3, + final Object arg4) { + + currentLogger.info(template, arg1, arg2, arg3, arg4); + } + + @Override + public void debug(final String message) { + currentLogger.debug(message); + } + + @Override + public void debug(final String template, final Object arg1) { + currentLogger.debug(template, arg1); + } + + @Override + public void debug(final String template, final Object arg1, final Object arg2) { + currentLogger.debug(template, arg1, arg2); + } + + @Override + public void debug(final String template, + final Object arg1, + final Object arg2, + final Object arg3) { + + currentLogger.debug(template, arg1, arg2, arg3); + } + + @Override + public void debug(final String template, + final Object arg1, + final Object arg2, + final Object arg3, + final Object arg4) { + + currentLogger.debug(template, arg1, arg2, arg3, arg4); + } + + @Override + public String format(final String t, final Seq arg) { + return currentLogger.format(t, arg); + } + + @Override + public scala.collection.immutable.Map mdc() { + return currentLogger.mdc(); + } + + @Override + public void mdc(final scala.collection.immutable.Map mdc) { + currentLogger.mdc(mdc); + } + + @Override + public Map getMDC() { + return currentLogger.getMDC(); + } + + @Override + public void setMDC(final Map jMdc) { + currentLogger.setMDC(jMdc); + } + + @Override + public void clearMDC() { + currentLogger.clearMDC(); + } + +} diff --git a/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DefaultDittoLogger.java b/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DefaultDittoLogger.java new file mode 100644 index 0000000000..621c188cdc --- /dev/null +++ b/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DefaultDittoLogger.java @@ -0,0 +1,412 @@ +/* + * Copyright (c) 2019 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.services.utils.akka.logging; + +import static org.eclipse.ditto.model.base.common.ConditionChecker.checkNotNull; + +import javax.annotation.Nullable; +import javax.annotation.concurrent.NotThreadSafe; + +import org.eclipse.ditto.model.base.headers.DittoHeaders; +import org.eclipse.ditto.model.base.headers.WithDittoHeaders; +import org.eclipse.ditto.services.utils.akka.LogUtil; +import org.slf4j.Logger; +import org.slf4j.Marker; + +/** + * Default implementation of {@link DittoLogger}. + * It harnesses the state pattern for determining how long a particular correlation ID is valid. + */ +@NotThreadSafe +final class DefaultDittoLogger implements DittoLogger, AutoCloseableSlf4jLogger { + + private final AutoCloseableSlf4jLogger autoCloseableSlf4jLogger; + private final AutoCloseableSlf4jLogger autoClosingSlf4jLogger; + private AutoCloseableSlf4jLogger currentLogger; + + private DefaultDittoLogger(final AutoCloseableSlf4jLogger autoCloseableSlf4jLogger, + final AutoCloseableSlf4jLogger autoClosingSlf4jLogger) { + + this.autoCloseableSlf4jLogger = autoCloseableSlf4jLogger; + this.autoClosingSlf4jLogger = autoClosingSlf4jLogger; + currentLogger = this.autoCloseableSlf4jLogger; + } + + /** + * Returns an instance of the default Ditto logger. + * + * @param logger the SLF4J logger which performs the actual logging. + * @return the default Ditto logger. + * @throws NullPointerException if {@code logger} is {@code null}. + */ + public static DefaultDittoLogger of(final Logger logger) { + final AutoCloseableSlf4jLogger autoCloseableSlf4jLogger = DefaultAutoCloseableSlf4jLogger.of(logger); + return new DefaultDittoLogger(autoCloseableSlf4jLogger, AutoClosingSlf4jLogger.of(autoCloseableSlf4jLogger)); + } + + @Override + public DefaultDittoLogger withCorrelationId(@Nullable final CharSequence correlationId) { + currentLogger = autoClosingSlf4jLogger; + LogUtil.enhanceLogWithCorrelationId(correlationId); + return this; + } + + @Override + public DefaultDittoLogger withCorrelationId(final WithDittoHeaders withDittoHeaders) { + return withCorrelationId(checkNotNull(withDittoHeaders, "withDittoHeaders").getDittoHeaders()); + } + + @Override + public DefaultDittoLogger withCorrelationId(final DittoHeaders dittoHeaders) { + checkNotNull(dittoHeaders, "dittoHeaders"); + currentLogger = autoClosingSlf4jLogger; + LogUtil.enhanceLogWithCorrelationId(dittoHeaders); + return this; + } + + @Override + public DefaultDittoLogger setCorrelationId(@Nullable final CharSequence correlationId) { + currentLogger = autoCloseableSlf4jLogger; + LogUtil.enhanceLogWithCorrelationId(correlationId); + 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"); + currentLogger = autoCloseableSlf4jLogger; + LogUtil.enhanceLogWithCorrelationId(dittoHeaders); + return this; + } + + @Override + public void discardCorrelationId() { + close(); + } + + @Override + public String getName() { + return currentLogger.getName(); + } + + @Override + public boolean isTraceEnabled() { + return currentLogger.isTraceEnabled(); + } + + @Override + public void trace(final String msg) { + currentLogger.trace(msg); + } + + @Override + public void trace(final String format, final Object arg) { + currentLogger.trace(format, arg); + } + + @Override + public void trace(final String format, final Object arg1, final Object arg2) { + currentLogger.trace(format, arg1, arg2); + } + + @Override + public void trace(final String format, final Object... arguments) { + currentLogger.trace(format, arguments); + } + + @Override + public void trace(final String msg, final Throwable t) { + currentLogger.trace(msg, t); + } + + @Override + public boolean isTraceEnabled(final Marker marker) { + return currentLogger.isTraceEnabled(marker); + } + + @Override + public void trace(final Marker marker, final String msg) { + currentLogger.trace(marker, msg); + } + + @Override + public void trace(final Marker marker, final String format, final Object arg) { + currentLogger.trace(marker, format, arg); + } + + @Override + public void trace(final Marker marker, final String format, final Object arg1, final Object arg2) { + currentLogger.trace(marker, format, arg1, arg2); + } + + @Override + public void trace(final Marker marker, final String format, final Object... argArray) { + currentLogger.trace(marker, format, argArray); + } + + @Override + public void trace(final Marker marker, final String msg, final Throwable t) { + currentLogger.trace(marker, msg, t); + } + + @Override + public boolean isDebugEnabled() { + return currentLogger.isDebugEnabled(); + } + + @Override + public void debug(final String msg) { + currentLogger.debug(msg); + } + + @Override + public void debug(final String format, final Object arg) { + currentLogger.debug(format, arg); + } + + @Override + public void debug(final String format, final Object arg1, final Object arg2) { + currentLogger.debug(format, arg1, arg2); + } + + @Override + public void debug(final String format, final Object... arguments) { + currentLogger.debug(format, arguments); + } + + @Override + public void debug(final String msg, final Throwable t) { + currentLogger.debug(msg, t); + } + + @Override + public boolean isDebugEnabled(final Marker marker) { + return currentLogger.isDebugEnabled(marker); + } + + @Override + public void debug(final Marker marker, final String msg) { + currentLogger.debug(marker, msg); + } + + @Override + public void debug(final Marker marker, final String format, final Object arg) { + currentLogger.debug(marker, format, arg); + } + + @Override + public void debug(final Marker marker, final String format, final Object arg1, final Object arg2) { + currentLogger.debug(marker, format, arg1, arg2); + } + + @Override + public void debug(final Marker marker, final String format, final Object... arguments) { + currentLogger.debug(marker, format, arguments); + } + + @Override + public void debug(final Marker marker, final String msg, final Throwable t) { + currentLogger.debug(marker, msg, t); + } + + @Override + public boolean isInfoEnabled() { + return currentLogger.isInfoEnabled(); + } + + @Override + public void info(final String msg) { + currentLogger.info(msg); + } + + @Override + public void info(final String format, final Object arg) { + currentLogger.info(format, arg); + } + + @Override + public void info(final String format, final Object arg1, final Object arg2) { + currentLogger.info(format, arg1, arg2); + } + + @Override + public void info(final String format, final Object... arguments) { + currentLogger.info(format, arguments); + } + + @Override + public void info(final String msg, final Throwable t) { + currentLogger.info(msg, t); + } + + @Override + public boolean isInfoEnabled(final Marker marker) { + return currentLogger.isInfoEnabled(marker); + } + + @Override + public void info(final Marker marker, final String msg) { + currentLogger.info(marker, msg); + } + + @Override + public void info(final Marker marker, final String format, final Object arg) { + currentLogger.info(marker, format, arg); + } + + @Override + public void info(final Marker marker, final String format, final Object arg1, final Object arg2) { + currentLogger.info(marker, format, arg1, arg2); + } + + @Override + public void info(final Marker marker, final String format, final Object... arguments) { + currentLogger.info(marker, format, arguments); + } + + @Override + public void info(final Marker marker, final String msg, final Throwable t) { + currentLogger.info(marker, msg, t); + } + + @Override + public boolean isWarnEnabled() { + return currentLogger.isWarnEnabled(); + } + + @Override + public void warn(final String msg) { + currentLogger.warn(msg); + } + + @Override + public void warn(final String format, final Object arg) { + currentLogger.warn(format, arg); + } + + @Override + public void warn(final String format, final Object... arguments) { + currentLogger.warn(format, arguments); + } + + @Override + public void warn(final String format, final Object arg1, final Object arg2) { + currentLogger.warn(format, arg1, arg2); + } + + @Override + public void warn(final String msg, final Throwable t) { + currentLogger.warn(msg, t); + } + + @Override + public boolean isWarnEnabled(final Marker marker) { + return currentLogger.isWarnEnabled(marker); + } + + @Override + public void warn(final Marker marker, final String msg) { + currentLogger.warn(marker, msg); + } + + @Override + public void warn(final Marker marker, final String format, final Object arg) { + currentLogger.warn(marker, format, arg); + } + + @Override + public void warn(final Marker marker, final String format, final Object arg1, final Object arg2) { + currentLogger.warn(marker, format, arg1, arg2); + } + + @Override + public void warn(final Marker marker, final String format, final Object... arguments) { + currentLogger.warn(marker, format, arguments); + } + + @Override + public void warn(final Marker marker, final String msg, final Throwable t) { + currentLogger.warn(marker, msg, t); + } + + @Override + public boolean isErrorEnabled() { + return currentLogger.isErrorEnabled(); + } + + @Override + public void error(final String msg) { + currentLogger.error(msg); + } + + @Override + public void error(final String format, final Object arg) { + currentLogger.error(format, arg); + } + + @Override + public void error(final String format, final Object arg1, final Object arg2) { + currentLogger.error(format, arg1, arg2); + } + + @Override + public void error(final String format, final Object... arguments) { + currentLogger.error(format, arguments); + } + + @Override + public void error(final String msg, final Throwable t) { + currentLogger.error(msg, t); + } + + @Override + public boolean isErrorEnabled(final Marker marker) { + return currentLogger.isErrorEnabled(marker); + } + + @Override + public void error(final Marker marker, final String msg) { + currentLogger.error(marker, msg); + } + + @Override + public void error(final Marker marker, final String format, final Object arg) { + currentLogger.error(marker, format, arg); + } + + @Override + public void error(final Marker marker, final String format, final Object arg1, final Object arg2) { + currentLogger.error(marker, format, arg1, arg2); + } + + @Override + public void error(final Marker marker, final String format, final Object... arguments) { + currentLogger.error(marker, format, arguments); + } + + @Override + public void error(final Marker marker, final String msg, final Throwable t) { + currentLogger.error(marker, msg, t); + } + + @Override + public void close() { + currentLogger.close(); + } + +} diff --git a/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DittoLogger.java b/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DittoLogger.java new file mode 100644 index 0000000000..888767d2d3 --- /dev/null +++ b/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DittoLogger.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2019 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.services.utils.akka.logging; + +import javax.annotation.Nullable; +import javax.annotation.concurrent.NotThreadSafe; + +import org.eclipse.ditto.model.base.headers.DittoHeaders; +import org.eclipse.ditto.model.base.headers.WithDittoHeaders; +import org.slf4j.Logger; + +/** + * A SLF4J {@link Logger} with additional functionality. + * The main purpose of DittoLogger is to provide an API for easily setting a correlation ID to the logging + * Mapped Diagnostic Context (MDC). + * + * DittoLogger can be used in two ways: + *
    + *
  1. set the correlation ID per log operation, i. e. it gets automatically discarded immediately after having + * performed the log operation.
  2. + *
  3. Or set the correlation ID globally until it gets manually discarded.
  4. + *
+ * + * The following example shows usage for case 1. + * The correlation ID is only logged for the info message and gets discarded automatically afterwards. + *
+ * DittoLogger dittoLogger = DittoLoggerFactory.getLogger(MyClass.class);
+ * dittoLogger.withCorrelationId("my-correlation-id").info("This is a normal SLF4J log operation.");
+ * dittoLogger.warn("The correlation ID is logged no more.");
+ * 
+ * + * For case 2 the correlation ID is set globally and will be logged until it gets discarded manually. + * The preferred way to do this is to utilize Javas try-with-resources: + *
+ * DittoLogger dittoLogger = DittoLoggerFactory.getLogger(MyClass.class);
+ * try (final AutoCloseableSlf4jLogger l = dittoLogger.setCorrelationId("my-correlation-id") {
+ *     l.info("This message logs the correlation ID.");
+ *     l.info("So does this message.");
+ *     l.info("And this.");
+ *     // All log messages within this scope will contain the correlation ID.
+ * }
+ * dittoLogger.warn("The correlation ID is logged no more.");
+ * 
+ * + * The second example for case 2 requires you to call {@link #discardCorrelationId()} explicitly. + * This approach is more flexible as it allows to set the correlation ID for a broader scope than the + * try-with-resources way. + *
+ * DittoLogger dittoLogger = DittoLoggerFactory.getLogger(MyClass.class);
+ *
+ * dittoLogger.setCorrelationId("my-correlationId"); // Ignore the returned value
+ * dittoLogger.info("This message logs the correlation ID.");
+ * dittoLogger.info("So does this message.");
+ * dittoLogger.info("And this.");
+ * dittoLogger.discardCorrelationId();
+ *
+ * dittoLogger.warn("The correlation ID is logged no more.");
+ * 
+ */ +@NotThreadSafe +public interface DittoLogger extends Logger { + + /** + * Sets the given correlation ID for the subsequent log operation. + * + * @param correlationId the correlation ID to be put to the MDC. + * @return this DittoLogger instance to allow method chaining. + */ + 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. + * @throws NullPointerException if {@code withDittoHeaders} is {@code null}. + */ + DittoLogger withCorrelationId(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. + * @throws NullPointerException if {@code dittoHeaders} is {@code null}. + */ + DittoLogger withCorrelationId(DittoHeaders dittoHeaders); + + /** + * 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 DittoLogger instance to allow method chaining. + */ + AutoCloseableSlf4jLogger setCorrelationId(@Nullable CharSequence correlationId); + + /** + * 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 DittoLogger instance to allow method chaining. + * @throws NullPointerException if {@code withDittoHeaders} is {@code null}. + */ + AutoCloseableSlf4jLogger setCorrelationId(WithDittoHeaders withDittoHeaders); + + /** + * 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 DittoLogger instance to allow method chaining. + * @throws NullPointerException if {@code dittoHeaders} is {@code null}. + */ + AutoCloseableSlf4jLogger setCorrelationId(DittoHeaders dittoHeaders); + + /** + * Removes the currently set correlation ID from the MDC. + */ + void discardCorrelationId(); + +} diff --git a/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DittoLoggerFactory.java b/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DittoLoggerFactory.java new file mode 100644 index 0000000000..54ae12a263 --- /dev/null +++ b/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/DittoLoggerFactory.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2019 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.services.utils.akka.logging; + +import static org.eclipse.ditto.model.base.common.ConditionChecker.checkNotNull; + +import javax.annotation.concurrent.Immutable; + +import org.eclipse.ditto.services.utils.akka.LogUtil; +import org.slf4j.LoggerFactory; + +import akka.actor.Actor; + +/** + * Factory for obtaining instances of {@link DittoLogger} and {@link DittoDiagnosticLoggingAdapter}. + */ +@Immutable +public final class DittoLoggerFactory { + + private DittoLoggerFactory() { + throw new AssertionError(); + } + + /** + * Returns a {@link DittoLogger} named corresponding to the class passed as parameter, using the statically bound + * {@link org.slf4j.ILoggerFactory} instance. + * + * In case the the clazz parameter differs from the name of the caller as computed internally by SLF4J, a logger + * name mismatch warning will be printed but only if the {@code slf4j.detectLoggerNameMismatch} system property is + * set to {@code true}. + * By default, this property is not set and no warnings will be printed even in case of a logger name mismatch. + * + * @param clazz provides the name of the returned logger. + * @return the logger. + * @throws NullPointerException if {@code clazz} is {@code null}. + */ + public static DittoLogger getLogger(final Class clazz) { + return DefaultDittoLogger.of(LoggerFactory.getLogger(checkNotNull(clazz, "clazz"))); + } + + /** + * Returns a {@link DittoLogger} named according to the name parameter using the statically bound + * {@link org.slf4j.ILoggerFactory} instance. + * + * @param name the name of the logger. + * @return the logger. + * @throws NullPointerException if {@code name} is {@code null}. + */ + public static DittoLogger getLogger(final CharSequence name) { + return DefaultDittoLogger.of(LoggerFactory.getLogger(checkNotNull(name, "name").toString())); + } + + /** + * Returns a LoggingAdapter with MDC support for the given actor. + * + * @param logSource the Actor used as logSource + * @return the logging adapter. + * @throws NullPointerException if {@code logSource} is {@code null}. + */ + public static DittoDiagnosticLoggingAdapter getDiagnosticLoggingAdapter(final Actor logSource) { + return DefaultDittoDiagnosticLoggingAdapter.of(LogUtil.obtain(checkNotNull(logSource, "logSource"))); + } + +} diff --git a/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/package-info.java b/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/package-info.java new file mode 100644 index 0000000000..8dfa6d1055 --- /dev/null +++ b/services/utils/akka/src/main/java/org/eclipse/ditto/services/utils/akka/logging/package-info.java @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2019 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 + */ +@org.eclipse.ditto.utils.jsr305.annotations.AllParametersAndReturnValuesAreNonnullByDefault +package org.eclipse.ditto.services.utils.akka.logging; diff --git a/services/utils/akka/src/main/scala/org/eclipse/ditto/services/utils/akka/logging/AbstractDiagnosticLoggingAdapter.scala b/services/utils/akka/src/main/scala/org/eclipse/ditto/services/utils/akka/logging/AbstractDiagnosticLoggingAdapter.scala new file mode 100644 index 0000000000..83f35d6161 --- /dev/null +++ b/services/utils/akka/src/main/scala/org/eclipse/ditto/services/utils/akka/logging/AbstractDiagnosticLoggingAdapter.scala @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2019 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.services.utils.akka.logging + +import akka.event.DiagnosticLoggingAdapter +import javax.annotation.concurrent.NotThreadSafe + +/** + * This class exists to be able to implement [[DiagnosticLoggingAdapter]] in Java. + */ +@NotThreadSafe +abstract class AbstractDiagnosticLoggingAdapter extends DiagnosticLoggingAdapter { + + /** Removes the currently set correlation ID from the MDC. + */ + def discardCorrelationId(): Unit + +} diff --git a/services/utils/akka/src/main/scala/org/eclipse/ditto/services/utils/akka/logging/DittoDiagnosticLoggingAdapter.scala b/services/utils/akka/src/main/scala/org/eclipse/ditto/services/utils/akka/logging/DittoDiagnosticLoggingAdapter.scala new file mode 100644 index 0000000000..13d69ac0f2 --- /dev/null +++ b/services/utils/akka/src/main/scala/org/eclipse/ditto/services/utils/akka/logging/DittoDiagnosticLoggingAdapter.scala @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2019 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.services.utils.akka.logging + +import javax.annotation.Nullable +import javax.annotation.concurrent.NotThreadSafe +import org.eclipse.ditto.model.base.headers.{DittoHeaders, WithDittoHeaders} + +/** An Akka [[akka.event.DiagnosticLoggingAdapter]] with additional functionality. + * + * The main purpose of DittoDiagnosticLoggingAdapter is to provide an API for easily setting a correlation ID to the + * logging MDC. + * + * DittoDiagnosticLoggingAdapter can be used in two ways: + *
    + *
  1. set the correlation ID per log operation, i. e. it gets automatically discarded immediately after having + * performed the log operation.
  2. + *
  3. Or set the correlation ID globally until it gets manually discarded.
  4. + *
+ * + * The following example shows usage for case 1. + * The correlation ID is only logged for the info message and gets discarded automatically afterwards. + *
+  * DittoDiagnosticLoggingAdapter dittoLogger = DittoLoggerFactory.getDiagnosticLoggingAdapter(myActor);
+  * dittoLogger.withCorrelationId("my-correlation-id").info("This is a normal log operation.");
+  * dittoLogger.warn("The correlation ID is logged no more.");
+  * 
+ * + * For case 2 the correlation ID is set globally and will be logged until it gets discarded manually. + *
+  * DittoDiagnosticLoggingAdapter dittoLogger = DittoLoggerFactory.getDiagnosticLoggingAdapter(myActor);
+  *
+  * dittoLogger.setCorrelationId("my-correlationId"); // Ignore the returned value
+  * dittoLogger.info("This message logs the correlation ID.");
+  * dittoLogger.info("So does this message.");
+  * dittoLogger.info("And this.");
+  * dittoLogger.discardCorrelationId();
+  *
+  * dittoLogger.warn("The correlation ID is logged no more.");
+  * 
+ */ +@NotThreadSafe +abstract class DittoDiagnosticLoggingAdapter extends AbstractDiagnosticLoggingAdapter { + + /** Sets the given correlation ID for the subsequent log operation. + * + * @param correlationId the correlation ID to be put to the MDC. + * @return this DittoLogger instance to allow method chaining. + */ + def withCorrelationId(@Nullable correlationId: CharSequence): 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. + * @return this DittoLogger instance to allow method chaining. + * @throws NullPointerException if `withDittoHeaders` is `null`. + */ + def withCorrelationId(withDittoHeaders: WithDittoHeaders[_]): DittoDiagnosticLoggingAdapter + + /** 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 `dittoHeaders` is `null`. + */ + def withCorrelationId(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 DittoLogger 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 DittoLogger 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 DittoLogger instance to allow method chaining. + * @throws NullPointerException if `dittoHeaders` is `null`. + */ + def setCorrelationId(dittoHeaders: DittoHeaders): DittoDiagnosticLoggingAdapter + +} diff --git a/services/utils/akka/src/main/scala/org/eclipse/ditto/services/utils/akka/logging/package-info.java b/services/utils/akka/src/main/scala/org/eclipse/ditto/services/utils/akka/logging/package-info.java new file mode 100644 index 0000000000..2c07f610cd --- /dev/null +++ b/services/utils/akka/src/main/scala/org/eclipse/ditto/services/utils/akka/logging/package-info.java @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2019 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 + */ + +@org.eclipse.ditto.utils.jsr305.annotations.AllParametersAndReturnValuesAreNonnullByDefault +package org.eclipse.ditto.services.utils.akka.logging;