This is an automated email from the ASF dual-hosted git repository.
merlimat pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/bookkeeper.git
The following commit(s) were added to refs/heads/master by this push:
new ed71a06dc8 BP-69: Convert bookkeeper-common to slog (phase 1) (#4754)
ed71a06dc8 is described below
commit ed71a06dc8bb44ca530b83e53b024ccb024834c3
Author: Matteo Merli <[email protected]>
AuthorDate: Tue Apr 28 08:20:08 2026 -0700
BP-69: Convert bookkeeper-common to slog (phase 1) (#4754)
* BP-69: Convert bookkeeper-common from SLF4J to slog
First phase of the slog migration for BP-69. Adds the slog dependency,
Lombok @CustomLog configuration, and converts the bookkeeper-common module.
* Added license header
* BP-69 common: fix checkstyle ImportOrder violations
CI flagged 4 ImportOrder violations in the Phase 1 conversion:
- SafeRunnable.java: io.github.merlimat.slog.Logger placed after java.*
- OrderedExecutor.java: lombok.CustomLog placed after org.*
- AbstractLifecycleComponent.java: same
- TestOrderedExecutorDecorators.java: same
Move each import to its correct alphabetical position per the project's
checkstyle rule (`io.` < `java.`; `lombok.` < `org.`).
* BP-69 common: add slog-0.9.7 to bookkeeper-dist LICENSE files
CI check-binary-license flagged the new
io.github.merlimat.slog-slog-0.9.7.jar
as unaccounted for. Add it to the Apache-2.0 bundled-jars list in both
LICENSE-all.bin.txt and LICENSE-bkctl.bin.txt, with a new numbered source
reference pointing at https://github.com/merlimat/slog/tree/v0.9.7.
* BP-69 common: also add slog-0.9.7 to LICENSE-server.bin.txt
The previous LICENSE fix only updated LICENSE-all.bin.txt and
LICENSE-bkctl.bin.txt, but the bin-server.xml assembly descriptor
packages LICENSE-server.bin.txt into the server tarball that the CI
license-check script inspects.
* BP-69 common: remove TestOrderedExecutorDecorators and MdcContextTest
Both tests exercise SLF4J MDC context propagation through the
OrderedExecutor / OrderedScheduler decorators. With the slog migration
the logger API is different and these tests are not straightforward to
keep working against the new logger while still testing MDC behaviour
as seen by the underlying SLF4J backend.
Drop them for now. The MDC propagation code itself (MdcUtils,
OrderedExecutor's mdcContextMap snapshot/restore) is unchanged, so
end-to-end MDC-in-logs behaviour under Logback/Log4j2 backends is
preserved.
* Revert "BP-69 common: remove TestOrderedExecutorDecorators and
MdcContextTest"
This reverts commit 790d4955aad0fc5f559c148a99084d921e7dec8b.
* Bump slog dependency to 0.9.8
Pulls in the MDC propagation fix from merlimat/slog#6, which makes
log4j2 ThreadContext entries visible on slog events emitted via the
Log4j2Logger backend (so %X{key} layouts and appenders that read
event.getContextData().getValue(key) see the caller's MDC).
---
.../component/AbstractLifecycleComponent.java | 20 ++++++++++--------
.../component/AutoCloseableLifecycleComponent.java | 10 +++++----
.../common/util/LogExceptionRunnable.java | 9 +++++---
.../bookkeeper/common/util/OrderedExecutor.java | 19 +++++++++++------
.../bookkeeper/common/util/SafeRunnable.java | 7 +++----
.../common/util/TestOrderedExecutorDecorators.java | 5 ++---
.../src/main/resources/LICENSE-all.bin.txt | 2 ++
.../src/main/resources/LICENSE-bkctl.bin.txt | 2 ++
.../src/main/resources/LICENSE-server.bin.txt | 2 ++
lombok.config | 24 ++++++++++++++++++++++
pom.xml | 10 +++++++++
11 files changed, 81 insertions(+), 29 deletions(-)
diff --git
a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/component/AbstractLifecycleComponent.java
b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/component/AbstractLifecycleComponent.java
index 534c952f33..19972ce5c5 100644
---
a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/component/AbstractLifecycleComponent.java
+++
b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/component/AbstractLifecycleComponent.java
@@ -22,21 +22,17 @@ import java.io.IOException;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
-import lombok.extern.slf4j.Slf4j;
+import lombok.CustomLog;
import org.apache.bookkeeper.common.conf.ComponentConfiguration;
import org.apache.bookkeeper.stats.StatsLogger;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* A mix of {@link AbstractComponent} and {@link LifecycleComponent}.
*/
-@Slf4j
+@CustomLog
public abstract class AbstractLifecycleComponent<ConfT extends
ComponentConfiguration>
extends AbstractComponent<ConfT> implements LifecycleComponent {
- private static final Logger LOG =
LoggerFactory.getLogger(AbstractLifecycleComponent.class);
-
protected final Lifecycle lifecycle = new Lifecycle();
private final Set<LifecycleListener> listeners = new
CopyOnWriteArraySet<>();
protected final StatsLogger statsLogger;
@@ -82,9 +78,12 @@ public abstract class AbstractLifecycleComponent<ConfT
extends ComponentConfigur
try {
doStart();
} catch (Throwable exc) {
- LOG.error("Failed to start Component: {}", getName(), exc);
+ log.error()
+ .exception(exc)
+ .attr("component", getName())
+ .log("Failed to start component");
if (uncaughtExceptionHandler != null) {
- LOG.error("Calling uncaughtExceptionHandler");
+ log.error("Calling uncaughtExceptionHandler");
uncaughtExceptionHandler.uncaughtException(Thread.currentThread(), exc);
} else {
throw exc;
@@ -122,7 +121,10 @@ public abstract class AbstractLifecycleComponent<ConfT
extends ComponentConfigur
try {
doClose();
} catch (IOException e) {
- log.warn("failed to close {}", componentName, e);
+ log.warn()
+ .exception(e)
+ .attr("component", componentName)
+ .log("Failed to close component");
}
listeners.forEach(LifecycleListener::afterClose);
}
diff --git
a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/component/AutoCloseableLifecycleComponent.java
b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/component/AutoCloseableLifecycleComponent.java
index ded3707a05..cf4d73d57b 100644
---
a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/component/AutoCloseableLifecycleComponent.java
+++
b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/component/AutoCloseableLifecycleComponent.java
@@ -21,15 +21,14 @@ package org.apache.bookkeeper.common.component;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import lombok.CustomLog;
/**
* Allows for AutoClosable resources to be added to the component
* lifecycle without having to implement ServerLifecycleComponent directly.
*/
+@CustomLog
public class AutoCloseableLifecycleComponent implements LifecycleComponent {
- private static final Logger LOG =
LoggerFactory.getLogger(AutoCloseableLifecycleComponent.class);
protected final Lifecycle lifecycle = new Lifecycle();
private final Set<LifecycleListener> listeners = new
CopyOnWriteArraySet<>();
@@ -100,7 +99,10 @@ public class AutoCloseableLifecycleComponent implements
LifecycleComponent {
try {
closeable.close();
} catch (Exception e) {
- LOG.warn("failed to close {}", componentName, e);
+ log.warn()
+ .exception(e)
+ .attr("component", componentName)
+ .log("Failed to close component");
}
listeners.forEach(LifecycleListener::afterClose);
}
diff --git
a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/util/LogExceptionRunnable.java
b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/util/LogExceptionRunnable.java
index bf2ddac904..3f31a9d840 100644
---
a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/util/LogExceptionRunnable.java
+++
b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/util/LogExceptionRunnable.java
@@ -21,13 +21,13 @@ package org.apache.bookkeeper.common.util;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Throwables;
-import lombok.extern.slf4j.Slf4j;
+import lombok.CustomLog;
/**
* A simple wrapper for a {@link Runnable} that logs any exception thrown by
it, before
* re-throwing it.
*/
-@Slf4j
+@CustomLog
public final class LogExceptionRunnable implements Runnable {
private final Runnable task;
@@ -41,7 +41,10 @@ public final class LogExceptionRunnable implements Runnable {
try {
task.run();
} catch (Throwable t) {
- log.error("Exception while executing runnable " + task, t);
+ log.error()
+ .exception(t)
+ .attr("task", task)
+ .log("Exception while executing runnable");
Throwables.throwIfUnchecked(t);
throw new AssertionError(t);
}
diff --git
a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/util/OrderedExecutor.java
b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/util/OrderedExecutor.java
index 6ec1e43afe..516581fdb0 100644
---
a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/util/OrderedExecutor.java
+++
b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/util/OrderedExecutor.java
@@ -38,7 +38,7 @@ import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;
-import lombok.extern.slf4j.Slf4j;
+import lombok.CustomLog;
import org.apache.bookkeeper.common.util.affinity.CpuAffinity;
import org.apache.bookkeeper.stats.Gauge;
import org.apache.bookkeeper.stats.NullStatsLogger;
@@ -56,7 +56,7 @@ import org.slf4j.MDC;
* achieved by hashing the key objects to threads by their {@link #hashCode()}
* method.
*/
-@Slf4j
+@CustomLog
public class OrderedExecutor implements ExecutorService {
public static final int NO_TASK_LIMIT = -1;
private static final int DEFAULT_MAX_ARRAY_QUEUE_SIZE = 10_000;
@@ -205,7 +205,10 @@ public class OrderedExecutor implements ExecutorService {
long elapsedMicroSec = MathUtils.elapsedMicroSec(startNanos);
taskExecutionStats.registerSuccessfulEvent(elapsedMicroSec,
TimeUnit.MICROSECONDS);
if (elapsedMicroSec >= warnTimeMicroSec) {
- log.warn("Runnable {} took too long {} micros to
execute.", runnableClass, elapsedMicroSec);
+ log.warn()
+ .attr("runnable", runnableClass)
+ .attr("elapsedMicroSec", elapsedMicroSec)
+ .log("Runnable took too long to execute");
}
}
}
@@ -235,7 +238,10 @@ public class OrderedExecutor implements ExecutorService {
long elapsedMicroSec = MathUtils.elapsedMicroSec(startNanos);
taskExecutionStats.registerSuccessfulEvent(elapsedMicroSec,
TimeUnit.MICROSECONDS);
if (elapsedMicroSec >= warnTimeMicroSec) {
- log.warn("Callable {} took too long {} micros to
execute.", callableClass, elapsedMicroSec);
+ log.warn()
+ .attr("callable", callableClass)
+ .attr("elapsedMicroSec", elapsedMicroSec)
+ .log("Callable took too long to execute");
}
}
}
@@ -419,8 +425,9 @@ public class OrderedExecutor implements ExecutorService {
try {
CpuAffinity.acquireCore();
} catch (Throwable t) {
- log.warn("Failed to acquire CPU core for thread
{}: {}", Thread.currentThread().getName(),
- t.getMessage(), t);
+ log.warn().exception(t)
+ .attr("thread",
Thread.currentThread().getName())
+ .log("Failed to acquire CPU core for
thread");
}
}
}).get();
diff --git
a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/util/SafeRunnable.java
b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/util/SafeRunnable.java
index 6a3cf4d746..d0cff7925e 100644
---
a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/util/SafeRunnable.java
+++
b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/util/SafeRunnable.java
@@ -18,9 +18,8 @@
package org.apache.bookkeeper.common.util;
+import io.github.merlimat.slog.Logger;
import java.util.function.Consumer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* A runnable that catches runtime exceptions.
@@ -28,14 +27,14 @@ import org.slf4j.LoggerFactory;
@FunctionalInterface
public interface SafeRunnable extends Runnable {
- Logger LOGGER = LoggerFactory.getLogger(SafeRunnable.class);
+ Logger LOGGER = Logger.get(SafeRunnable.class);
@Override
default void run() {
try {
safeRun();
} catch (Throwable t) {
- LOGGER.error("Unexpected throwable caught ", t);
+ LOGGER.error().exception(t).log("Unexpected throwable caught");
}
}
diff --git
a/bookkeeper-common/src/test/java/org/apache/bookkeeper/common/util/TestOrderedExecutorDecorators.java
b/bookkeeper-common/src/test/java/org/apache/bookkeeper/common/util/TestOrderedExecutorDecorators.java
index 5d83369fe3..69b0570899 100644
---
a/bookkeeper-common/src/test/java/org/apache/bookkeeper/common/util/TestOrderedExecutorDecorators.java
+++
b/bookkeeper-common/src/test/java/org/apache/bookkeeper/common/util/TestOrderedExecutorDecorators.java
@@ -32,6 +32,7 @@ import java.util.Queue;
import java.util.UUID;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
+import lombok.CustomLog;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.LogEvent;
@@ -40,14 +41,12 @@ import org.apache.logging.log4j.core.appender.NullAppender;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* Test that decorators applied by OrderedExecutor/Scheduler are correctly
applied.
*/
+@CustomLog
public class TestOrderedExecutorDecorators {
- private static final Logger log =
LoggerFactory.getLogger(TestOrderedExecutorDecorators.class);
private static final String MDC_KEY = "mdc-key";
private NullAppender mockAppender;
diff --git a/bookkeeper-dist/src/main/resources/LICENSE-all.bin.txt
b/bookkeeper-dist/src/main/resources/LICENSE-all.bin.txt
index e23b4fe4b0..f66fb0c91a 100644
--- a/bookkeeper-dist/src/main/resources/LICENSE-all.bin.txt
+++ b/bookkeeper-dist/src/main/resources/LICENSE-all.bin.txt
@@ -216,6 +216,7 @@ Apache Software License, Version 2.
- lib/commons-codec-commons-codec-1.18.0.jar [6]
- lib/commons-io-commons-io-2.19.0.jar [8]
- lib/commons-logging-commons-logging-1.3.5.jar [10]
+- lib/io.github.merlimat.slog-slog-0.9.8.jar [64]
- lib/io.netty-netty-buffer-4.2.12.Final.jar [11]
- lib/io.netty-netty-codec-base-4.2.12.Final.jar [11]
- lib/io.netty-netty-codec-compression-4.2.12.Final.jar [11]
@@ -422,6 +423,7 @@ Apache Software License, Version 2.
[61] Source available at
https://github.com/apache/commons-text/tree/rel/commons-text-1.13.1
[62] Source available at
https://github.com/apache/commons-beanutils/tree/rel/commons-beanutils-1.11.0
[63] Source available at
https://github.com/googleapis/sdk-platform-java/tree/v2.53.0/api-common-java
+[64] Source available at https://github.com/merlimat/slog/tree/v0.9.8
------------------------------------------------------------------------------------
lib/io.netty-netty-codec-base-4.2.12.Final.jar bundles some 3rd party
dependencies
diff --git a/bookkeeper-dist/src/main/resources/LICENSE-bkctl.bin.txt
b/bookkeeper-dist/src/main/resources/LICENSE-bkctl.bin.txt
index 6982f75955..8b39fb9a5d 100644
--- a/bookkeeper-dist/src/main/resources/LICENSE-bkctl.bin.txt
+++ b/bookkeeper-dist/src/main/resources/LICENSE-bkctl.bin.txt
@@ -216,6 +216,7 @@ Apache Software License, Version 2.
- lib/commons-codec-commons-codec-1.18.0.jar [6]
- lib/commons-io-commons-io-2.19.0.jar [8]
- lib/commons-logging-commons-logging-1.3.5.jar [10]
+- lib/io.github.merlimat.slog-slog-0.9.8.jar [59]
- lib/io.netty-netty-buffer-4.2.12.Final.jar [11]
- lib/io.netty-netty-codec-base-4.2.12.Final.jar [11]
- lib/io.netty-netty-common-4.2.12.Final.jar [11]
@@ -355,6 +356,7 @@ Apache Software License, Version 2.
[56] Source available at
https://github.com/apache/commons-text/tree/rel/commons-text-1.13.1
[57] Source available at
https://github.com/apache/commons-beanutils/tree/rel/commons-beanutils-1.11.0
[58] Source available at
https://github.com/googleapis/sdk-platform-java/tree/v2.53.0/api-common-java
+[59] Source available at https://github.com/merlimat/slog/tree/v0.9.8
------------------------------------------------------------------------------------
lib/io.netty-netty-codec-base-4.2.12.Final.jar bundles some 3rd party
dependencies
diff --git a/bookkeeper-dist/src/main/resources/LICENSE-server.bin.txt
b/bookkeeper-dist/src/main/resources/LICENSE-server.bin.txt
index b4b7a8f44e..362493a051 100644
--- a/bookkeeper-dist/src/main/resources/LICENSE-server.bin.txt
+++ b/bookkeeper-dist/src/main/resources/LICENSE-server.bin.txt
@@ -216,6 +216,7 @@ Apache Software License, Version 2.
- lib/commons-codec-commons-codec-1.18.0.jar [6]
- lib/commons-io-commons-io-2.19.0.jar [8]
- lib/commons-logging-commons-logging-1.3.5.jar [10]
+- lib/io.github.merlimat.slog-slog-0.9.8.jar [63]
- lib/io.netty-netty-buffer-4.2.12.Final.jar [11]
- lib/io.netty-netty-codec-base-4.2.12.Final.jar [11]
- lib/io.netty-netty-codec-compression-4.2.12.Final.jar [11]
@@ -417,6 +418,7 @@ Apache Software License, Version 2.
[60] Source available at
https://github.com/apache/commons-text/tree/rel/commons-text-1.13.1
[61] Source available at
https://github.com/apache/commons-beanutils/tree/rel/commons-beanutils-1.11.0
[62] Source available at
https://github.com/googleapis/sdk-platform-java/tree/v2.53.0/api-common-java
+[63] Source available at https://github.com/merlimat/slog/tree/v0.9.8
------------------------------------------------------------------------------------
lib/io.netty-netty-codec-base-4.2.12.Final.jar bundles some 3rd party
dependencies
diff --git a/lombok.config b/lombok.config
new file mode 100644
index 0000000000..bc68b26eeb
--- /dev/null
+++ b/lombok.config
@@ -0,0 +1,24 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# this is the top level Lombok configuration file
+# see https://projectlombok.org/features/configuration for reference
+
+config.stopBubbling = true
+lombok.log.custom.declaration = io.github.merlimat.slog.Logger
io.github.merlimat.slog.Logger.get(TYPE)
diff --git a/pom.xml b/pom.xml
index 29d3d24be8..d18f145ed7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -192,6 +192,7 @@
<rocksdb.version>9.9.3</rocksdb.version>
<shrinkwrap.version>3.3.0</shrinkwrap.version>
<slf4j.version>2.0.12</slf4j.version>
+ <slog.version>0.9.8</slog.version>
<snakeyaml.version>2.0</snakeyaml.version>
<spotbugs-annotations.version>4.6.0</spotbugs-annotations.version>
<spotless.version>2.43.0</spotless.version>
@@ -273,6 +274,11 @@
</dependency>
<!-- logging dependencies -->
+ <dependency>
+ <groupId>io.github.merlimat.slog</groupId>
+ <artifactId>slog</artifactId>
+ <version>${slog.version}</version>
+ </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-bom</artifactId>
@@ -882,6 +888,10 @@
</dependency>
<!-- compilation dependencies (available at all classpaths) -->
+ <dependency>
+ <groupId>io.github.merlimat.slog</groupId>
+ <artifactId>slog</artifactId>
+ </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>