You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ko...@apache.org on 2022/07/05 07:33:32 UTC

[ignite-3] branch main updated: IGNITE-17240 Provide an ability to configure logging backend through IgniteClient.Builder (#913)

This is an automated email from the ASF dual-hosted git repository.

korlov pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new cc6cacde5 IGNITE-17240 Provide an ability to configure logging backend through IgniteClient.Builder (#913)
cc6cacde5 is described below

commit cc6cacde52bd84cc79554b48ea549846cd357893
Author: korlov42 <ko...@gridgain.com>
AuthorDate: Tue Jul 5 10:33:27 2022 +0300

    IGNITE-17240 Provide an ability to configure logging backend through IgniteClient.Builder (#913)
---
 modules/client/pom.xml                             |  28 ++++
 .../org/apache/ignite/client/IgniteClient.java     |  21 ++-
 .../ignite/client/IgniteClientConfiguration.java   |  10 ++
 .../client/IgniteClientConfigurationImpl.java      |  27 ++-
 .../ignite/internal/client/ReliableChannel.java    |  22 +--
 .../ignite/internal/client/TcpIgniteClient.java    |  10 +-
 .../org/apache/ignite/client/ClientArchTest.java   |  79 +++++++++
 .../apache/ignite/client/ClientLoggingTest.java    | 185 +++++++++++++++++++++
 .../management/ClusterManagementGroupManager.java  |   2 +-
 .../cluster/management/raft/ValidationManager.java |   2 +-
 .../internal/compute/ComputeComponentImpl.java     |   5 +-
 .../internal/compute/ComputeComponentImplTest.java |   3 +-
 .../internal/components/LongJvmPauseDetector.java  |  30 ++--
 .../thread/LogUncaughtExceptionHandler.java        |  38 +++++
 .../ignite/internal/thread/NamedThreadFactory.java |  33 ++--
 .../java/org/apache/ignite/lang/IgniteLogger.java  |  55 +++---
 .../java/org/apache/ignite/lang/LoggerFactory.java |  32 ++++
 .../java/org/apache/ignite/logger/NullLogger.java  |   2 +-
 .../internal/testframework/IgniteTestUtils.java    |   9 +-
 .../client/ItMetaStorageRaftGroupTest.java         |   2 +-
 .../client/ItMetaStorageServiceTest.java           |   2 +-
 .../persistence/checkpoint/Checkpointer.java       |   2 +-
 .../service/ItAbstractListenerSnapshotTest.java    |   5 +-
 .../raft/server/ItJraftCounterServerTest.java      |   2 +-
 .../raft/server/ItSimpleCounterServerTest.java     |   2 +-
 .../java/org/apache/ignite/internal/raft/Loza.java |   4 +-
 .../org/apache/ignite/raft/jraft/JRaftUtils.java   |   7 +-
 .../ignite/raft/jraft/core/TimerManager.java       |   5 +-
 .../raft/jraft/disruptor/DisruptorBuilder.java     |   3 +-
 .../raft/jraft/disruptor/StripedDisruptor.java     |   2 +-
 .../storage/impl/DefaultLogStorageFactory.java     |   5 +-
 .../ignite/raft/jraft/util/RepeatedTimer.java      |   2 +-
 .../DefaultFixedThreadsExecutorGroupFactory.java   |   5 +-
 .../concurrent/DefaultSingleThreadExecutor.java    |   4 +-
 .../jraft/util/timer/DefaultRaftTimerFactory.java  |   5 +-
 .../ignite/raft/jraft/util/timer/DefaultTimer.java |   5 +-
 .../raft/jraft/core/RaftGroupServiceTest.java      |   2 +-
 .../concurrent/MpscSingleThreadExecutorTest.java   |   2 +-
 .../concurrent/SingleThreadExecutorBenchmark.java  |  16 +-
 .../org/apache/ignite/internal/app/IgniteImpl.java |   2 +-
 .../storage/DistributedConfigurationStorage.java   |   2 +-
 .../storage/LocalConfigurationStorage.java         |   2 +-
 .../sql/engine/exec/QueryTaskExecutorImpl.java     |   3 +-
 .../sql/engine/prepare/PrepareServiceImpl.java     |   5 +-
 .../sql/engine/exec/rel/AbstractExecutionTest.java |   3 +-
 .../PersistentPageMemoryPartitionStorageTest.java  |   3 +-
 .../storage/rocksdb/RocksDbStorageEngine.java      |   5 +-
 .../distributed/ItInternalTableScanTest.java       |   5 +-
 .../distributed/ItTxDistributedTestSingleNode.java |   5 +-
 .../internal/table/distributed/TableManager.java   |   2 +-
 .../table/distributed/TableManagerTest.java        |   5 +-
 .../vault/persistence/PersistentVaultService.java  |   5 +-
 parent/pom.xml                                     |  15 ++
 53 files changed, 608 insertions(+), 129 deletions(-)

diff --git a/modules/client/pom.xml b/modules/client/pom.xml
index fd791efa2..3a90c1953 100644
--- a/modules/client/pom.xml
+++ b/modules/client/pom.xml
@@ -104,6 +104,16 @@
             <scope>test</scope>
         </dependency>
 
+        <dependency>
+            <groupId>com.tngtech.archunit</groupId>
+            <artifactId>archunit</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.tngtech.archunit</groupId>
+            <artifactId>archunit-junit5</artifactId>
+        </dependency>
+
         <dependency>
             <groupId>org.apache.ignite</groupId>
             <artifactId>ignite-core</artifactId>
@@ -144,5 +154,23 @@
                 <filtering>true</filtering>
             </resource>
         </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>install</phase>
+                        <goals>
+                            <goal>copy-dependencies</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/libs</outputDirectory>
+                            <includeScope>runtime</includeScope>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
     </build>
 </project>
diff --git a/modules/client/src/main/java/org/apache/ignite/client/IgniteClient.java b/modules/client/src/main/java/org/apache/ignite/client/IgniteClient.java
index afa48b7fc..e0c00e76f 100644
--- a/modules/client/src/main/java/org/apache/ignite/client/IgniteClient.java
+++ b/modules/client/src/main/java/org/apache/ignite/client/IgniteClient.java
@@ -32,6 +32,7 @@ import java.util.function.Function;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.internal.client.IgniteClientConfigurationImpl;
 import org.apache.ignite.internal.client.TcpIgniteClient;
+import org.apache.ignite.lang.LoggerFactory;
 import org.apache.ignite.network.ClusterNode;
 
 /**
@@ -88,6 +89,8 @@ public interface IgniteClient extends Ignite {
         /** Retry policy. */
         private RetryPolicy retryPolicy = new RetryReadPolicy();
 
+        private LoggerFactory loggerFactory;
+
         /**
          * Sets the addresses of Ignite server nodes within a cluster. An address can be an IP address or a hostname, with or without port.
          * If port is not set then Ignite will generate multiple addresses for default port range. See {@link
@@ -119,6 +122,20 @@ public interface IgniteClient extends Ignite {
             return this;
         }
 
+        /**
+         * Sets the logger factory. This factory will be used to create a logger instance when needed.
+         *
+         * <p>When {@code null} (default), {@link System#getLogger} is used.
+         *
+         * @param loggerFactory A factory.
+         * @return This instance.
+         */
+        public Builder loggerFactory(LoggerFactory loggerFactory) {
+            this.loggerFactory = loggerFactory;
+
+            return this;
+        }
+
         /**
          * Sets the socket connection timeout, in milliseconds.
          *
@@ -246,7 +263,9 @@ public interface IgniteClient extends Ignite {
                     reconnectThrottlingRetries,
                     asyncContinuationExecutor,
                     heartbeatInterval,
-                    retryPolicy);
+                    retryPolicy,
+                    loggerFactory
+            );
 
             return TcpIgniteClient.startAsync(cfg);
         }
diff --git a/modules/client/src/main/java/org/apache/ignite/client/IgniteClientConfiguration.java b/modules/client/src/main/java/org/apache/ignite/client/IgniteClientConfiguration.java
index 81161e7a0..26b0d3802 100644
--- a/modules/client/src/main/java/org/apache/ignite/client/IgniteClientConfiguration.java
+++ b/modules/client/src/main/java/org/apache/ignite/client/IgniteClientConfiguration.java
@@ -20,6 +20,7 @@ package org.apache.ignite.client;
 import java.util.concurrent.Executor;
 import java.util.concurrent.ForkJoinPool;
 import java.util.function.Function;
+import org.apache.ignite.lang.LoggerFactory;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -119,4 +120,13 @@ public interface IgniteClientConfiguration {
      * @return Heartbeat interval.
      */
     public long heartbeatInterval();
+
+    /**
+     * Returns the logger factory. This factory will be used to create a logger instance when needed.
+     *
+     * <p>When {@code null} (default), {@link System#getLogger} is used.
+     *
+     * @return Configured logger factory.
+     */
+    @Nullable LoggerFactory loggerFactory();
 }
diff --git a/modules/client/src/main/java/org/apache/ignite/internal/client/IgniteClientConfigurationImpl.java b/modules/client/src/main/java/org/apache/ignite/internal/client/IgniteClientConfigurationImpl.java
index ed3be61c3..d16168951 100644
--- a/modules/client/src/main/java/org/apache/ignite/internal/client/IgniteClientConfigurationImpl.java
+++ b/modules/client/src/main/java/org/apache/ignite/internal/client/IgniteClientConfigurationImpl.java
@@ -21,6 +21,7 @@ import java.util.concurrent.Executor;
 import org.apache.ignite.client.IgniteClientAddressFinder;
 import org.apache.ignite.client.IgniteClientConfiguration;
 import org.apache.ignite.client.RetryPolicy;
+import org.apache.ignite.lang.LoggerFactory;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -51,15 +52,20 @@ public final class IgniteClientConfigurationImpl implements IgniteClientConfigur
     /** Retry policy. */
     private final RetryPolicy retryPolicy;
 
+    private final LoggerFactory loggerFactory;
+
     /**
      * Constructor.
      *
-     * @param addressFinder             Address finder.
-     * @param addresses                 Addresses.
-     * @param connectTimeout            Socket connect timeout.
+     * @param addressFinder Address finder.
+     * @param addresses  Addresses.
+     * @param connectTimeout Socket connect timeout.
+     * @param reconnectThrottlingPeriod Reconnect throttling period, in milliseconds.
+     * @param reconnectThrottlingRetries Reconnect throttling retries.
      * @param asyncContinuationExecutor Async continuation executor.
-     * @param heartbeatInterval         Heartbeat message interval.
-     * @param retryPolicy               Retry policy.
+     * @param heartbeatInterval Heartbeat message interval.
+     * @param retryPolicy Retry policy.
+     * @param loggerFactory Logger factory which will be used to create a logger instance for this this particular client when needed.
      */
     public IgniteClientConfigurationImpl(
             IgniteClientAddressFinder addressFinder,
@@ -69,7 +75,9 @@ public final class IgniteClientConfigurationImpl implements IgniteClientConfigur
             int reconnectThrottlingRetries,
             Executor asyncContinuationExecutor,
             long heartbeatInterval,
-            RetryPolicy retryPolicy) {
+            RetryPolicy retryPolicy,
+            LoggerFactory loggerFactory
+    ) {
         this.addressFinder = addressFinder;
 
         //noinspection AssignmentOrReturnOfFieldWithMutableType (cloned in Builder).
@@ -81,6 +89,7 @@ public final class IgniteClientConfigurationImpl implements IgniteClientConfigur
         this.asyncContinuationExecutor = asyncContinuationExecutor;
         this.heartbeatInterval = heartbeatInterval;
         this.retryPolicy = retryPolicy;
+        this.loggerFactory = loggerFactory;
     }
 
     /** {@inheritDoc} */
@@ -125,6 +134,12 @@ public final class IgniteClientConfigurationImpl implements IgniteClientConfigur
         return heartbeatInterval;
     }
 
+    /** {@inheritDoc} */
+    @Override
+    public @Nullable LoggerFactory loggerFactory() {
+        return loggerFactory;
+    }
+
     /** {@inheritDoc} */
     @Override
     public @Nullable RetryPolicy retryPolicy() {
diff --git a/modules/client/src/main/java/org/apache/ignite/internal/client/ReliableChannel.java b/modules/client/src/main/java/org/apache/ignite/internal/client/ReliableChannel.java
index a942f7cde..6d1db166f 100644
--- a/modules/client/src/main/java/org/apache/ignite/internal/client/ReliableChannel.java
+++ b/modules/client/src/main/java/org/apache/ignite/internal/client/ReliableChannel.java
@@ -25,6 +25,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionException;
@@ -45,6 +46,7 @@ import org.apache.ignite.client.RetryPolicy;
 import org.apache.ignite.client.RetryPolicyContext;
 import org.apache.ignite.internal.client.io.ClientConnectionMultiplexer;
 import org.apache.ignite.internal.client.io.netty.NettyClientConnectionMultiplexer;
+import org.apache.ignite.lang.IgniteLogger;
 import org.apache.ignite.network.ClusterNode;
 
 /**
@@ -81,6 +83,8 @@ public final class ReliableChannel implements AutoCloseable {
     /** Connection manager. */
     private final ClientConnectionMultiplexer connMgr;
 
+    private final IgniteLogger log;
+
     /** Cache addresses returned by {@code ThinClientAddressFinder}. */
     private volatile String[] prevHostAddrs;
 
@@ -91,17 +95,10 @@ public final class ReliableChannel implements AutoCloseable {
      * @param clientCfg Client config.
      */
     ReliableChannel(BiFunction<ClientChannelConfiguration, ClientConnectionMultiplexer, ClientChannel> chFactory,
-            IgniteClientConfiguration clientCfg) {
-        if (chFactory == null) {
-            throw new NullPointerException("chFactory");
-        }
-
-        if (clientCfg == null) {
-            throw new NullPointerException("clientCfg");
-        }
-
-        this.clientCfg = clientCfg;
-        this.chFactory = chFactory;
+            IgniteClientConfiguration clientCfg, IgniteLogger log) {
+        this.clientCfg = Objects.requireNonNull(clientCfg, "clientCfg");
+        this.chFactory = Objects.requireNonNull(chFactory, "chFactory");
+        this.log = Objects.requireNonNull(log, "log");
 
         connMgr = new NettyClientConnectionMultiplexer();
         connMgr.start(clientCfg);
@@ -271,6 +268,9 @@ public final class ReliableChannel implements AutoCloseable {
                         }
 
                         if (shouldRetry(opCode, attempt, connectionErr)) {
+                            log.debug("Going to retry request because of error [opCode={}, currentAttempt={}, errMsg={}]",
+                                    failure0, opCode, attempt, failure0.getMessage());
+
                             handleServiceAsync(fut, opCode, payloadWriter, payloadReader, null, failure0, attempt + 1);
 
                             return null;
diff --git a/modules/client/src/main/java/org/apache/ignite/internal/client/TcpIgniteClient.java b/modules/client/src/main/java/org/apache/ignite/internal/client/TcpIgniteClient.java
index 53ab95209..9c888820d 100644
--- a/modules/client/src/main/java/org/apache/ignite/internal/client/TcpIgniteClient.java
+++ b/modules/client/src/main/java/org/apache/ignite/internal/client/TcpIgniteClient.java
@@ -35,6 +35,8 @@ import org.apache.ignite.internal.client.sql.ClientSql;
 import org.apache.ignite.internal.client.table.ClientTables;
 import org.apache.ignite.internal.client.tx.ClientTransactions;
 import org.apache.ignite.internal.jdbc.proto.ClientMessage;
+import org.apache.ignite.lang.IgniteLogger;
+import org.apache.ignite.lang.LoggerFactory;
 import org.apache.ignite.network.ClusterNode;
 import org.apache.ignite.network.NetworkAddress;
 import org.apache.ignite.sql.IgniteSql;
@@ -87,7 +89,13 @@ public class TcpIgniteClient implements IgniteClient {
 
         this.cfg = cfg;
 
-        ch = new ReliableChannel(chFactory, cfg);
+        var loggerFactory = cfg.loggerFactory() == null
+                ? (LoggerFactory) System::getLogger
+                : cfg.loggerFactory();
+
+        var log = IgniteLogger.forClass(TcpIgniteClient.class, loggerFactory);
+
+        ch = new ReliableChannel(chFactory, cfg, log);
         tables = new ClientTables(ch);
         transactions = new ClientTransactions(ch);
         compute = new ClientCompute(ch, tables);
diff --git a/modules/client/src/test/java/org/apache/ignite/client/ClientArchTest.java b/modules/client/src/test/java/org/apache/ignite/client/ClientArchTest.java
new file mode 100644
index 000000000..07371fee9
--- /dev/null
+++ b/modules/client/src/test/java/org/apache/ignite/client/ClientArchTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.client;
+
+import com.tngtech.archunit.core.domain.JavaModifier;
+import com.tngtech.archunit.core.importer.Location;
+import com.tngtech.archunit.junit.AnalyzeClasses;
+import com.tngtech.archunit.junit.ArchTest;
+import com.tngtech.archunit.junit.LocationProvider;
+import com.tngtech.archunit.lang.ArchRule;
+import com.tngtech.archunit.lang.syntax.ArchRuleDefinition;
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.jar.JarFile;
+import org.apache.ignite.client.ClientArchTest.ClassesWithLibsLocationProvider;
+import org.apache.ignite.lang.IgniteLogger;
+
+/**
+ * This test ensures static logger is not used in the modules the client module relies on.
+ *
+ * <p>It's possible to specify a custom logger for an Ignite client, and that configured logger should be used everywhere throughout
+ * a client, that's why we shouldn't use a static logger.
+ */
+@AnalyzeClasses(
+        locations = ClassesWithLibsLocationProvider.class
+)
+public class ClientArchTest {
+    static class ClassesWithLibsLocationProvider implements LocationProvider {
+        @Override
+        public Set<Location> get(Class<?> testClass) {
+            var locations = new HashSet<Location>();
+
+            // both target/classes and target/libs defines a runtime scope of this particular module
+            locations.add(Location.of(Paths.get("target", "classes")));
+
+            var libDir = Paths.get("target", "libs").toFile();
+
+            if (!libDir.exists()) {
+                throw new AssertionError("Expect \"libs\" directory to exist. Try to run 'mvn clean install'");
+            }
+
+            for (var lib : libDir.listFiles()) {
+                if (!lib.getName().endsWith(".jar")) {
+                    continue;
+                }
+
+                try {
+                    locations.add(Location.of(new JarFile(lib)));
+                } catch (IOException e) {
+                    throw new AssertionError("Unable to read jar file", e);
+                }
+            }
+
+            return locations;
+        }
+    }
+
+    @ArchTest
+    public static final ArchRule NO_STATIC_LOGGER_FIELD = ArchRuleDefinition.noFields()
+            .that().haveRawType(IgniteLogger.class)
+            .should().haveModifier(JavaModifier.STATIC);
+}
diff --git a/modules/client/src/test/java/org/apache/ignite/client/ClientLoggingTest.java b/modules/client/src/test/java/org/apache/ignite/client/ClientLoggingTest.java
new file mode 100644
index 000000000..9893237d9
--- /dev/null
+++ b/modules/client/src/test/java/org/apache/ignite/client/ClientLoggingTest.java
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.client;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.startsWith;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.lang.System.Logger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ResourceBundle;
+import java.util.function.Supplier;
+import org.apache.ignite.client.fakes.FakeIgnite;
+import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.lang.LoggerFactory;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests verifies an ability to set custom logger to the client.
+ */
+public class ClientLoggingTest {
+    /** Test server. */
+    TestServer server;
+
+    /** Test server 2. */
+    TestServer server2;
+
+    @AfterEach
+    void tearDown() throws Exception {
+        IgniteUtils.closeAll(server, server2);
+    }
+
+    @Test
+    public void loggersSetToDifferentClientsNotInterfereWithEachOther() throws Exception {
+        FakeIgnite ignite1 = new FakeIgnite();
+        ignite1.tables().createTable("t", c -> {});
+
+        server = startServer(10900, ignite1);
+
+        var loggerFactory1 = new TestLoggerFactory("client1");
+        var loggerFactory2 = new TestLoggerFactory("client2");
+
+        var client1 = createClient(loggerFactory1);
+        var client2 = createClient(loggerFactory2);
+
+        assertEquals("t", client1.tables().tables().get(0).name());
+        assertEquals("t", client2.tables().tables().get(0).name());
+
+        assertThat(loggerFactory1.logger.entries(), empty());
+        assertThat(loggerFactory2.logger.entries(), empty());
+
+        server.close();
+
+        FakeIgnite ignite2 = new FakeIgnite();
+        ignite2.tables().createTable("t2", c -> {});
+
+        server2 = startServer(10950, ignite2);
+
+        assertEquals("t2", client1.tables().tables().get(0).name());
+        assertEquals("t2", client2.tables().tables().get(0).name());
+
+        assertThat(loggerFactory1.logger.entries(), not(empty()));
+        assertThat(loggerFactory2.logger.entries(), not(empty()));
+
+        loggerFactory1.logger.entries().forEach(msg -> assertThat(msg, startsWith("client1:")));
+        loggerFactory2.logger.entries().forEach(msg -> assertThat(msg, startsWith("client2:")));
+    }
+
+    private TestServer startServer(int port, FakeIgnite ignite) {
+        return AbstractClientTest.startServer(
+                port,
+                10,
+                0,
+                ignite
+        );
+    }
+
+    private IgniteClient createClient(LoggerFactory loggerFactory) {
+        return IgniteClient.builder()
+                .addresses("127.0.0.1:10900..10910", "127.0.0.1:10950..10960")
+                .retryPolicy(new RetryLimitPolicy().retryLimit(1))
+                .loggerFactory(loggerFactory)
+                .build();
+    }
+
+    private static class TestLoggerFactory implements LoggerFactory {
+        private final SimpleCapturingLogger logger;
+
+        public TestLoggerFactory(String factoryName) {
+            this.logger = new SimpleCapturingLogger(factoryName);
+        }
+
+        @Override
+        public Logger forName(String name) {
+            return logger;
+        }
+    }
+
+    private static class SimpleCapturingLogger implements System.Logger {
+        private final String name;
+
+        private final List<String> logEntries = new ArrayList<>();
+
+        public SimpleCapturingLogger(String name) {
+            this.name = name;
+        }
+
+        @Override
+        public String getName() {
+            return name;
+        }
+
+        @Override
+        public boolean isLoggable(Level level) {
+            return true;
+        }
+
+        @Override
+        public void log(Level level, String msg) {
+            captureLog(msg);
+        }
+
+        @Override
+        public void log(Level level, Supplier<String> msgSupplier) {
+            throw new AssertionError("Should not be called");
+        }
+
+        @Override
+        public void log(Level level, Object obj) {
+            throw new AssertionError("Should not be called");
+        }
+
+        @Override
+        public void log(Level level, String msg, Throwable thrown) {
+            captureLog(msg);
+        }
+
+        @Override
+        public void log(Level level, Supplier<String> msgSupplier, Throwable thrown) {
+            throw new AssertionError("Should not be called");
+        }
+
+        @Override
+        public void log(Level level, String format, Object... params) {
+            throw new AssertionError("Should not be called");
+        }
+
+        @Override
+        public void log(Level level, ResourceBundle bundle, String msg, Throwable thrown) {
+            throw new AssertionError("Should not be called");
+        }
+
+        @Override
+        public void log(Level level, ResourceBundle bundle, String format, Object... params) {
+            throw new AssertionError("Should not be called");
+        }
+
+        public List<String> entries() {
+            return logEntries;
+        }
+
+        private void captureLog(String msg) {
+            logEntries.add(name + ":" + msg);
+        }
+    }
+}
diff --git a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterManagementGroupManager.java b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterManagementGroupManager.java
index 522a0b9fd..2d3c7c18d 100644
--- a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterManagementGroupManager.java
+++ b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterManagementGroupManager.java
@@ -106,7 +106,7 @@ public class ClusterManagementGroupManager implements IgniteComponent {
 
     /** Delayed executor. */
     private final ScheduledExecutorService scheduledExecutor =
-            Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("cmg-manager"));
+            Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("cmg-manager", LOG));
 
     private final ClusterService clusterService;
 
diff --git a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/raft/ValidationManager.java b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/raft/ValidationManager.java
index 79dcfb0d7..07b07e845 100644
--- a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/raft/ValidationManager.java
+++ b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/raft/ValidationManager.java
@@ -46,7 +46,7 @@ class ValidationManager implements AutoCloseable {
     private static final IgniteLogger LOG = IgniteLogger.forClass(CmgRaftGroupListener.class);
 
     private final ScheduledExecutorService executor =
-            Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("node-validator"));
+            Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("node-validator", LOG));
 
     private final RaftStorageManager storage;
 
diff --git a/modules/compute/src/main/java/org/apache/ignite/internal/compute/ComputeComponentImpl.java b/modules/compute/src/main/java/org/apache/ignite/internal/compute/ComputeComponentImpl.java
index 5a9241574..15565abed 100644
--- a/modules/compute/src/main/java/org/apache/ignite/internal/compute/ComputeComponentImpl.java
+++ b/modules/compute/src/main/java/org/apache/ignite/internal/compute/ComputeComponentImpl.java
@@ -39,6 +39,7 @@ import org.apache.ignite.internal.thread.NamedThreadFactory;
 import org.apache.ignite.internal.util.IgniteSpinBusyLock;
 import org.apache.ignite.internal.util.IgniteUtils;
 import org.apache.ignite.lang.IgniteInternalException;
+import org.apache.ignite.lang.IgniteLogger;
 import org.apache.ignite.lang.NodeStoppingException;
 import org.apache.ignite.network.ClusterNode;
 import org.apache.ignite.network.MessagingService;
@@ -49,6 +50,8 @@ import org.jetbrains.annotations.Nullable;
  * Implementation of {@link ComputeComponent}.
  */
 public class ComputeComponentImpl implements ComputeComponent {
+    private static final IgniteLogger LOG = IgniteLogger.forClass(ComputeComponentImpl.class);
+
     private static final long NETWORK_TIMEOUT_MILLIS = Long.MAX_VALUE;
 
     private static final long THREAD_KEEP_ALIVE_SECONDS = 60;
@@ -192,7 +195,7 @@ public class ComputeComponentImpl implements ComputeComponent {
                 THREAD_KEEP_ALIVE_SECONDS,
                 TimeUnit.SECONDS,
                 newExecutorServiceTaskQueue(),
-                new NamedThreadFactory("[" + ignite.name() + "] Compute-")
+                new NamedThreadFactory(NamedThreadFactory.threadPrefix(ignite.name(), "compute"), LOG)
         );
 
         messagingService.addMessageHandler(ComputeMessageTypes.class, (message, senderAddr, correlationId) -> {
diff --git a/modules/compute/src/test/java/org/apache/ignite/internal/compute/ComputeComponentImplTest.java b/modules/compute/src/test/java/org/apache/ignite/internal/compute/ComputeComponentImplTest.java
index 44658904b..fe1555822 100644
--- a/modules/compute/src/test/java/org/apache/ignite/internal/compute/ComputeComponentImplTest.java
+++ b/modules/compute/src/test/java/org/apache/ignite/internal/compute/ComputeComponentImplTest.java
@@ -55,6 +55,7 @@ import org.apache.ignite.configuration.schemas.compute.ComputeConfiguration;
 import org.apache.ignite.internal.compute.message.ExecuteRequest;
 import org.apache.ignite.internal.compute.message.ExecuteResponse;
 import org.apache.ignite.internal.testframework.IgniteTestUtils;
+import org.apache.ignite.internal.thread.NamedThreadFactory;
 import org.apache.ignite.lang.NodeStoppingException;
 import org.apache.ignite.network.ClusterNode;
 import org.apache.ignite.network.MessagingService;
@@ -319,7 +320,7 @@ class ComputeComponentImplTest {
     void executorThreadsAreNamedAccordingly() throws Exception {
         String threadName = computeComponent.executeLocally(GetThreadNameJob.class).get();
 
-        assertThat(threadName, startsWith("[" + INSTANCE_NAME + "] Compute-"));
+        assertThat(threadName, startsWith(NamedThreadFactory.threadPrefix(INSTANCE_NAME, "compute")));
     }
 
     @Test
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/components/LongJvmPauseDetector.java b/modules/core/src/main/java/org/apache/ignite/internal/components/LongJvmPauseDetector.java
index f77baa734..4930d8932 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/components/LongJvmPauseDetector.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/components/LongJvmPauseDetector.java
@@ -61,9 +61,6 @@ public class LongJvmPauseDetector implements IgniteComponent {
     /** Disabled flag. */
     private static final boolean DISABLED = getBoolean("IGNITE_JVM_PAUSE_DETECTOR_DISABLED");
 
-    /** The logger. */
-    private static final IgniteLogger LOG = IgniteLogger.forClass(LongJvmPauseDetector.class);
-
     /** Worker reference. */
     private final AtomicReference<Thread> workerRef = new AtomicReference<>();
 
@@ -84,17 +81,18 @@ public class LongJvmPauseDetector implements IgniteComponent {
 
     private final String nodeName;
 
-    public LongJvmPauseDetector(String nodeName) {
+    private final IgniteLogger log;
+
+    public LongJvmPauseDetector(String nodeName, IgniteLogger log) {
         this.nodeName = nodeName;
+        this.log = log;
     }
 
     /** {@inheritDoc} */
     @Override
     public void start() {
         if (DISABLED) {
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("JVM Pause Detector is disabled.");
-            }
+            log.debug("JVM Pause Detector is disabled");
 
             return;
         }
@@ -107,9 +105,7 @@ public class LongJvmPauseDetector implements IgniteComponent {
                     lastWakeUpTime = System.currentTimeMillis();
                 }
 
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug(getName() + " has been started.");
-                }
+                log.debug(getName() + " has been started");
 
                 while (true) {
                     try {
@@ -119,7 +115,7 @@ public class LongJvmPauseDetector implements IgniteComponent {
                         final long pause = now - PRECISION - lastWakeUpTime;
 
                         if (pause >= threshold) {
-                            LOG.warn("Possible too long JVM pause: " + pause + " milliseconds.");
+                            log.warn("Possible too long JVM pause: " + pause + " milliseconds");
 
                             synchronized (LongJvmPauseDetector.this) {
                                 final int next = (int) (longPausesCnt % EVT_CNT);
@@ -141,9 +137,9 @@ public class LongJvmPauseDetector implements IgniteComponent {
                         }
                     } catch (InterruptedException e) {
                         if (workerRef.compareAndSet(this, null)) {
-                            LOG.error(getName() + " has been interrupted.", e);
-                        } else if (LOG.isDebugEnabled()) {
-                            LOG.debug(getName() + " has been stopped.");
+                            log.error(getName() + " has been interrupted", e);
+                        } else {
+                            log.debug(getName() + " has been stopped");
                         }
 
                         break;
@@ -153,7 +149,7 @@ public class LongJvmPauseDetector implements IgniteComponent {
         };
 
         if (!workerRef.compareAndSet(null, worker)) {
-            LOG.warn(LongJvmPauseDetector.class.getSimpleName() + " already started!");
+            log.warn(LongJvmPauseDetector.class.getSimpleName() + " already started");
 
             return;
         }
@@ -161,9 +157,7 @@ public class LongJvmPauseDetector implements IgniteComponent {
         worker.setDaemon(true);
         worker.start();
 
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("LongJVMPauseDetector was successfully started");
-        }
+        log.debug("LongJVMPauseDetector was successfully started");
     }
 
     /** {@inheritDoc} */
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/LogUncaughtExceptionHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/LogUncaughtExceptionHandler.java
new file mode 100644
index 000000000..2a61c8086
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/LogUncaughtExceptionHandler.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.thread;
+
+import java.util.Objects;
+import org.apache.ignite.lang.IgniteLogger;
+
+/**
+ * Print uncaught exceptions to log. Default handler of uncaught exceptions for thread pools.
+ */
+public final class LogUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
+    private final IgniteLogger log;
+
+    public LogUncaughtExceptionHandler(IgniteLogger log) {
+        this.log = Objects.requireNonNull(log, "log");
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void uncaughtException(Thread t, Throwable e) {
+        log.error("Uncaught exception in thread {}", e, t);
+    }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/NamedThreadFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/NamedThreadFactory.java
index 60333a22a..de529b65b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/thread/NamedThreadFactory.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/NamedThreadFactory.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.thread;
 
+import java.util.Objects;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.ignite.lang.IgniteLogger;
@@ -25,12 +26,6 @@ import org.apache.ignite.lang.IgniteLogger;
  * Named thread factory with prefix.
  */
 public class NamedThreadFactory implements ThreadFactory {
-    /** Logger. */
-    private static final IgniteLogger LOG = IgniteLogger.forClass(NamedThreadFactory.class);
-
-    /** LogUncaughtExceptionHandler is used as default handler for uncaught exceptions. */
-    private static final LogUncaughtExceptionHandler DFLT_LOG_UNCAUGHT_EX_HANDLER = new LogUncaughtExceptionHandler();
-
     /** Thread prefix. */
     private final String prefix;
 
@@ -47,9 +42,10 @@ public class NamedThreadFactory implements ThreadFactory {
      * Constructor.
      *
      * @param prefix Thread name prefix.
+     * @param log A logger instance is used to create {@link LogUncaughtExceptionHandler}.
      */
-    public NamedThreadFactory(String prefix) {
-        this(prefix, false);
+    public NamedThreadFactory(String prefix, IgniteLogger log) {
+        this(prefix, false, log);
     }
 
     /**
@@ -57,9 +53,10 @@ public class NamedThreadFactory implements ThreadFactory {
      *
      * @param prefix Thread name prefix.
      * @param daemon Daemon flag.
+     * @param log A logger instance is used to create {@link LogUncaughtExceptionHandler}.
      */
-    public NamedThreadFactory(String prefix, boolean daemon) {
-        this(prefix, daemon, DFLT_LOG_UNCAUGHT_EX_HANDLER);
+    public NamedThreadFactory(String prefix, boolean daemon, IgniteLogger log) {
+        this(prefix, daemon, new LogUncaughtExceptionHandler(log));
     }
 
     /**
@@ -67,13 +64,13 @@ public class NamedThreadFactory implements ThreadFactory {
      *
      * @param prefix Thread name prefix.
      * @param daemon Daemon flag.
-     * @param exHnd   Uncaught exception handler.
+     * @param exHnd Uncaught exception handler.
      */
     public NamedThreadFactory(String prefix, boolean daemon, Thread.UncaughtExceptionHandler exHnd) {
         super();
-        this.prefix = prefix;
+        this.prefix = Objects.requireNonNull(prefix, "prefix");
         this.daemon = daemon;
-        this.exHnd = exHnd != null ? exHnd : DFLT_LOG_UNCAUGHT_EX_HANDLER;
+        this.exHnd = Objects.requireNonNull(exHnd, "exHnd");
     }
 
     /** {@inheritDoc} */
@@ -95,14 +92,4 @@ public class NamedThreadFactory implements ThreadFactory {
         return IgniteThread.threadPrefix(nodeName, poolName);
     }
 
-    /**
-     * Print uncaught exceptions to log. Default handler of uncaught exceptions for thread pools.
-     */
-    private static final class LogUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
-        /** {@inheritDoc} */
-        @Override
-        public void uncaughtException(Thread t, Throwable e) {
-            LOG.error("Uncaught exception in thread {}", e, t);
-        }
-    }
 }
diff --git a/modules/core/src/main/java/org/apache/ignite/lang/IgniteLogger.java b/modules/core/src/main/java/org/apache/ignite/lang/IgniteLogger.java
index 8fa7a85f6..808b883b6 100644
--- a/modules/core/src/main/java/org/apache/ignite/lang/IgniteLogger.java
+++ b/modules/core/src/main/java/org/apache/ignite/lang/IgniteLogger.java
@@ -27,25 +27,40 @@ import org.jetbrains.annotations.NotNull;
  */
 public class IgniteLogger {
     /**
-     * Creates logger for class.
+     * Creates logger for given class with system logger as a backend.
      *
      * @param cls The class for a logger.
      * @return Ignite logger.
      */
     public static IgniteLogger forClass(Class<?> cls) {
-        return new IgniteLogger(cls);
+        var delegate = System.getLogger(Objects.requireNonNull(cls).getName());
+
+        return new IgniteLogger(delegate);
+    }
+
+    /**
+     * Creates logger for given class with backend created by the given loggerFactory.
+     *
+     * @param cls The class for a logger.
+     * @param loggerFactory Logger factory to create backend for the logger.
+     * @return Ignite logger.
+     */
+    public static IgniteLogger forClass(Class<?> cls, LoggerFactory loggerFactory) {
+        var delegate = loggerFactory.forName(Objects.requireNonNull(cls).getName());
+
+        return new IgniteLogger(delegate);
     }
 
     /** Logger delegate. */
-    private final System.Logger log;
+    private final System.Logger delegate;
 
     /**
      * Creates logger instance for a category related to the given class.
      *
-     * @param cls The class for a logger.
+     * @param delegate The class for a logger.
      */
-    protected IgniteLogger(@NotNull Class<?> cls) {
-        log = System.getLogger(Objects.requireNonNull(cls).getName());
+    protected IgniteLogger(@NotNull System.Logger delegate) {
+        this.delegate = delegate;
     }
 
     /**
@@ -86,7 +101,7 @@ public class IgniteLogger {
      * @param th  The {@code Throwable} associated with the log message.
      */
     public void info(String msg, Throwable th) {
-        log.log(Level.INFO, msg, th);
+        delegate.log(Level.INFO, msg, th);
     }
 
     /**
@@ -127,7 +142,7 @@ public class IgniteLogger {
      * @param th  The {@code Throwable} associated with the log message;
      */
     public void debug(String msg, Throwable th) {
-        log.log(Level.DEBUG, msg, th);
+        delegate.log(Level.DEBUG, msg, th);
     }
 
     /**
@@ -168,7 +183,7 @@ public class IgniteLogger {
      * @param th  The {@code Throwable} associated with the log message.
      */
     public void warn(String msg, Throwable th) {
-        log.log(Level.WARNING, msg, th);
+        delegate.log(Level.WARNING, msg, th);
     }
 
     /**
@@ -209,7 +224,7 @@ public class IgniteLogger {
      * @param th  The {@code Throwable} associated with the log message.
      */
     public void error(String msg, Throwable th) {
-        log.log(Level.ERROR, msg, th);
+        delegate.log(Level.ERROR, msg, th);
     }
 
     /**
@@ -250,7 +265,7 @@ public class IgniteLogger {
      * @param th  A {@code Throwable} associated with the log message.
      */
     public void trace(String msg, Throwable th) {
-        log.log(Level.TRACE, msg, th);
+        delegate.log(Level.TRACE, msg, th);
     }
 
     /**
@@ -265,14 +280,14 @@ public class IgniteLogger {
     private void logInternal(Level level, String msg, Throwable th, Object... params) {
         Objects.requireNonNull(level);
 
-        if (!log.isLoggable(level)) {
+        if (!delegate.isLoggable(level)) {
             return;
         }
 
         if (th != null) {
-            log.log(level, IgniteStringFormatter.arrayFormat(msg, params), th);
+            delegate.log(level, IgniteStringFormatter.arrayFormat(msg, params), th);
         } else {
-            log.log(level, IgniteStringFormatter.arrayFormat(msg, params));
+            delegate.log(level, IgniteStringFormatter.arrayFormat(msg, params));
         }
     }
 
@@ -288,11 +303,11 @@ public class IgniteLogger {
         Objects.requireNonNull(level);
         Objects.requireNonNull(msgSupplier);
 
-        if (!log.isLoggable(level)) {
+        if (!delegate.isLoggable(level)) {
             return;
         }
 
-        log.log(level, msgSupplier.get(), th);
+        delegate.log(level, msgSupplier.get(), th);
     }
 
     /**
@@ -301,7 +316,7 @@ public class IgniteLogger {
      * @return {@code true} if the message level is currently being logged, {@code false} otherwise.
      */
     public boolean isTraceEnabled() {
-        return log.isLoggable(Level.TRACE);
+        return delegate.isLoggable(Level.TRACE);
     }
 
     /**
@@ -310,7 +325,7 @@ public class IgniteLogger {
      * @return {@code true} if the message level is currently being logged, {@code false} otherwise.
      */
     public boolean isDebugEnabled() {
-        return log.isLoggable(Level.DEBUG);
+        return delegate.isLoggable(Level.DEBUG);
     }
 
     /**
@@ -319,7 +334,7 @@ public class IgniteLogger {
      * @return {@code true} if the message level is currently being logged, {@code false} otherwise.
      */
     public boolean isInfoEnabled() {
-        return log.isLoggable(Level.INFO);
+        return delegate.isLoggable(Level.INFO);
     }
 
     /**
@@ -328,6 +343,6 @@ public class IgniteLogger {
      * @return {@code true} if the message level is currently being logged, {@code false} otherwise.
      */
     public boolean isWarnEnabled() {
-        return log.isLoggable(Level.WARNING);
+        return delegate.isLoggable(Level.WARNING);
     }
 }
diff --git a/modules/core/src/main/java/org/apache/ignite/lang/LoggerFactory.java b/modules/core/src/main/java/org/apache/ignite/lang/LoggerFactory.java
new file mode 100644
index 000000000..c5bc092c3
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/lang/LoggerFactory.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.lang;
+
+/**
+ * An interface describing a factory to create a logger instance.
+ */
+@FunctionalInterface
+public interface LoggerFactory {
+    /**
+     * Creates a logger instance with a given name.
+     *
+     * @param name Name to create logger with.
+     * @return Logger instance.
+     */
+    System.Logger forName(String name);
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/logger/NullLogger.java b/modules/core/src/main/java/org/apache/ignite/logger/NullLogger.java
index 6b12e6aa6..a62cafeea 100644
--- a/modules/core/src/main/java/org/apache/ignite/logger/NullLogger.java
+++ b/modules/core/src/main/java/org/apache/ignite/logger/NullLogger.java
@@ -29,7 +29,7 @@ public class NullLogger extends IgniteLogger {
      * Creates null logger.
      */
     public NullLogger() {
-        super(NullLogger.class);
+        super(System.getLogger(NullLogger.class.getName()));
     }
 
 
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/testframework/IgniteTestUtils.java b/modules/core/src/test/java/org/apache/ignite/internal/testframework/IgniteTestUtils.java
index 46f9ecc83..436dc5832 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/testframework/IgniteTestUtils.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/testframework/IgniteTestUtils.java
@@ -41,6 +41,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.function.BooleanSupplier;
 import org.apache.ignite.internal.thread.NamedThreadFactory;
 import org.apache.ignite.lang.IgniteInternalException;
+import org.apache.ignite.lang.IgniteLogger;
 import org.apache.ignite.lang.IgniteStringFormatter;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -50,6 +51,8 @@ import org.junit.jupiter.api.TestInfo;
  * Utility class for tests.
  */
 public final class IgniteTestUtils {
+    private static final IgniteLogger LOG = IgniteLogger.forClass(IgniteTestUtils.class);
+
     private static final int TIMEOUT_SEC = 5000;
 
     /**
@@ -430,7 +433,7 @@ public final class IgniteTestUtils {
      * @return Future with task result.
      */
     public static <T> CompletableFuture<T> runAsync(final Callable<T> task, String threadName) {
-        final NamedThreadFactory thrFactory = new NamedThreadFactory(threadName);
+        final NamedThreadFactory thrFactory = new NamedThreadFactory(threadName, LOG);
 
         final CompletableFuture<T> fut = new CompletableFuture<T>();
 
@@ -518,7 +521,7 @@ public final class IgniteTestUtils {
     public static long runMultiThreaded(Callable<?> call, int threadNum, String threadName) throws Exception {
         List<Callable<?>> calls = Collections.nCopies(threadNum, call);
 
-        NamedThreadFactory threadFactory = new NamedThreadFactory(threadName);
+        NamedThreadFactory threadFactory = new NamedThreadFactory(threadName, LOG);
 
         return runMultiThreaded(calls, threadFactory);
     }
@@ -550,7 +553,7 @@ public final class IgniteTestUtils {
     public static CompletableFuture<Long> runMultiThreadedAsync(Callable<?> call, int threadNum, final String threadName) {
         List<Callable<?>> calls = Collections.<Callable<?>>nCopies(threadNum, call);
 
-        NamedThreadFactory threadFactory = new NamedThreadFactory(threadName);
+        NamedThreadFactory threadFactory = new NamedThreadFactory(threadName, LOG);
 
         return runAsync(() -> runMultiThreaded(calls, threadFactory));
     }
diff --git a/modules/metastorage-client/src/integrationTest/java/org/apache/ignite/internal/metastorage/client/ItMetaStorageRaftGroupTest.java b/modules/metastorage-client/src/integrationTest/java/org/apache/ignite/internal/metastorage/client/ItMetaStorageRaftGroupTest.java
index a9e36c008..bc543a034 100644
--- a/modules/metastorage-client/src/integrationTest/java/org/apache/ignite/internal/metastorage/client/ItMetaStorageRaftGroupTest.java
+++ b/modules/metastorage-client/src/integrationTest/java/org/apache/ignite/internal/metastorage/client/ItMetaStorageRaftGroupTest.java
@@ -180,7 +180,7 @@ public class ItMetaStorageRaftGroupTest {
 
         LOG.info("Cluster started.");
 
-        executor = new ScheduledThreadPoolExecutor(20, new NamedThreadFactory(Loza.CLIENT_POOL_NAME));
+        executor = new ScheduledThreadPoolExecutor(20, new NamedThreadFactory(Loza.CLIENT_POOL_NAME, LOG));
     }
 
     /**
diff --git a/modules/metastorage-client/src/integrationTest/java/org/apache/ignite/internal/metastorage/client/ItMetaStorageServiceTest.java b/modules/metastorage-client/src/integrationTest/java/org/apache/ignite/internal/metastorage/client/ItMetaStorageServiceTest.java
index afe7e53b9..dcb01aeb1 100644
--- a/modules/metastorage-client/src/integrationTest/java/org/apache/ignite/internal/metastorage/client/ItMetaStorageServiceTest.java
+++ b/modules/metastorage-client/src/integrationTest/java/org/apache/ignite/internal/metastorage/client/ItMetaStorageServiceTest.java
@@ -237,7 +237,7 @@ public class ItMetaStorageServiceTest {
 
         LOG.info("Cluster started.");
 
-        executor = new ScheduledThreadPoolExecutor(20, new NamedThreadFactory(Loza.CLIENT_POOL_NAME));
+        executor = new ScheduledThreadPoolExecutor(20, new NamedThreadFactory(Loza.CLIENT_POOL_NAME, LOG));
 
         metaStorageSvc = prepareMetaStorage();
     }
diff --git a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/checkpoint/Checkpointer.java b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/checkpoint/Checkpointer.java
index 3e0a65d06..c4ff483d9 100644
--- a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/checkpoint/Checkpointer.java
+++ b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/checkpoint/Checkpointer.java
@@ -168,7 +168,7 @@ public class Checkpointer extends IgniteWorker {
                     30_000,
                     MILLISECONDS,
                     new LinkedBlockingQueue<>(),
-                    new NamedThreadFactory(CHECKPOINT_RUNNER_THREAD_PREFIX + "-io")
+                    new NamedThreadFactory(CHECKPOINT_RUNNER_THREAD_PREFIX + "-io", log)
             );
         } else {
             checkpointWritePagesPool = null;
diff --git a/modules/raft/src/integrationTest/java/org/apache/ignite/raft/client/service/ItAbstractListenerSnapshotTest.java b/modules/raft/src/integrationTest/java/org/apache/ignite/raft/client/service/ItAbstractListenerSnapshotTest.java
index 92038256d..ba642fd50 100644
--- a/modules/raft/src/integrationTest/java/org/apache/ignite/raft/client/service/ItAbstractListenerSnapshotTest.java
+++ b/modules/raft/src/integrationTest/java/org/apache/ignite/raft/client/service/ItAbstractListenerSnapshotTest.java
@@ -38,6 +38,7 @@ import org.apache.ignite.internal.testframework.WorkDirectory;
 import org.apache.ignite.internal.testframework.WorkDirectoryExtension;
 import org.apache.ignite.internal.thread.NamedThreadFactory;
 import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.lang.IgniteLogger;
 import org.apache.ignite.network.ClusterService;
 import org.apache.ignite.network.NetworkAddress;
 import org.apache.ignite.network.StaticNodeFinder;
@@ -59,6 +60,8 @@ import org.junit.jupiter.params.provider.MethodSource;
  */
 @ExtendWith(WorkDirectoryExtension.class)
 public abstract class ItAbstractListenerSnapshotTest<T extends RaftGroupListener> {
+    private static final IgniteLogger LOG = IgniteLogger.forClass(ItAbstractListenerSnapshotTest.class);
+
     /** Starting server port. */
     private static final int PORT = 5003;
 
@@ -96,7 +99,7 @@ public abstract class ItAbstractListenerSnapshotTest<T extends RaftGroupListener
      */
     @BeforeEach
     public void beforeTest() {
-        executor = new ScheduledThreadPoolExecutor(20, new NamedThreadFactory(Loza.CLIENT_POOL_NAME));
+        executor = new ScheduledThreadPoolExecutor(20, new NamedThreadFactory(Loza.CLIENT_POOL_NAME, LOG));
     }
 
     /**
diff --git a/modules/raft/src/integrationTest/java/org/apache/ignite/raft/server/ItJraftCounterServerTest.java b/modules/raft/src/integrationTest/java/org/apache/ignite/raft/server/ItJraftCounterServerTest.java
index fae72c1a5..85a487520 100644
--- a/modules/raft/src/integrationTest/java/org/apache/ignite/raft/server/ItJraftCounterServerTest.java
+++ b/modules/raft/src/integrationTest/java/org/apache/ignite/raft/server/ItJraftCounterServerTest.java
@@ -149,7 +149,7 @@ class ItJraftCounterServerTest extends RaftServerAbstractTest {
     void before() {
         LOG.info(">>>>>>>>>>>>>>> Start test method: {}", testInfo.getTestMethod().orElseThrow().getName());
 
-        executor = new ScheduledThreadPoolExecutor(20, new NamedThreadFactory(Loza.CLIENT_POOL_NAME));
+        executor = new ScheduledThreadPoolExecutor(20, new NamedThreadFactory(Loza.CLIENT_POOL_NAME, LOG));
     }
 
     /**
diff --git a/modules/raft/src/integrationTest/java/org/apache/ignite/raft/server/ItSimpleCounterServerTest.java b/modules/raft/src/integrationTest/java/org/apache/ignite/raft/server/ItSimpleCounterServerTest.java
index 46da74d31..2b85bb589 100644
--- a/modules/raft/src/integrationTest/java/org/apache/ignite/raft/server/ItSimpleCounterServerTest.java
+++ b/modules/raft/src/integrationTest/java/org/apache/ignite/raft/server/ItSimpleCounterServerTest.java
@@ -116,7 +116,7 @@ class ItSimpleCounterServerTest extends RaftServerAbstractTest {
 
         ClusterService clientNode1 = clusterService(PORT + 1, List.of(addr), true);
 
-        executor = new ScheduledThreadPoolExecutor(20, new NamedThreadFactory(Loza.CLIENT_POOL_NAME));
+        executor = new ScheduledThreadPoolExecutor(20, new NamedThreadFactory(Loza.CLIENT_POOL_NAME, LOG));
 
         client1 = RaftGroupServiceImpl.start(COUNTER_GROUP_ID_0, clientNode1, FACTORY, 1000,
                 List.of(new Peer(serverNode.address())), false, 200, executor).get(3, TimeUnit.SECONDS);
diff --git a/modules/raft/src/main/java/org/apache/ignite/internal/raft/Loza.java b/modules/raft/src/main/java/org/apache/ignite/internal/raft/Loza.java
index af3a5ed10..994fc7557 100644
--- a/modules/raft/src/main/java/org/apache/ignite/internal/raft/Loza.java
+++ b/modules/raft/src/main/java/org/apache/ignite/internal/raft/Loza.java
@@ -103,7 +103,7 @@ public class Loza implements IgniteComponent {
 
         this.executor = new ScheduledThreadPoolExecutor(CLIENT_POOL_SIZE,
                 new NamedThreadFactory(NamedThreadFactory.threadPrefix(clusterNetSvc.localConfiguration().getName(),
-                        CLIENT_POOL_NAME)
+                        CLIENT_POOL_NAME), LOG
                 )
         );
     }
@@ -121,7 +121,7 @@ public class Loza implements IgniteComponent {
 
         this.executor = new ScheduledThreadPoolExecutor(CLIENT_POOL_SIZE,
                 new NamedThreadFactory(NamedThreadFactory.threadPrefix(clusterNetSvc.localConfiguration().getName(),
-                        CLIENT_POOL_NAME)
+                        CLIENT_POOL_NAME), LOG
                 )
         );
     }
diff --git a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/JRaftUtils.java b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/JRaftUtils.java
index 5f5c4593e..d6cf85208 100644
--- a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/JRaftUtils.java
+++ b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/JRaftUtils.java
@@ -22,6 +22,7 @@ import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.ThreadPoolExecutor;
 import org.apache.ignite.internal.thread.NamedThreadFactory;
+import org.apache.ignite.lang.IgniteLogger;
 import org.apache.ignite.network.NetworkAddress;
 import org.apache.ignite.raft.jraft.conf.Configuration;
 import org.apache.ignite.raft.jraft.core.NodeImpl;
@@ -44,6 +45,8 @@ import org.apache.ignite.raft.jraft.util.timer.Timer;
  * Some helper methods for jraft usage.
  */
 public final class JRaftUtils {
+    private static final IgniteLogger LOG = IgniteLogger.forClass(JRaftUtils.class);
+
     /**
      * Bootstrap a non-empty raft node.
      *
@@ -135,7 +138,7 @@ public final class JRaftUtils {
             .maximumThreads(opts.getRpcProcessorThreadPoolSize()) //
             .keepAliveSeconds(60L) //
             .workQueue(new ArrayBlockingQueue<>(10000)) //
-            .threadFactory(new NamedThreadFactory(prefix, true)) //
+            .threadFactory(createThreadFactory(prefix)) //
             .build();
     }
 
@@ -187,7 +190,7 @@ public final class JRaftUtils {
      * @return a new {@link ThreadFactory} instance
      */
     public static ThreadFactory createThreadFactory(final String prefixName) {
-        return new NamedThreadFactory(prefixName, true);
+        return new NamedThreadFactory(prefixName, true, LOG);
     }
 
     /**
diff --git a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/core/TimerManager.java b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/core/TimerManager.java
index d3f546233..9b2c47955 100644
--- a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/core/TimerManager.java
+++ b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/core/TimerManager.java
@@ -20,12 +20,15 @@ import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 import org.apache.ignite.internal.thread.NamedThreadFactory;
+import org.apache.ignite.lang.IgniteLogger;
 import org.apache.ignite.raft.jraft.util.ThreadPoolUtil;
 
 /**
  * The global timer manager.
  */
 public class TimerManager implements Scheduler {
+    private static final IgniteLogger LOG = IgniteLogger.forClass(TimerManager.class);
+
     private final ScheduledExecutorService executor;
 
     public TimerManager(int workerNum) {
@@ -37,7 +40,7 @@ public class TimerManager implements Scheduler {
             .poolName(name) //
             .coreThreads(workerNum) //
             .enableMetric(true) //
-            .threadFactory(new NamedThreadFactory(name, true)) //
+            .threadFactory(new NamedThreadFactory(name, true, LOG)) //
             .build();
     }
 
diff --git a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/disruptor/DisruptorBuilder.java b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/disruptor/DisruptorBuilder.java
index 6d2581852..d9536d649 100644
--- a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/disruptor/DisruptorBuilder.java
+++ b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/disruptor/DisruptorBuilder.java
@@ -31,7 +31,7 @@ import org.apache.ignite.raft.jraft.util.Requires;
 public class DisruptorBuilder<T> {
     private EventFactory<T> eventFactory;
     private Integer ringBufferSize;
-    private ThreadFactory threadFactory = new NamedThreadFactory("Disruptor-", true);
+    private ThreadFactory threadFactory;
     private ProducerType producerType = ProducerType.MULTI;
     private WaitStrategy waitStrategy = new BlockingWaitStrategy();
 
@@ -90,6 +90,7 @@ public class DisruptorBuilder<T> {
     public Disruptor<T> build() {
         Requires.requireNonNull(this.ringBufferSize, " Ring buffer size not set");
         Requires.requireNonNull(this.eventFactory, "Event factory not set");
+        Requires.requireNonNull(this.threadFactory, "Thread factory not set");
 
         return new Disruptor<>(this.eventFactory, this.ringBufferSize, this.threadFactory, this.producerType,
             this.waitStrategy);
diff --git a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/disruptor/StripedDisruptor.java b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/disruptor/StripedDisruptor.java
index 52abf92bc..fa41a6a19 100644
--- a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/disruptor/StripedDisruptor.java
+++ b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/disruptor/StripedDisruptor.java
@@ -79,7 +79,7 @@ public class StripedDisruptor<T extends GroupAware> {
             Disruptor<T> disruptor = DisruptorBuilder.<T>newInstance()
                 .setRingBufferSize(bufferSize)
                 .setEventFactory(eventFactory)
-                .setThreadFactory(new NamedThreadFactory(stripeName, true))
+                .setThreadFactory(new NamedThreadFactory(stripeName, true, LOG))
                 .setProducerType(ProducerType.MULTI)
                 .setWaitStrategy(new BlockingWaitStrategy())
                 .build();
diff --git a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/storage/impl/DefaultLogStorageFactory.java b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/storage/impl/DefaultLogStorageFactory.java
index fb9566baf..3e0a1ac98 100644
--- a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/storage/impl/DefaultLogStorageFactory.java
+++ b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/storage/impl/DefaultLogStorageFactory.java
@@ -29,6 +29,7 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import org.apache.ignite.internal.thread.NamedThreadFactory;
 import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.lang.IgniteLogger;
 import org.apache.ignite.raft.jraft.option.RaftOptions;
 import org.apache.ignite.raft.jraft.storage.LogStorage;
 import org.apache.ignite.raft.jraft.storage.LogStorageFactory;
@@ -47,6 +48,8 @@ import org.rocksdb.util.SizeUnit;
 
 /** Implementation of the {@link LogStorageFactory} that creates {@link RocksDbSharedLogStorage}s. */
 public class DefaultLogStorageFactory implements LogStorageFactory {
+    private static final IgniteLogger LOG = IgniteLogger.forClass(DefaultLogStorageFactory.class);
+
     /** Database path. */
     private final Path path;
 
@@ -75,7 +78,7 @@ public class DefaultLogStorageFactory implements LogStorageFactory {
 
         executorService = Executors.newFixedThreadPool(
                 Runtime.getRuntime().availableProcessors() * 2,
-                new NamedThreadFactory("raft-shared-log-storage-pool")
+                new NamedThreadFactory("raft-shared-log-storage-pool", LOG)
         );
     }
 
diff --git a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/util/RepeatedTimer.java b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/util/RepeatedTimer.java
index 92c66fe60..7c815dd5f 100644
--- a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/util/RepeatedTimer.java
+++ b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/util/RepeatedTimer.java
@@ -48,7 +48,7 @@ public abstract class RepeatedTimer implements Describer {
     }
 
     public RepeatedTimer(final String name, final int timeoutMs) {
-        this(name, timeoutMs, new HashedWheelTimer(new NamedThreadFactory(name, true), 1, TimeUnit.MILLISECONDS, 2048));
+        this(name, timeoutMs, new HashedWheelTimer(new NamedThreadFactory(name, true, LOG), 1, TimeUnit.MILLISECONDS, 2048));
     }
 
     public RepeatedTimer(final String name, final int timeoutMs, final Timer timer) {
diff --git a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/util/concurrent/DefaultFixedThreadsExecutorGroupFactory.java b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/util/concurrent/DefaultFixedThreadsExecutorGroupFactory.java
index 104940e7d..55040dd0a 100644
--- a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/util/concurrent/DefaultFixedThreadsExecutorGroupFactory.java
+++ b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/util/concurrent/DefaultFixedThreadsExecutorGroupFactory.java
@@ -19,6 +19,7 @@ package org.apache.ignite.raft.jraft.util.concurrent;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.ThreadFactory;
 import org.apache.ignite.internal.thread.NamedThreadFactory;
+import org.apache.ignite.lang.IgniteLogger;
 import org.apache.ignite.raft.jraft.util.Requires;
 import org.apache.ignite.raft.jraft.util.Utils;
 
@@ -26,6 +27,8 @@ import org.apache.ignite.raft.jraft.util.Utils;
  * TODO asch switch default executor to threadpoolexecutor + mpsc blocking queue IGNITE-14832
  */
 public final class DefaultFixedThreadsExecutorGroupFactory implements FixedThreadsExecutorGroupFactory {
+    private static final IgniteLogger LOG = IgniteLogger.forClass(DefaultFixedThreadsExecutorGroupFactory.class);
+
     public static final DefaultFixedThreadsExecutorGroupFactory INSTANCE = new DefaultFixedThreadsExecutorGroupFactory();
 
     @Override
@@ -40,7 +43,7 @@ public final class DefaultFixedThreadsExecutorGroupFactory implements FixedThrea
         Requires.requireTrue(nThreads > 0, "nThreads must > 0");
         final boolean mpsc = useMpscQueue && Utils.USE_MPSC_SINGLE_THREAD_EXECUTOR;
         final SingleThreadExecutor[] children = new SingleThreadExecutor[nThreads];
-        final ThreadFactory threadFactory = mpsc ? new NamedThreadFactory(poolName, true) : null;
+        final ThreadFactory threadFactory = mpsc ? new NamedThreadFactory(poolName, true, LOG) : null;
         for (int i = 0; i < nThreads; i++) {
             if (mpsc) {
                 children[i] = new MpscSingleThreadExecutor(maxPendingTasksPerThread, threadFactory);
diff --git a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/util/concurrent/DefaultSingleThreadExecutor.java b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/util/concurrent/DefaultSingleThreadExecutor.java
index 6ef648c9a..567aafe67 100644
--- a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/util/concurrent/DefaultSingleThreadExecutor.java
+++ b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/util/concurrent/DefaultSingleThreadExecutor.java
@@ -20,6 +20,7 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 import org.apache.ignite.internal.thread.NamedThreadFactory;
+import org.apache.ignite.lang.IgniteLogger;
 import org.apache.ignite.raft.jraft.util.ExecutorServiceHelper;
 import org.apache.ignite.raft.jraft.util.ThreadPoolUtil;
 
@@ -27,6 +28,7 @@ import org.apache.ignite.raft.jraft.util.ThreadPoolUtil;
  *
  */
 public final class DefaultSingleThreadExecutor implements SingleThreadExecutor {
+    private static final IgniteLogger LOG = IgniteLogger.forClass(DefaultSingleThreadExecutor.class);
 
     private final SingleThreadExecutor singleThreadExecutor;
 
@@ -91,7 +93,7 @@ public final class DefaultSingleThreadExecutor implements SingleThreadExecutor {
             .maximumThreads(1) //
             .keepAliveSeconds(60L) //
             .workQueue(new LinkedBlockingQueue<>(maxPendingTasks)) //
-            .threadFactory(new NamedThreadFactory(poolName, true)) //
+            .threadFactory(new NamedThreadFactory(poolName, true, LOG)) //
             .build();
 
         return new SingleThreadExecutor() {
diff --git a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/util/timer/DefaultRaftTimerFactory.java b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/util/timer/DefaultRaftTimerFactory.java
index 5710172c0..e600f94aa 100644
--- a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/util/timer/DefaultRaftTimerFactory.java
+++ b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/util/timer/DefaultRaftTimerFactory.java
@@ -18,6 +18,7 @@ package org.apache.ignite.raft.jraft.util.timer;
 
 import java.util.concurrent.TimeUnit;
 import org.apache.ignite.internal.thread.NamedThreadFactory;
+import org.apache.ignite.lang.IgniteLogger;
 import org.apache.ignite.raft.jraft.core.Scheduler;
 import org.apache.ignite.raft.jraft.core.TimerManager;
 
@@ -25,6 +26,8 @@ import org.apache.ignite.raft.jraft.core.TimerManager;
  * RAFT timers and schedulers factory.
  */
 public class DefaultRaftTimerFactory implements RaftTimerFactory {
+    private static final IgniteLogger LOG = IgniteLogger.forClass(DefaultRaftTimerFactory.class);
+
     @Override
     public Timer getElectionTimer(final String name) {
         return createTimer(name);
@@ -47,7 +50,7 @@ public class DefaultRaftTimerFactory implements RaftTimerFactory {
 
     @Override
     public Timer createTimer(final String name) {
-        return new HashedWheelTimer(new NamedThreadFactory(name, true), 1, TimeUnit.MILLISECONDS, 2048);
+        return new HashedWheelTimer(new NamedThreadFactory(name, true, LOG), 1, TimeUnit.MILLISECONDS, 2048);
     }
 
     @Override
diff --git a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/util/timer/DefaultTimer.java b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/util/timer/DefaultTimer.java
index 7b2003934..222710697 100644
--- a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/util/timer/DefaultTimer.java
+++ b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/util/timer/DefaultTimer.java
@@ -22,6 +22,7 @@ import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 import org.apache.ignite.internal.thread.NamedThreadFactory;
+import org.apache.ignite.lang.IgniteLogger;
 import org.apache.ignite.raft.jraft.util.ExecutorServiceHelper;
 import org.apache.ignite.raft.jraft.util.Requires;
 import org.apache.ignite.raft.jraft.util.ThreadPoolUtil;
@@ -30,6 +31,8 @@ import org.apache.ignite.raft.jraft.util.ThreadPoolUtil;
  *
  */
 public class DefaultTimer implements Timer {
+    private static final IgniteLogger LOG = IgniteLogger.forClass(DefaultTimer.class);
+
     private final ScheduledExecutorService scheduledExecutorService;
 
     public DefaultTimer(int workerNum, String name) {
@@ -37,7 +40,7 @@ public class DefaultTimer implements Timer {
             .coreThreads(workerNum) //
             .poolName(name) //
             .enableMetric(true) //
-            .threadFactory(new NamedThreadFactory(name, true)) //
+            .threadFactory(new NamedThreadFactory(name, true, LOG)) //
             .build();
     }
 
diff --git a/modules/raft/src/test/java/org/apache/ignite/raft/jraft/core/RaftGroupServiceTest.java b/modules/raft/src/test/java/org/apache/ignite/raft/jraft/core/RaftGroupServiceTest.java
index 732bea151..7b3d7adb4 100644
--- a/modules/raft/src/test/java/org/apache/ignite/raft/jraft/core/RaftGroupServiceTest.java
+++ b/modules/raft/src/test/java/org/apache/ignite/raft/jraft/core/RaftGroupServiceTest.java
@@ -124,7 +124,7 @@ public class RaftGroupServiceTest {
     void before(TestInfo testInfo) {
         when(cluster.messagingService()).thenReturn(messagingService);
 
-        executor = new ScheduledThreadPoolExecutor(20, new NamedThreadFactory(Loza.CLIENT_POOL_NAME));
+        executor = new ScheduledThreadPoolExecutor(20, new NamedThreadFactory(Loza.CLIENT_POOL_NAME, LOG));
 
         LOG.info(">>>> Starting test {}", testInfo.getTestMethod().orElseThrow().getName());
     }
diff --git a/modules/raft/src/test/java/org/apache/ignite/raft/jraft/util/concurrent/MpscSingleThreadExecutorTest.java b/modules/raft/src/test/java/org/apache/ignite/raft/jraft/util/concurrent/MpscSingleThreadExecutorTest.java
index c59e3bad0..d9e9e8a7f 100644
--- a/modules/raft/src/test/java/org/apache/ignite/raft/jraft/util/concurrent/MpscSingleThreadExecutorTest.java
+++ b/modules/raft/src/test/java/org/apache/ignite/raft/jraft/util/concurrent/MpscSingleThreadExecutorTest.java
@@ -36,7 +36,7 @@ import static org.junit.jupiter.api.Assertions.fail;
 public class MpscSingleThreadExecutorTest {
     private static final IgniteLogger LOG = IgniteLogger.forClass(MpscSingleThreadExecutorTest.class);
 
-    private static final ThreadFactory THREAD_FACTORY = new NamedThreadFactory("test", true);
+    private static final ThreadFactory THREAD_FACTORY = new NamedThreadFactory("test", true, LOG);
 
     @Test
     public void testExecutorIsShutdownWithoutTask() {
diff --git a/modules/raft/src/test/java/org/apache/ignite/raft/jraft/util/concurrent/SingleThreadExecutorBenchmark.java b/modules/raft/src/test/java/org/apache/ignite/raft/jraft/util/concurrent/SingleThreadExecutorBenchmark.java
index c3d05b1c4..c38049b54 100644
--- a/modules/raft/src/test/java/org/apache/ignite/raft/jraft/util/concurrent/SingleThreadExecutorBenchmark.java
+++ b/modules/raft/src/test/java/org/apache/ignite/raft/jraft/util/concurrent/SingleThreadExecutorBenchmark.java
@@ -27,6 +27,7 @@ import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 import io.netty.util.concurrent.DefaultEventExecutor;
 import org.apache.ignite.internal.thread.NamedThreadFactory;
+import org.apache.ignite.lang.IgniteLogger;
 import org.apache.ignite.raft.jraft.util.ExecutorServiceHelper;
 import org.apache.ignite.raft.jraft.util.ThreadPoolUtil;
 import org.jctools.queues.MpscBlockingConsumerArrayQueue;
@@ -50,6 +51,7 @@ import org.openjdk.jmh.runner.options.OptionsBuilder;
 @BenchmarkMode(Mode.Throughput)
 @OutputTimeUnit(TimeUnit.SECONDS)
 public class SingleThreadExecutorBenchmark {
+    private static final IgniteLogger LOG = IgniteLogger.forClass(SingleThreadExecutorBenchmark.class);
 
     private static final int TIMES = 1000000;
     private static final int THREADS = 32;
@@ -98,7 +100,7 @@ public class SingleThreadExecutorBenchmark {
     @Benchmark
     public void nettyDefaultEventExecutor() throws InterruptedException {
         execute(new DefaultSingleThreadExecutor(
-            new DefaultEventExecutor(new NamedThreadFactory("netty_executor", true))));
+            new DefaultEventExecutor(new NamedThreadFactory("netty_executor", true, LOG))));
     }
 
     @Benchmark
@@ -115,7 +117,7 @@ public class SingleThreadExecutorBenchmark {
             .enableMetric(false) //
             .workQueue(new MpscBlockingConsumerArrayQueue<>(TIMES)) // TODO asch IGNITE-15997
             .keepAliveSeconds(60L) //
-            .threadFactory(new NamedThreadFactory("default", true)) //
+            .threadFactory(new NamedThreadFactory("default", true, LOG)) //
             .build();
 
         execute(new DefaultSingleThreadExecutor(pool));
@@ -123,12 +125,12 @@ public class SingleThreadExecutorBenchmark {
 
     @Benchmark
     public void mpscSingleThreadExecutor() throws InterruptedException {
-        execute(new MpscSingleThreadExecutor(TIMES, new NamedThreadFactory("mpsc", true)));
+        execute(new MpscSingleThreadExecutor(TIMES, new NamedThreadFactory("mpsc", true, LOG)));
     }
 
     @Benchmark
     public void mpscSingleThreadExecutorWithConcurrentLinkedQueue() throws InterruptedException {
-        execute(new MpscSingleThreadExecutor(TIMES, new NamedThreadFactory("mpsc_clq", true)) {
+        execute(new MpscSingleThreadExecutor(TIMES, new NamedThreadFactory("mpsc_clq", true, LOG)) {
 
             @Override
             protected Queue<Runnable> newTaskQueue(final int maxPendingTasks) {
@@ -139,7 +141,7 @@ public class SingleThreadExecutorBenchmark {
 
     @Benchmark
     public void mpscSingleThreadExecutorWithLinkedBlockingQueue() throws InterruptedException {
-        execute(new MpscSingleThreadExecutor(TIMES, new NamedThreadFactory("mpsc_lbq", true)) {
+        execute(new MpscSingleThreadExecutor(TIMES, new NamedThreadFactory("mpsc_lbq", true, LOG)) {
 
             @Override
             protected Queue<Runnable> newTaskQueue(final int maxPendingTasks) {
@@ -150,7 +152,7 @@ public class SingleThreadExecutorBenchmark {
 
     @Benchmark
     public void mpscSingleThreadExecutorWithLinkedTransferQueue() throws InterruptedException {
-        execute(new MpscSingleThreadExecutor(TIMES, new NamedThreadFactory("mpsc_ltq", true)) {
+        execute(new MpscSingleThreadExecutor(TIMES, new NamedThreadFactory("mpsc_ltq", true, LOG)) {
 
             @Override
             protected Queue<Runnable> newTaskQueue(final int maxPendingTasks) {
@@ -175,7 +177,7 @@ public class SingleThreadExecutorBenchmark {
             .enableMetric(false) //
             .workQueue(new ArrayBlockingQueue<>(TIMES)) //
             .keepAliveSeconds(60L) //
-            .threadFactory(new NamedThreadFactory("benchmark", true)) //
+            .threadFactory(new NamedThreadFactory("benchmark", true, LOG)) //
             .build();
     }
 }
diff --git a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
index e759524d8..83b5d82d6 100644
--- a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
+++ b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
@@ -204,7 +204,7 @@ public class IgniteImpl implements Ignite {
     IgniteImpl(String name, Path workDir, @Nullable ClassLoader serviceProviderClassLoader) {
         this.name = name;
 
-        longJvmPauseDetector = new LongJvmPauseDetector(name);
+        longJvmPauseDetector = new LongJvmPauseDetector(name, IgniteLogger.forClass(LongJvmPauseDetector.class));
 
         lifecycleManager = new LifecycleManager(name);
 
diff --git a/modules/runner/src/main/java/org/apache/ignite/internal/configuration/storage/DistributedConfigurationStorage.java b/modules/runner/src/main/java/org/apache/ignite/internal/configuration/storage/DistributedConfigurationStorage.java
index 2e04b028a..e7f4d9009 100644
--- a/modules/runner/src/main/java/org/apache/ignite/internal/configuration/storage/DistributedConfigurationStorage.java
+++ b/modules/runner/src/main/java/org/apache/ignite/internal/configuration/storage/DistributedConfigurationStorage.java
@@ -107,7 +107,7 @@ public class DistributedConfigurationStorage implements ConfigurationStorage {
      */
     private final AtomicLong changeId = new AtomicLong(0L);
 
-    private final ExecutorService threadPool = Executors.newFixedThreadPool(4, new NamedThreadFactory("dst-cfg"));
+    private final ExecutorService threadPool = Executors.newFixedThreadPool(4, new NamedThreadFactory("dst-cfg", LOG));
 
     private final InFlightFutures futureTracker = new InFlightFutures();
 
diff --git a/modules/runner/src/main/java/org/apache/ignite/internal/configuration/storage/LocalConfigurationStorage.java b/modules/runner/src/main/java/org/apache/ignite/internal/configuration/storage/LocalConfigurationStorage.java
index 18fc4eabc..bbf4fa194 100644
--- a/modules/runner/src/main/java/org/apache/ignite/internal/configuration/storage/LocalConfigurationStorage.java
+++ b/modules/runner/src/main/java/org/apache/ignite/internal/configuration/storage/LocalConfigurationStorage.java
@@ -64,7 +64,7 @@ public class LocalConfigurationStorage implements ConfigurationStorage {
     /** End key in range for searching local configuration keys. */
     private static final ByteArray LOC_KEYS_END_RANGE = ByteArray.fromString(incrementLastChar(LOC_PREFIX));
 
-    private final ExecutorService threadPool = Executors.newFixedThreadPool(4, new NamedThreadFactory("loc-cfg"));
+    private final ExecutorService threadPool = Executors.newFixedThreadPool(4, new NamedThreadFactory("loc-cfg", LOG));
 
     private final InFlightFutures futureTracker = new InFlightFutures();
 
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/QueryTaskExecutorImpl.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/QueryTaskExecutorImpl.java
index 3d618b3f6..f931e80db 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/QueryTaskExecutorImpl.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/exec/QueryTaskExecutorImpl.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.sql.engine.exec;
 import java.util.UUID;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ThreadLocalRandom;
+import org.apache.ignite.internal.thread.LogUncaughtExceptionHandler;
 import org.apache.ignite.internal.thread.NamedThreadFactory;
 import org.apache.ignite.internal.thread.StripedThreadPoolExecutor;
 import org.apache.ignite.internal.util.IgniteUtils;
@@ -53,7 +54,7 @@ public class QueryTaskExecutorImpl implements QueryTaskExecutor, Thread.Uncaught
         this.stripedThreadPoolExecutor = new StripedThreadPoolExecutor(
                 4,
                 NamedThreadFactory.threadPrefix(nodeName, "sql-execution-pool"),
-                null,
+                new LogUncaughtExceptionHandler(LOG),
                 false,
                 0
         );
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/PrepareServiceImpl.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/PrepareServiceImpl.java
index 20d4942f3..62620e063 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/PrepareServiceImpl.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/PrepareServiceImpl.java
@@ -48,6 +48,7 @@ import org.apache.ignite.internal.sql.engine.util.TypeUtils;
 import org.apache.ignite.internal.storage.DataStorageManager;
 import org.apache.ignite.internal.thread.NamedThreadFactory;
 import org.apache.ignite.lang.IgniteInternalException;
+import org.apache.ignite.lang.IgniteLogger;
 import org.apache.ignite.sql.ColumnMetadata;
 import org.apache.ignite.sql.ResultSetMetadata;
 import org.jetbrains.annotations.Nullable;
@@ -56,6 +57,8 @@ import org.jetbrains.annotations.Nullable;
  * An implementation of the {@link PrepareService} that uses a Calcite-based query planner to validate and optimize a given query.
  */
 public class PrepareServiceImpl implements PrepareService, SchemaUpdateListener {
+    private static final IgniteLogger LOG = IgniteLogger.forClass(PrepareServiceImpl.class);
+
     private static final long THREAD_TIMEOUT_MS = 60_000;
 
     private static final int THREAD_COUNT = 4;
@@ -119,7 +122,7 @@ public class PrepareServiceImpl implements PrepareService, SchemaUpdateListener
                 THREAD_TIMEOUT_MS,
                 TimeUnit.MILLISECONDS,
                 new LinkedBlockingQueue<>(),
-                new NamedThreadFactory(NamedThreadFactory.threadPrefix(nodeName, "sql-planning-pool"))
+                new NamedThreadFactory(NamedThreadFactory.threadPrefix(nodeName, "sql-planning-pool"), LOG)
         );
 
         planningPool.allowCoreThreadTimeOut(true);
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/AbstractExecutionTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/AbstractExecutionTest.java
index 4c8f720ec..ea0144106 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/AbstractExecutionTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/exec/rel/AbstractExecutionTest.java
@@ -42,6 +42,7 @@ import org.apache.ignite.internal.sql.engine.metadata.FragmentDescription;
 import org.apache.ignite.internal.sql.engine.util.BaseQueryContext;
 import org.apache.ignite.internal.testframework.IgniteAbstractTest;
 import org.apache.ignite.internal.testframework.IgniteTestUtils;
+import org.apache.ignite.internal.thread.LogUncaughtExceptionHandler;
 import org.apache.ignite.internal.thread.NamedThreadFactory;
 import org.apache.ignite.internal.thread.StripedThreadPoolExecutor;
 import org.apache.ignite.internal.util.Pair;
@@ -87,7 +88,7 @@ public class AbstractExecutionTest extends IgniteAbstractTest {
         if (withDelays) {
             StripedThreadPoolExecutor testExecutor = new IgniteTestStripedThreadPoolExecutor(8,
                     NamedThreadFactory.threadPrefix("fake-test-node", "sqlTestExec"),
-                    null,
+                    new LogUncaughtExceptionHandler(log),
                     false,
                     0);
             IgniteTestUtils.setFieldValue(taskExecutor, "stripedThreadPoolExecutor", testExecutor);
diff --git a/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryPartitionStorageTest.java b/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryPartitionStorageTest.java
index 1fff51621..887271835 100644
--- a/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryPartitionStorageTest.java
+++ b/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryPartitionStorageTest.java
@@ -47,6 +47,7 @@ import org.apache.ignite.internal.storage.pagememory.configuration.schema.Persis
 import org.apache.ignite.internal.testframework.WorkDirectory;
 import org.apache.ignite.internal.testframework.WorkDirectoryExtension;
 import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.lang.IgniteLogger;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
@@ -96,7 +97,7 @@ public class PersistentPageMemoryPartitionStorageTest extends AbstractPartitionS
     void setUp() throws Exception {
         String nodeName = "test-node";
 
-        longJvmPauseDetector = new LongJvmPauseDetector(nodeName);
+        longJvmPauseDetector = new LongJvmPauseDetector(nodeName, IgniteLogger.forClass(LongJvmPauseDetector.class));
 
         longJvmPauseDetector.start();
 
diff --git a/modules/storage-rocksdb/src/main/java/org/apache/ignite/internal/storage/rocksdb/RocksDbStorageEngine.java b/modules/storage-rocksdb/src/main/java/org/apache/ignite/internal/storage/rocksdb/RocksDbStorageEngine.java
index f4f46fce8..0c7a663a6 100644
--- a/modules/storage-rocksdb/src/main/java/org/apache/ignite/internal/storage/rocksdb/RocksDbStorageEngine.java
+++ b/modules/storage-rocksdb/src/main/java/org/apache/ignite/internal/storage/rocksdb/RocksDbStorageEngine.java
@@ -40,6 +40,7 @@ import org.apache.ignite.internal.storage.rocksdb.configuration.schema.RocksDbDa
 import org.apache.ignite.internal.storage.rocksdb.configuration.schema.RocksDbStorageEngineConfiguration;
 import org.apache.ignite.internal.thread.NamedThreadFactory;
 import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.lang.IgniteLogger;
 import org.rocksdb.RocksDB;
 
 /**
@@ -49,6 +50,8 @@ public class RocksDbStorageEngine implements StorageEngine {
     /** Engine name. */
     public static final String ENGINE_NAME = "rocksdb";
 
+    private static final IgniteLogger LOG = IgniteLogger.forClass(RocksDbStorageEngine.class);
+
     static {
         RocksDB.loadLibrary();
     }
@@ -59,7 +62,7 @@ public class RocksDbStorageEngine implements StorageEngine {
 
     private final ExecutorService threadPool = Executors.newFixedThreadPool(
             Runtime.getRuntime().availableProcessors(),
-            new NamedThreadFactory("rocksdb-storage-engine-pool")
+            new NamedThreadFactory("rocksdb-storage-engine-pool", LOG)
     );
 
     private final Map<String, RocksDbDataRegion> regions = new ConcurrentHashMap<>();
diff --git a/modules/table/src/integrationTest/java/org/apache/ignite/distributed/ItInternalTableScanTest.java b/modules/table/src/integrationTest/java/org/apache/ignite/distributed/ItInternalTableScanTest.java
index b9d0fd0eb..fd319592d 100644
--- a/modules/table/src/integrationTest/java/org/apache/ignite/distributed/ItInternalTableScanTest.java
+++ b/modules/table/src/integrationTest/java/org/apache/ignite/distributed/ItInternalTableScanTest.java
@@ -68,6 +68,7 @@ import org.apache.ignite.internal.tx.impl.TxManagerImpl;
 import org.apache.ignite.internal.util.ByteUtils;
 import org.apache.ignite.internal.util.Cursor;
 import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.lang.IgniteLogger;
 import org.apache.ignite.network.ClusterNode;
 import org.apache.ignite.network.ClusterService;
 import org.apache.ignite.network.NetworkAddress;
@@ -91,6 +92,8 @@ import org.mockito.junit.jupiter.MockitoExtension;
  */
 @ExtendWith(MockitoExtension.class)
 public class ItInternalTableScanTest {
+    private static final IgniteLogger LOG = IgniteLogger.forClass(ItInternalTableScanTest.class);
+
     private static final RaftMessagesFactory FACTORY = new RaftMessagesFactory();
 
     private static final String TEST_TABLE_NAME = "testTbl";
@@ -165,7 +168,7 @@ public class ItInternalTableScanTest {
                 RaftGroupOptions.defaults()
         );
 
-        executor = new ScheduledThreadPoolExecutor(20, new NamedThreadFactory(Loza.CLIENT_POOL_NAME));
+        executor = new ScheduledThreadPoolExecutor(20, new NamedThreadFactory(Loza.CLIENT_POOL_NAME, LOG));
 
         RaftGroupService raftGrpSvc = RaftGroupServiceImpl.start(
                 RAFT_GRP_ID,
diff --git a/modules/table/src/integrationTest/java/org/apache/ignite/distributed/ItTxDistributedTestSingleNode.java b/modules/table/src/integrationTest/java/org/apache/ignite/distributed/ItTxDistributedTestSingleNode.java
index 84bd2f393..a691e5fca 100644
--- a/modules/table/src/integrationTest/java/org/apache/ignite/distributed/ItTxDistributedTestSingleNode.java
+++ b/modules/table/src/integrationTest/java/org/apache/ignite/distributed/ItTxDistributedTestSingleNode.java
@@ -53,6 +53,7 @@ import org.apache.ignite.internal.tx.impl.HeapLockManager;
 import org.apache.ignite.internal.tx.impl.IgniteTransactionsImpl;
 import org.apache.ignite.internal.tx.impl.TxManagerImpl;
 import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.lang.IgniteLogger;
 import org.apache.ignite.network.ClusterNode;
 import org.apache.ignite.network.ClusterService;
 import org.apache.ignite.network.NetworkAddress;
@@ -73,6 +74,8 @@ import org.mockito.Mockito;
  * Distributed transaction test using a single partition table.
  */
 public class ItTxDistributedTestSingleNode extends TxAbstractTest {
+    private static final IgniteLogger LOG = IgniteLogger.forClass(ItTxDistributedTestSingleNode.class);
+
     public static final int NODE_PORT_BASE = 20_000;
 
     private static final RaftMessagesFactory FACTORY = new RaftMessagesFactory();
@@ -173,7 +176,7 @@ public class ItTxDistributedTestSingleNode extends TxAbstractTest {
         txManagers = new HashMap<>(nodes);
 
         executor = new ScheduledThreadPoolExecutor(20,
-                new NamedThreadFactory(Loza.CLIENT_POOL_NAME));
+                new NamedThreadFactory(Loza.CLIENT_POOL_NAME, LOG));
 
         for (int i = 0; i < nodes; i++) {
             var raftSrv = new Loza(cluster.get(i), workDir.resolve("node" + i));
diff --git a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java
index 23f99d201..030ddf46d 100644
--- a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java
+++ b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java
@@ -231,7 +231,7 @@ public class TableManager extends Producer<TableEvent, TableEventParameters> imp
         tablesByIdVv = new VersionedValue<>(null, HashMap::new);
 
         rebalanceScheduler = new ScheduledThreadPoolExecutor(REBALANCE_SCHEDULER_POOL_SIZE,
-                new NamedThreadFactory("rebalance-scheduler"));
+                new NamedThreadFactory("rebalance-scheduler", LOG));
     }
 
     /** {@inheritDoc} */
diff --git a/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/TableManagerTest.java b/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/TableManagerTest.java
index 06cd02022..6668f47d5 100644
--- a/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/TableManagerTest.java
+++ b/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/TableManagerTest.java
@@ -103,6 +103,7 @@ import org.apache.ignite.internal.tx.TxManager;
 import org.apache.ignite.internal.util.ByteUtils;
 import org.apache.ignite.lang.ByteArray;
 import org.apache.ignite.lang.IgniteException;
+import org.apache.ignite.lang.IgniteLogger;
 import org.apache.ignite.network.ClusterNode;
 import org.apache.ignite.network.ClusterService;
 import org.apache.ignite.network.MessagingService;
@@ -136,6 +137,8 @@ import org.mockito.quality.Strictness;
 @ExtendWith({MockitoExtension.class, ConfigurationExtension.class})
 @MockitoSettings(strictness = Strictness.LENIENT)
 public class TableManagerTest extends IgniteAbstractTest {
+    private static IgniteLogger LOG = IgniteLogger.forClass(TableManagerTest.class);
+
     /** The name of the table which is preconfigured. */
     private static final String PRECONFIGURED_TABLE_NAME = "t1";
 
@@ -667,7 +670,7 @@ public class TableManagerTest extends IgniteAbstractTest {
 
         TableManager tableManager = createTableManager(tblManagerFut, false);
 
-        ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(20, new NamedThreadFactory(Loza.CLIENT_POOL_NAME));
+        ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(20, new NamedThreadFactory(Loza.CLIENT_POOL_NAME, LOG));
 
         String groupId = "test";
 
diff --git a/modules/vault/src/main/java/org/apache/ignite/internal/vault/persistence/PersistentVaultService.java b/modules/vault/src/main/java/org/apache/ignite/internal/vault/persistence/PersistentVaultService.java
index e76674602..8119c4c59 100644
--- a/modules/vault/src/main/java/org/apache/ignite/internal/vault/persistence/PersistentVaultService.java
+++ b/modules/vault/src/main/java/org/apache/ignite/internal/vault/persistence/PersistentVaultService.java
@@ -33,6 +33,7 @@ import org.apache.ignite.internal.vault.VaultEntry;
 import org.apache.ignite.internal.vault.VaultService;
 import org.apache.ignite.lang.ByteArray;
 import org.apache.ignite.lang.IgniteInternalException;
+import org.apache.ignite.lang.IgniteLogger;
 import org.jetbrains.annotations.Nullable;
 import org.rocksdb.BlockBasedTableConfig;
 import org.rocksdb.BloomFilter;
@@ -55,7 +56,9 @@ public class PersistentVaultService implements VaultService {
         RocksDB.loadLibrary();
     }
 
-    private final ExecutorService threadPool = Executors.newFixedThreadPool(4, new NamedThreadFactory("vault"));
+    private static final IgniteLogger LOG = IgniteLogger.forClass(PersistentVaultService.class);
+
+    private final ExecutorService threadPool = Executors.newFixedThreadPool(4, new NamedThreadFactory("vault", LOG));
 
     private final InFlightFutures futureTracker = new InFlightFutures();
 
diff --git a/parent/pom.xml b/parent/pom.xml
index 4da425afd..1c6c7771d 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -102,6 +102,7 @@
         <kryo.version>4.0.1</kryo.version>
         <bytebuddy.version>1.12.8</bytebuddy.version>
         <mock-server.version>5.13.2</mock-server.version>
+        <archunit.version>0.23.1</archunit.version>
 
         <!-- Plugins versions -->
         <apache.rat.plugin.version>0.13</apache.rat.plugin.version>
@@ -771,6 +772,20 @@
                 <scope>test</scope>
             </dependency>
 
+            <dependency>
+                <groupId>com.tngtech.archunit</groupId>
+                <artifactId>archunit</artifactId>
+                <version>${archunit.version}</version>
+                <scope>test</scope>
+            </dependency>
+
+            <dependency>
+                <groupId>com.tngtech.archunit</groupId>
+                <artifactId>archunit-junit5</artifactId>
+                <version>${archunit.version}</version>
+                <scope>test</scope>
+            </dependency>
+
             <dependency>
                 <groupId>com.google.testing.compile</groupId>
                 <artifactId>compile-testing</artifactId>