- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
1 parent
088360b
commit 97cb23f
Showing
16 changed files
with
251 additions
and
551 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
60 changes: 0 additions & 60 deletions
60
src/main/java/io/github/brenoepics/at4j/util/logging/FallbackLoggerConfiguration.java
This file was deleted.
Oops, something went wrong.
46 changes: 0 additions & 46 deletions
46
src/main/java/io/github/brenoepics/at4j/util/logging/Log4jPropertySource.java
This file was deleted.
Oops, something went wrong.
96 changes: 23 additions & 73 deletions
96
src/main/java/io/github/brenoepics/at4j/util/logging/LoggerUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,81 +1,31 @@ | ||
package io.github.brenoepics.at4j.util.logging; | ||
|
||
import java.util.Map; | ||
import java.util.Properties; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
import java.util.concurrent.atomic.AtomicBoolean; | ||
import java.util.concurrent.atomic.AtomicReference; | ||
import org.apache.logging.log4j.Level; | ||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
import org.apache.logging.log4j.simple.SimpleLogger; | ||
import org.apache.logging.log4j.util.PropertiesUtil; | ||
import org.apache.logging.log4j.util.ProviderUtil; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
/** This class is used to get a {@link Logger} instance. */ | ||
public class LoggerUtil { | ||
LoggerUtil() { | ||
throw new UnsupportedOperationException(); | ||
} | ||
|
||
private static final AtomicReference<Boolean> initialized = new AtomicReference<>(false); | ||
private static final AtomicBoolean noLogger = new AtomicBoolean(); | ||
private static final Map<String, Logger> loggers = new ConcurrentHashMap<>(); | ||
|
||
/** | ||
* Get or create a logger with the given name. | ||
* | ||
* @param name The name of the logger. | ||
* @return The logger with the given name. | ||
*/ | ||
public static Logger getLogger(String name) { | ||
AtomicBoolean logWarning = new AtomicBoolean(false); | ||
initialized.updateAndGet( | ||
initialized -> { | ||
if (Boolean.TRUE.equals(!initialized) && !ProviderUtil.hasProviders()) { | ||
noLogger.set(true); | ||
logWarning.set(true); | ||
} | ||
return true; | ||
}); | ||
LoggerUtil() { | ||
throw new UnsupportedOperationException(); | ||
} | ||
|
||
if (noLogger.get()) { | ||
return loggers.computeIfAbsent( | ||
name, | ||
key -> { | ||
Level debugLevel = | ||
FallbackLoggerConfiguration.isDebugEnabled() ? Level.DEBUG : Level.INFO; | ||
Level level = FallbackLoggerConfiguration.isTraceEnabled() ? Level.TRACE : debugLevel; | ||
Logger logger = | ||
new SimpleLogger( | ||
name, | ||
level, | ||
true, | ||
false, | ||
true, | ||
true, | ||
"yyyy-MM-dd HH:mm:ss.SSSZ", | ||
null, | ||
new PropertiesUtil(new Properties()), | ||
System.out); | ||
if (logWarning.get()) { | ||
logger.info( | ||
"No Log4j2 compatible logger was found. Using default AT4J implementation!"); | ||
} | ||
return new PrivacyProtectionLogger(logger); | ||
}); | ||
} else { | ||
return new PrivacyProtectionLogger(LogManager.getLogger(name)); | ||
/** | ||
* Get or create a logger with the given name. | ||
* | ||
* @param name The name of the logger. | ||
* @return The logger with the given name. | ||
*/ | ||
public static Logger getLogger(String name) { | ||
return LoggerFactory.getLogger(name); | ||
} | ||
} | ||
|
||
/** | ||
* Gets or creates a logger for the given name. | ||
* | ||
* @param clazz The class of the logger. | ||
* @return A logger for the given class. | ||
*/ | ||
public static Logger getLogger(Class<?> clazz) { | ||
return getLogger(clazz.getName()); | ||
} | ||
} | ||
/** | ||
* Gets or creates a logger for the given class. | ||
* | ||
* @param clazz The class of the logger. | ||
* @return A logger for the given class. | ||
*/ | ||
public static Logger getLogger(Class<?> clazz) { | ||
return LoggerFactory.getLogger(clazz); | ||
} | ||
} |
212 changes: 0 additions & 212 deletions
212
src/main/java/io/github/brenoepics/at4j/util/logging/PrivacyProtectionLogger.java
This file was deleted.
Oops, something went wrong.
138 changes: 138 additions & 0 deletions
138
src/main/java/io/github/brenoepics/at4j/util/logging/ProtectedLogger.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
package io.github.brenoepics.at4j.util.logging; | ||
|
||
import java.util.HashSet; | ||
import java.util.Set; | ||
import org.slf4j.Logger; | ||
import org.slf4j.Marker; | ||
import org.slf4j.event.Level; | ||
import org.slf4j.helpers.AbstractLogger; | ||
|
||
/** | ||
* This logger is used to wrap another logger and replace configured sensitive data by asterisks. | ||
*/ | ||
public class ProtectedLogger extends AbstractLogger { | ||
private static final long serialVersionUID = 91095837261631L; | ||
private static final String PRIVATE_DATA_REPLACEMENT = "**********"; | ||
private static final Set<String> privateDataSet = new HashSet<>(); | ||
|
||
private final transient Logger delegate; | ||
|
||
/** | ||
* Class constructor. It's recommended to use {@link LoggerUtil#getLogger(String)}. | ||
* | ||
* @param delegate The delegate logger that gets the cleaned messages. | ||
*/ | ||
ProtectedLogger(Logger delegate) { | ||
this.delegate = delegate; | ||
} | ||
|
||
/** | ||
* Adds private data to be asterisked out in log messages. A {@code null} argument is simply | ||
* ignored. | ||
* | ||
* @param privateData The private data. | ||
*/ | ||
public static void addPrivateData(String privateData) { | ||
if (privateData != null && !privateData.trim().isEmpty()) { | ||
privateDataSet.add(privateData); | ||
} | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return delegate.getName(); | ||
} | ||
|
||
@Override | ||
public boolean isTraceEnabled() { | ||
return delegate.isTraceEnabled(); | ||
} | ||
|
||
@Override | ||
public boolean isTraceEnabled(Marker marker) { | ||
return delegate.isTraceEnabled(marker); | ||
} | ||
|
||
@Override | ||
public boolean isDebugEnabled() { | ||
return delegate.isDebugEnabled(); | ||
} | ||
|
||
@Override | ||
public boolean isDebugEnabled(Marker marker) { | ||
return delegate.isDebugEnabled(marker); | ||
} | ||
|
||
@Override | ||
public boolean isInfoEnabled() { | ||
return delegate.isInfoEnabled(); | ||
} | ||
|
||
@Override | ||
public boolean isInfoEnabled(Marker marker) { | ||
return delegate.isInfoEnabled(marker); | ||
} | ||
|
||
@Override | ||
public boolean isWarnEnabled() { | ||
return delegate.isWarnEnabled(); | ||
} | ||
|
||
@Override | ||
public boolean isWarnEnabled(Marker marker) { | ||
return delegate.isWarnEnabled(marker); | ||
} | ||
|
||
@Override | ||
public boolean isErrorEnabled() { | ||
return delegate.isErrorEnabled(); | ||
} | ||
|
||
@Override | ||
public boolean isErrorEnabled(Marker marker) { | ||
return delegate.isErrorEnabled(marker); | ||
} | ||
|
||
@Override | ||
protected String getFullyQualifiedCallerName() { | ||
return delegate.getName(); | ||
} | ||
|
||
@Override | ||
protected void handleNormalizedLoggingCall( | ||
Level level, Marker marker, String message, Object[] objects, Throwable t) { | ||
if (privateDataSet.stream().noneMatch(message::contains)) { | ||
log(level, marker, objects, t, message); | ||
return; | ||
} | ||
|
||
String replacedMessage = message; | ||
for (String privateData : privateDataSet) { | ||
if (message.contains(privateData)) { | ||
replacedMessage = replacedMessage.replace(privateData, PRIVATE_DATA_REPLACEMENT); | ||
} | ||
} | ||
|
||
log(level, marker, objects, t, replacedMessage); | ||
} | ||
|
||
private void log(Level level, Marker marker, Object[] objects, Throwable t, String message) { | ||
switch (level) { | ||
case TRACE: | ||
delegate.trace(marker, message, objects, t); | ||
break; | ||
case DEBUG: | ||
delegate.debug(marker, message, objects, t); | ||
break; | ||
case INFO: | ||
delegate.info(marker, message, objects, t); | ||
break; | ||
case WARN: | ||
delegate.warn(marker, message, objects, t); | ||
break; | ||
case ERROR: | ||
delegate.error(marker, message, objects, t); | ||
break; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 0 additions & 1 deletion
1
src/main/resources/META-INF/services/org.apache.logging.log4j.util.PropertySource
This file was deleted.
Oops, something went wrong.
53 changes: 0 additions & 53 deletions
53
src/test/java/io/github/brenoepics/at4j/util/logging/FallbackLoggerConfigurationTest.java
This file was deleted.
Oops, something went wrong.
44 changes: 0 additions & 44 deletions
44
src/test/java/io/github/brenoepics/at4j/util/logging/PrivacyProtectionLoggerTest.java
This file was deleted.
Oops, something went wrong.
79 changes: 79 additions & 0 deletions
79
src/test/java/io/github/brenoepics/at4j/util/logging/ProtectedLoggerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package io.github.brenoepics.at4j.util.logging; | ||
|
||
import static org.mockito.Mockito.*; | ||
|
||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
import org.mockito.Mockito; | ||
import org.slf4j.Logger; | ||
import org.slf4j.Marker; | ||
import org.slf4j.event.Level; | ||
|
||
class ProtectedLoggerTest { | ||
private Logger delegate; | ||
private ProtectedLogger protectedLogger; | ||
|
||
@BeforeEach | ||
public void setup() { | ||
delegate = Mockito.mock(Logger.class); | ||
protectedLogger = new ProtectedLogger(delegate); | ||
} | ||
|
||
@Test | ||
void logMessageTest() { | ||
String privateData = "secret"; | ||
ProtectedLogger.addPrivateData(privateData); | ||
String message = "This is a secret message"; | ||
Marker marker = Mockito.mock(Marker.class); | ||
protectedLogger.handleNormalizedLoggingCall(Level.INFO, marker, message, null, null); | ||
verify(delegate).info(eq(marker), eq("This is a ********** message"), isNull(), isNull()); | ||
} | ||
|
||
@Test | ||
void logTraceMessageTest() { | ||
String privateData = "secret"; | ||
ProtectedLogger.addPrivateData(privateData); | ||
String message = "This is a secret trace message"; | ||
Marker marker = Mockito.mock(Marker.class); | ||
protectedLogger.handleNormalizedLoggingCall(Level.TRACE, marker, message, null, null); | ||
verify(delegate).trace(eq(marker), eq("This is a ********** trace message"), isNull(), isNull()); | ||
} | ||
|
||
@Test | ||
void logDebugMessageTest() { | ||
String privateData = "secret"; | ||
ProtectedLogger.addPrivateData(privateData); | ||
String message = "This is a secret debug message"; | ||
Marker marker = Mockito.mock(Marker.class); | ||
protectedLogger.handleNormalizedLoggingCall(Level.DEBUG, marker, message, null, null); | ||
verify(delegate).debug(eq(marker), eq("This is a ********** debug message"), isNull(), isNull()); | ||
} | ||
|
||
@Test | ||
void logWarnMessageTest() { | ||
String privateData = "secret"; | ||
ProtectedLogger.addPrivateData(privateData); | ||
String message = "This is a secret warn message"; | ||
Marker marker = Mockito.mock(Marker.class); | ||
protectedLogger.handleNormalizedLoggingCall(Level.WARN, marker, message, null, null); | ||
verify(delegate).warn(eq(marker), eq("This is a ********** warn message"), isNull(), isNull()); | ||
} | ||
|
||
@Test | ||
void logErrorMessageTest() { | ||
String privateData = "secret"; | ||
ProtectedLogger.addPrivateData(privateData); | ||
String message = "This is a secret error message"; | ||
Marker marker = Mockito.mock(Marker.class); | ||
protectedLogger.handleNormalizedLoggingCall(Level.ERROR, marker, message, null, null); | ||
verify(delegate).error(eq(marker), eq("This is a ********** error message"), isNull(), isNull()); | ||
} | ||
|
||
@Test | ||
void logMessageWithoutPrivateDataTest() { | ||
String message = "This is a regular message"; | ||
Marker marker = Mockito.mock(Marker.class); | ||
protectedLogger.handleNormalizedLoggingCall(Level.INFO, marker, message, null, null); | ||
verify(delegate).info(eq(marker), eq("This is a regular message"), isNull(), isNull()); | ||
} | ||
} |