Skip to content

Commit 432a259

Browse files
authored
Migrate logging API from SLF4J to Log4j 2.x (#459)
* Migrate logging API from SLF4J to Log4j 2.x Standardize all modules on the Log4j 2.x API so Flume's own logging no longer goes through the SLF4J facade. Applied the OpenRewrite Slf4jToLog4j recipe, then normalized the result: drop loggers that were never used, make every logger field private static final named "logger", and use the no-arg LogManager.getLogger() since each one named its own class. Assisted-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Formatting * Ban transitive logging implementations and bridges Dependencies frequently ship a logging backend or an API bridge as a compile dependency, which then leaks to our consumers. Add a maven-enforcer rule that bans every known logging implementation/bridge and whitelists only the real logging APIs. To satisfy the rule, drop the now-unneeded log4j-1.2-api (no Flume code path reaches the Hadoop classes that use the org.apache.log4j API) and exclude the logging backends that Hadoop (reload4j) and ZooKeeper (logback) pull in. Exclusions live in dependencyManagement so they apply wherever the dependency is used, and only where the artifact is actually pulled; the enforcer rule catches anything reintroduced later. Assisted-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Pin SLF4J to 2.x and use the SLF4J 2 binding The ban-logging rule whitelisted the whole log4j2 group, which let the SLF4J 1.x binding (log4j-slf4j-impl) through. Switch the test bindings to log4j-slf4j2-impl and import slf4j-bom so conflict resolution cannot downgrade transitive SLF4J to 1.x. Drop the log4j-jul and log4j-jcl bridges the tightened rule then flagged, and manage commons-logging to a current release so transitive deps stop pulling the ancient 1.2. Assisted-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 51063b4 commit 432a259

133 files changed

Lines changed: 814 additions & 862 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

flume-ng-auth/pom.xml

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,14 @@
4444
<scope>test</scope>
4545
</dependency>
4646

47-
<dependency>
48-
<groupId>org.slf4j</groupId>
49-
<artifactId>slf4j-api</artifactId>
50-
</dependency>
51-
5247
<dependency>
5348
<groupId>org.apache.logging.log4j</groupId>
54-
<artifactId>log4j-slf4j-impl</artifactId>
55-
<scope>test</scope>
49+
<artifactId>log4j-api</artifactId>
5650
</dependency>
5751

5852
<dependency>
5953
<groupId>org.apache.logging.log4j</groupId>
60-
<artifactId>log4j-1.2-api</artifactId>
54+
<artifactId>log4j-slf4j2-impl</artifactId>
6155
<scope>test</scope>
6256
</dependency>
6357

@@ -77,6 +71,7 @@
7771
<artifactId>hadoop-minikdc</artifactId>
7872
<scope>test</scope>
7973
</dependency>
74+
8075
<dependency>
8176
<!-- add this to satisfy the dependency requirement of apacheds-jdbm1 in minikdc-->
8277
<groupId>org.apache.directory.jdbm</groupId>

flume-ng-auth/src/main/java/org/apache/flume/auth/KerberosAuthenticator.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,16 @@
3333
import org.apache.hadoop.security.SecurityUtil;
3434
import org.apache.hadoop.security.UserGroupInformation;
3535
import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
36-
import org.slf4j.Logger;
37-
import org.slf4j.LoggerFactory;
36+
import org.apache.logging.log4j.LogManager;
37+
import org.apache.logging.log4j.Logger;
3838

3939
/**
4040
* A kerberos authenticator, which authenticates using the supplied principal
4141
* and keytab and executes with authenticated privileges
4242
*/
4343
class KerberosAuthenticator implements FlumeAuthenticator {
4444

45-
private static final Logger LOG = LoggerFactory.getLogger(KerberosAuthenticator.class);
45+
private static final Logger logger = LogManager.getLogger();
4646

4747
private volatile UserGroupInformation ugi;
4848
private volatile KerberosUser prevUser;
@@ -146,7 +146,7 @@ public synchronized void authenticate(String principal, String keytab) {
146146
curUser = null;
147147
}
148148
} catch (IOException e) {
149-
LOG.warn("User unexpectedly had no active login. Continuing with " + "authentication", e);
149+
logger.warn("User unexpectedly had no active login. Continuing with " + "authentication", e);
150150
}
151151

152152
/*
@@ -158,13 +158,13 @@ public synchronized void authenticate(String principal, String keytab) {
158158
try {
159159
if (ugi != null) {
160160
if (curUser != null && curUser.getUserName().equals(ugi.getUserName())) {
161-
LOG.debug("Using existing principal login: {}", ugi);
161+
logger.debug("Using existing principal login: {}", ugi);
162162
} else {
163-
LOG.info("Attempting kerberos Re-login as principal ({}) ", new Object[] {ugi.getUserName()});
163+
logger.info("Attempting kerberos Re-login as principal ({}) ", new Object[] {ugi.getUserName()});
164164
ugi.reloginFromKeytab();
165165
}
166166
} else {
167-
LOG.info(
167+
logger.info(
168168
"Attempting kerberos login as principal ({}) from keytab " + "file ({})",
169169
new Object[] {resolvedPrincipal, keytab});
170170
UserGroupInformation.loginUserFromKeytab(resolvedPrincipal, keytab);
@@ -187,7 +187,7 @@ private void printUGI(UserGroupInformation ugi) {
187187
if (ugi != null) {
188188
// dump login information
189189
AuthenticationMethod authMethod = ugi.getAuthenticationMethod();
190-
LOG.info("\n{} \nUser: {} \nAuth method: {} \nKeytab: {} \n", new Object[] {
190+
logger.info("\n{} \nUser: {} \nAuth method: {} \nKeytab: {} \n", new Object[] {
191191
authMethod.equals(AuthenticationMethod.PROXY) ? "Proxy as: " : "Logged as: ",
192192
ugi.getUserName(),
193193
authMethod,
@@ -213,7 +213,7 @@ public void run() {
213213
try {
214214
ugi.checkTGTAndReloginFromKeytab();
215215
} catch (IOException e) {
216-
LOG.warn(
216+
logger.warn(
217217
"Error occured during checkTGTAndReloginFromKeytab() for user " + ugi.getUserName(),
218218
e);
219219
}

flume-ng-channels/flume-file-channel/pom.xml

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@
5353
</dependency>
5454

5555
<dependency>
56-
<groupId>org.slf4j</groupId>
57-
<artifactId>slf4j-api</artifactId>
56+
<groupId>org.apache.logging.log4j</groupId>
57+
<artifactId>log4j-api</artifactId>
5858
</dependency>
5959

6060
<dependency>
@@ -87,19 +87,7 @@
8787

8888
<dependency>
8989
<groupId>org.apache.logging.log4j</groupId>
90-
<artifactId>log4j-jcl</artifactId>
91-
<scope>test</scope>
92-
</dependency>
93-
94-
<dependency>
95-
<groupId>org.apache.logging.log4j</groupId>
96-
<artifactId>log4j-slf4j-impl</artifactId>
97-
<scope>test</scope>
98-
</dependency>
99-
100-
<dependency>
101-
<groupId>org.apache.logging.log4j</groupId>
102-
<artifactId>log4j-1.2-api</artifactId>
90+
<artifactId>log4j-slf4j2-impl</artifactId>
10391
<scope>test</scope>
10492
</dependency>
10593

flume-ng-channels/flume-file-channel/src/main/java/org/apache/flume/channel/file/CheckpointRebuilder.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
import org.apache.commons.cli.Option;
3333
import org.apache.commons.cli.Options;
3434
import org.apache.flume.channel.file.instrumentation.FileChannelCounter;
35-
import org.slf4j.Logger;
36-
import org.slf4j.LoggerFactory;
35+
import org.apache.logging.log4j.LogManager;
36+
import org.apache.logging.log4j.Logger;
3737

3838
public class CheckpointRebuilder {
3939

@@ -45,7 +45,7 @@ public class CheckpointRebuilder {
4545
private final SetMultimap<Long, ComparableFlumeEventPointer> uncommittedTakes = HashMultimap.create();
4646
private final boolean fsyncPerTransaction;
4747

48-
private static Logger LOG = LoggerFactory.getLogger(CheckpointRebuilder.class);
48+
private static final Logger logger = LogManager.getLogger();
4949

5050
public CheckpointRebuilder(List<File> logFiles, FlumeEventQueue queue, boolean fsyncPerTransaction)
5151
throws IOException {
@@ -55,13 +55,13 @@ public CheckpointRebuilder(List<File> logFiles, FlumeEventQueue queue, boolean f
5555
}
5656

5757
public boolean rebuild() throws IOException, Exception {
58-
LOG.info("Attempting to fast replay the log files.");
58+
logger.info("Attempting to fast replay the log files.");
5959
List<LogFile.SequentialReader> logReaders = Lists.newArrayList();
6060
for (File logFile : logFiles) {
6161
try {
6262
logReaders.add(LogFileFactory.getSequentialReader(logFile, null, fsyncPerTransaction));
6363
} catch (EOFException e) {
64-
LOG.warn("Ignoring " + logFile + " due to EOF", e);
64+
logger.warn("Ignoring " + logFile + " due to EOF", e);
6565
}
6666
}
6767
long transactionIDSeed = 0;
@@ -120,7 +120,7 @@ public boolean rebuild() throws IOException, Exception {
120120
}
121121
}
122122
} catch (Exception e) {
123-
LOG.warn("Error while generating checkpoint using fast generation logic", e);
123+
logger.warn("Error while generating checkpoint using fast generation logic", e);
124124
return false;
125125
} finally {
126126
TransactionIDOracle.setSeed(transactionIDSeed);
@@ -135,7 +135,7 @@ public boolean rebuild() throws IOException, Exception {
135135
queue.addTail(put.pointer);
136136
count++;
137137
}
138-
LOG.info("Replayed {} events using fast replay logic.", count);
138+
logger.info("Replayed {} events using fast replay logic.", count);
139139
return true;
140140
}
141141

@@ -155,7 +155,7 @@ private void writeCheckpoint() throws IOException {
155155
}
156156
}
157157
} catch (Exception e) {
158-
LOG.warn("Error while generating checkpoint using fast generation logic", e);
158+
logger.warn("Error while generating checkpoint using fast generation logic", e);
159159
} finally {
160160
for (LogFile.MetaDataWriter metaDataWriter : metaDataWriters) {
161161
metaDataWriter.close();
@@ -228,7 +228,7 @@ public static void main(String[] args) throws Exception {
228228
int capacity = Integer.parseInt(cli.getOptionValue("t"));
229229
File checkpointFile = new File(checkpointDir, "checkpoint");
230230
if (checkpointFile.exists()) {
231-
LOG.error("Cannot execute fast replay", new IllegalStateException("Checkpoint exists" + checkpointFile));
231+
logger.error("Cannot execute fast replay", new IllegalStateException("Checkpoint exists" + checkpointFile));
232232
} else {
233233
EventQueueBackingStore backingStore = EventQueueBackingStoreFactory.get(
234234
checkpointFile, capacity, "channel", new FileChannelCounter("Main"));
@@ -241,7 +241,7 @@ public static void main(String[] args) throws Exception {
241241
if (rebuilder.rebuild()) {
242242
rebuilder.writeCheckpoint();
243243
} else {
244-
LOG.error("Could not rebuild the checkpoint due to errors.");
244+
logger.error("Could not rebuild the checkpoint due to errors.");
245245
}
246246
}
247247
}

flume-ng-channels/flume-file-channel/src/main/java/org/apache/flume/channel/file/EventQueueBackingStoreFactory.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@
2121
import java.io.IOException;
2222
import java.io.RandomAccessFile;
2323
import org.apache.flume.channel.file.instrumentation.FileChannelCounter;
24-
import org.slf4j.Logger;
25-
import org.slf4j.LoggerFactory;
24+
import org.apache.logging.log4j.LogManager;
25+
import org.apache.logging.log4j.Logger;
2626

2727
class EventQueueBackingStoreFactory {
28-
private static final Logger LOG = LoggerFactory.getLogger(EventQueueBackingStoreFactory.class);
28+
private static final Logger logger = LogManager.getLogger();
2929

3030
private EventQueueBackingStoreFactory() {}
3131

@@ -60,7 +60,7 @@ static EventQueueBackingStore get(
6060
// delete everything in the checkpoint directory and force
6161
// a full replay.
6262
if (!checkpointExists || checkpointFile.length() == 0) {
63-
LOG.warn("MetaData file for checkpoint "
63+
logger.warn("MetaData file for checkpoint "
6464
+ " exists but checkpoint does not. Checkpoint = " + checkpointFile
6565
+ ", metaDataFile = " + metaDataFile);
6666
throw new BadCheckpointException("The last checkpoint was not completed correctly, "
@@ -90,15 +90,15 @@ static EventQueueBackingStore get(
9090
}
9191
return new EventQueueBackingStoreFileV2(checkpointFile, capacity, name, counter);
9292
}
93-
LOG.error("Found version " + Integer.toHexString(version) + " in " + checkpointFile);
93+
logger.error("Found version " + Integer.toHexString(version) + " in " + checkpointFile);
9494
throw new BadCheckpointException(
9595
"Checkpoint file exists with " + Serialization.VERSION_3 + " but no metadata file found.");
9696
} finally {
9797
if (checkpointFileHandle != null) {
9898
try {
9999
checkpointFileHandle.close();
100100
} catch (IOException e) {
101-
LOG.warn("Unable to close " + checkpointFile, e);
101+
logger.warn("Unable to close " + checkpointFile, e);
102102
}
103103
}
104104
}
@@ -113,7 +113,7 @@ private static EventQueueBackingStore upgrade(
113113
boolean compressBackup,
114114
FileChannelCounter counter)
115115
throws Exception {
116-
LOG.info("Attempting upgrade of " + checkpointFile + " for " + name);
116+
logger.info("Attempting upgrade of " + checkpointFile + " for " + name);
117117
EventQueueBackingStoreFileV2 backingStoreV2 =
118118
new EventQueueBackingStoreFileV2(checkpointFile, capacity, name, counter);
119119
String backupName = checkpointFile.getName() + "-backup-" + System.currentTimeMillis();

flume-ng-channels/flume-file-channel/src/main/java/org/apache/flume/channel/file/EventQueueBackingStoreFile.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@
3838
import java.util.concurrent.TimeUnit;
3939
import java.util.concurrent.atomic.AtomicInteger;
4040
import org.apache.flume.channel.file.instrumentation.FileChannelCounter;
41-
import org.slf4j.Logger;
42-
import org.slf4j.LoggerFactory;
41+
import org.apache.logging.log4j.LogManager;
42+
import org.apache.logging.log4j.Logger;
4343

4444
abstract class EventQueueBackingStoreFile extends EventQueueBackingStore {
45-
private static final Logger LOG = LoggerFactory.getLogger(EventQueueBackingStoreFile.class);
45+
private static final Logger logger = LogManager.getLogger();
4646
private static final int MAX_ALLOC_BUFFER_SIZE = 2 * 1024 * 1024; // 2MB
4747
protected static final int HEADER_SIZE = 1029;
4848
protected static final int INDEX_VERSION = 0;
@@ -94,7 +94,7 @@ protected EventQueueBackingStoreFile(
9494
checkpointFileHandle.seek(INDEX_VERSION * Serialization.SIZE_OF_LONG);
9595
checkpointFileHandle.writeLong(getVersion());
9696
checkpointFileHandle.getChannel().force(true);
97-
LOG.info("Preallocated " + checkpointFile + " to " + checkpointFileHandle.length() + " for capacity "
97+
logger.info("Preallocated " + checkpointFile + " to " + checkpointFileHandle.length() + " for capacity "
9898
+ capacity);
9999
}
100100
if (checkpointFile.length() != totalBytes) {
@@ -187,7 +187,7 @@ protected void backupCheckpoint(File backupDirectory) throws IOException {
187187
+ "this directory: "
188188
+ backupDirectory.toString() + " as backup?");
189189
if (!backupFile.createNewFile()) {
190-
LOG.error("Could not create backup file. Backup of checkpoint will "
190+
logger.error("Could not create backup file. Backup of checkpoint will "
191191
+ "not be used during replay even if checkpoint is bad.");
192192
}
193193
}
@@ -225,7 +225,7 @@ public static boolean restoreBackup(File checkpointDir, File backupDir) throws I
225225

226226
@Override
227227
void beginCheckpoint() throws IOException {
228-
LOG.info("Start checkpoint for " + checkpointFile + ", elements to sync = " + overwriteMap.size());
228+
logger.info("Start checkpoint for " + checkpointFile + ", elements to sync = " + overwriteMap.size());
229229

230230
if (shouldBackup) {
231231
int permits = backupCompletedSema.drainPermits();
@@ -250,7 +250,7 @@ void beginCheckpoint() throws IOException {
250250
void checkpoint() throws IOException {
251251

252252
setLogWriteOrderID(WriteOrderOracle.next());
253-
LOG.info("Updating checkpoint metadata: logWriteOrderID: "
253+
logger.info("Updating checkpoint metadata: logWriteOrderID: "
254254
+ getLogWriteOrderID() + ", queueSize: " + getSize() + ", queueHead: "
255255
+ getHead());
256256
elementsBuffer.put(INDEX_WRITE_ORDER_ID, getLogWriteOrderID());
@@ -286,7 +286,7 @@ private void startBackupThread() {
286286
checkpointBackUpExecutor,
287287
"Expected the checkpoint backup exector to be non-null, "
288288
+ "but it is null. Checkpoint will not be backed up.");
289-
LOG.info("Attempting to back up checkpoint.");
289+
logger.info("Attempting to back up checkpoint.");
290290
checkpointBackUpExecutor.submit(new Runnable() {
291291

292292
@Override
@@ -297,12 +297,12 @@ public void run() {
297297
} catch (Throwable throwable) {
298298
fileChannelCounter.incrementCheckpointBackupWriteErrorCount();
299299
error = true;
300-
LOG.error("Backing up of checkpoint directory failed.", throwable);
300+
logger.error("Backing up of checkpoint directory failed.", throwable);
301301
} finally {
302302
backupCompletedSema.release();
303303
}
304304
if (!error) {
305-
LOG.info("Checkpoint backup completed.");
305+
logger.info("Checkpoint backup completed.");
306306
}
307307
}
308308
});
@@ -314,15 +314,15 @@ void close() {
314314
try {
315315
checkpointFileHandle.close();
316316
} catch (IOException e) {
317-
LOG.info("Error closing " + checkpointFile, e);
317+
logger.info("Error closing " + checkpointFile, e);
318318
}
319319
if (checkpointBackUpExecutor != null && !checkpointBackUpExecutor.isShutdown()) {
320320
checkpointBackUpExecutor.shutdown();
321321
try {
322322
// Wait till the executor dies.
323323
while (!checkpointBackUpExecutor.awaitTermination(1, TimeUnit.SECONDS)) {}
324324
} catch (InterruptedException ex) {
325-
LOG.warn("Interrupted while waiting for checkpoint backup to " + "complete");
325+
logger.warn("Interrupted while waiting for checkpoint backup to " + "complete");
326326
}
327327
}
328328
}

0 commit comments

Comments
 (0)