Skip to content

Commit

Permalink
Issue 710 JUL Respect LogManager Config (#744)
Browse files Browse the repository at this point in the history
* Issue 710 JUL Respect LogManager Config

Updating JUL to check for existing global LogManager configuration prior
to applying ESAPI file settings.

Adding tests to verify LogManager Configurations are preferred to the
ESAPI configurations.

* 710 JavaLogFactory javadoc updates

Capturing recomended configuration options for class use.

* JavaDoc Update JUL

Updating terminology referencing LogManager configuration to match terms
use in LogManager documentation.

* JavaLogFactory LogSpecial on LogManager config

Adding startup System.out.println content (logSpecial) if the custom
esapi-java-logging.properties file is not being applied to the
underlying java LogManager instance.

* JavaLogFactory Javadoc Updates

Attempting to clarify differences between the -D use or
System.setProperty for LogManager configuration recommendations.

* JavaLogFactory Javadoc update

Adding reference to ESAPI Wiki page.
  • Loading branch information
jeremiahjstacey authored Oct 20, 2022
1 parent 967b18d commit 0df09e5
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 5 deletions.
34 changes: 30 additions & 4 deletions src/main/java/org/owasp/esapi/logging/java/JavaLogFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.owasp.esapi.ESAPI;
import org.owasp.esapi.LogFactory;
import org.owasp.esapi.Logger;
import org.owasp.esapi.PropNames;
import org.owasp.esapi.codecs.HTMLEntityCodec;
import org.owasp.esapi.errors.ConfigurationException;
import org.owasp.esapi.logging.appender.LogAppender;
Expand All @@ -43,10 +44,17 @@

/**
* LogFactory implementation which creates JAVA supporting Loggers.
*
* This implementation requires that a file named 'esapi-java-logging.properties' exists on the classpath.
* <br>
* A default file implementation is available in the configuration jar on GitHub under the 'Releases'
* <br><br>
* Options for customizing this configuration (in recommended order)
* <ol>
* <li>Consider using the <i>SLF4JLogFactory</i> with a java-logging implementation.</li>
* <li>Configure the runtime startup command to set the desired system properties for the <i>java.util.logging.LogManager</i> instance. EG: <code>-Djava.util.logging.config.file=/custom/file/path.properties</code></li>
* <li>Overwrite the esapi-java-logging.properties file with the desired logging configurations. <br>A default file implementation is available in the configuration jar on GitHub under the 'Releases'</li>
* <li>Apply custom-code solution to set the system properties for the <i>java.util.logging.LogManager</i> at runtime. EG: <code>System.setProperty("java.util.logging.config.file", "/custom/file/path.properties");</code></li>
* <li>Create a custom JavaLogFactory class in client project baseline and update the ESAPI.properties configuration to use that reference.</li>
* </ol>
*
* @see <a href="https://github.com/ESAPI/esapi-java-legacy/wiki/Configuration-Reference:-JavaLogFactory">ESAPI Wiki - Configuration Reference: JavaLogFactory</a>
*
*/
public class JavaLogFactory implements LogFactory {
Expand Down Expand Up @@ -93,6 +101,24 @@ public class JavaLogFactory implements LogFactory {
* @param logManager LogManager which is being configured.
*/
/*package*/ static void readLoggerConfiguration(LogManager logManager) {
if (System.getProperties().keySet().stream().anyMatch(propKey ->
"java.util.logging.config.class".equals(propKey) || "java.util.logging.config.file".equals(propKey))) {
// LogManager has external configuration. Do not load ESAPI defaults.
// See javadoc for the LogManager class for more information on properties.
boolean isStartupSysoutDisabled = Boolean.valueOf(System.getProperty(PropNames.DISCARD_LOGSPECIAL, Boolean.FALSE.toString()));
if (!isStartupSysoutDisabled) {
String logManagerPreferredMsg = String.format("[ESAPI-STARTUP] ESAPI JavaLogFactory Configuration will not be applied. "
+ "java.util.LogManager configuration Detected. "
+ "{\"java.util.logging.config.class\":\"%s\",\"java.util.logging.config.file\":\"%s\"}",
System.getProperty("java.util.logging.config.class"), System.getProperty("java.util.logging.config.file"));

System.out.println(logManagerPreferredMsg);
// ::SAMPLE OUTPUT::
//[ESAPI-STARTUP] ESAPI JavaLogFactory Configuration will not be applied. java.util.LogManager configuration Detected.{"java.util.logging.config.class":"some.defined.value","java.util.logging.config.file":"null"}
}

return;
}
/*
* This will load the logging properties file to control the format of the output for Java logs.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,59 @@ public class JavaLogFactoryTest {
@Rule
public ExpectedException exEx = ExpectedException.none();

@Test
public void testLogManagerConfigurationAsClass() throws Exception {
String propKey = "java.util.logging.config.class";
//If defined, grab the value; otherwise, set to a known value to allow for prop to be cleared.
String sysDefault = System.getProperties().stringPropertyNames().contains(propKey) ? System.getProperty(propKey) : testName.getMethodName();

System.setProperty(propKey, "some.defined.value");
LogManager testLogManager = new LogManager() {
@Override
public void readConfiguration(InputStream ins) throws IOException, SecurityException {
throw new IOException(testName.getMethodName());
}
};

try {
// This would throw an IOException if the LogManager was not being respected since no esapi-java-logging file is specified
JavaLogFactory.readLoggerConfiguration(testLogManager);
} finally {
//Restore original prop values
if (testName.getMethodName().equals(sysDefault))
System.clearProperty(propKey);
else {
System.setProperty(propKey, sysDefault);
}
}
}

@Test
public void testLogManagerConfigurationAsFile() throws Exception {
String propKey = "java.util.logging.config.file";
//If defined, grab the value; otherwise, set to a known value to allow for prop to be cleared.
String sysDefault = System.getProperties().stringPropertyNames().contains(propKey) ? System.getProperty(propKey) : testName.getMethodName();

System.setProperty(propKey, "some.defined.value");
LogManager testLogManager = new LogManager() {
@Override
public void readConfiguration(InputStream ins) throws IOException, SecurityException {
throw new IOException(testName.getMethodName());
}
};

try {
// This would throw an IOException if the LogManager was not being respected since no esapi-java-logging file is specified
JavaLogFactory.readLoggerConfiguration(testLogManager);
} finally {
//Restore original prop values
if (testName.getMethodName().equals(sysDefault)) {
System.clearProperty(propKey);
} else {
System.setProperty(propKey, sysDefault);
}
}
}
@Test
public void testConfigurationExceptionOnMissingConfiguration() throws Exception {
final IOException originException = new IOException(testName.getMethodName());
Expand All @@ -65,7 +118,7 @@ public void readConfiguration(InputStream ins) throws IOException, SecurityExcep
exEx.expectCause(new CustomMatcher<Throwable>("Check for IOException") {
@Override
public boolean matches(Object item) {
return item instanceof IOException;
return item instanceof IOException;
}
});

Expand Down

0 comments on commit 0df09e5

Please sign in to comment.