Skip to content

Commit 0df09e5

Browse files
Issue 710 JUL Respect LogManager Config (#744)
* 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.
1 parent 967b18d commit 0df09e5

File tree

2 files changed

+84
-5
lines changed

2 files changed

+84
-5
lines changed

src/main/java/org/owasp/esapi/logging/java/JavaLogFactory.java

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.owasp.esapi.ESAPI;
2626
import org.owasp.esapi.LogFactory;
2727
import org.owasp.esapi.Logger;
28+
import org.owasp.esapi.PropNames;
2829
import org.owasp.esapi.codecs.HTMLEntityCodec;
2930
import org.owasp.esapi.errors.ConfigurationException;
3031
import org.owasp.esapi.logging.appender.LogAppender;
@@ -43,10 +44,17 @@
4344

4445
/**
4546
* LogFactory implementation which creates JAVA supporting Loggers.
46-
*
47-
* This implementation requires that a file named 'esapi-java-logging.properties' exists on the classpath.
48-
* <br>
49-
* A default file implementation is available in the configuration jar on GitHub under the 'Releases'
47+
* <br><br>
48+
* Options for customizing this configuration (in recommended order)
49+
* <ol>
50+
* <li>Consider using the <i>SLF4JLogFactory</i> with a java-logging implementation.</li>
51+
* <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>
52+
* <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>
53+
* <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>
54+
* <li>Create a custom JavaLogFactory class in client project baseline and update the ESAPI.properties configuration to use that reference.</li>
55+
* </ol>
56+
*
57+
* @see <a href="https://github.com/ESAPI/esapi-java-legacy/wiki/Configuration-Reference:-JavaLogFactory">ESAPI Wiki - Configuration Reference: JavaLogFactory</a>
5058
*
5159
*/
5260
public class JavaLogFactory implements LogFactory {
@@ -93,6 +101,24 @@ public class JavaLogFactory implements LogFactory {
93101
* @param logManager LogManager which is being configured.
94102
*/
95103
/*package*/ static void readLoggerConfiguration(LogManager logManager) {
104+
if (System.getProperties().keySet().stream().anyMatch(propKey ->
105+
"java.util.logging.config.class".equals(propKey) || "java.util.logging.config.file".equals(propKey))) {
106+
// LogManager has external configuration. Do not load ESAPI defaults.
107+
// See javadoc for the LogManager class for more information on properties.
108+
boolean isStartupSysoutDisabled = Boolean.valueOf(System.getProperty(PropNames.DISCARD_LOGSPECIAL, Boolean.FALSE.toString()));
109+
if (!isStartupSysoutDisabled) {
110+
String logManagerPreferredMsg = String.format("[ESAPI-STARTUP] ESAPI JavaLogFactory Configuration will not be applied. "
111+
+ "java.util.LogManager configuration Detected. "
112+
+ "{\"java.util.logging.config.class\":\"%s\",\"java.util.logging.config.file\":\"%s\"}",
113+
System.getProperty("java.util.logging.config.class"), System.getProperty("java.util.logging.config.file"));
114+
115+
System.out.println(logManagerPreferredMsg);
116+
// ::SAMPLE OUTPUT::
117+
//[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"}
118+
}
119+
120+
return;
121+
}
96122
/*
97123
* This will load the logging properties file to control the format of the output for Java logs.
98124
*/

src/test/java/org/owasp/esapi/logging/java/JavaLogFactoryTest.java

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,59 @@ public class JavaLogFactoryTest {
4848
@Rule
4949
public ExpectedException exEx = ExpectedException.none();
5050

51+
@Test
52+
public void testLogManagerConfigurationAsClass() throws Exception {
53+
String propKey = "java.util.logging.config.class";
54+
//If defined, grab the value; otherwise, set to a known value to allow for prop to be cleared.
55+
String sysDefault = System.getProperties().stringPropertyNames().contains(propKey) ? System.getProperty(propKey) : testName.getMethodName();
56+
57+
System.setProperty(propKey, "some.defined.value");
58+
LogManager testLogManager = new LogManager() {
59+
@Override
60+
public void readConfiguration(InputStream ins) throws IOException, SecurityException {
61+
throw new IOException(testName.getMethodName());
62+
}
63+
};
64+
65+
try {
66+
// This would throw an IOException if the LogManager was not being respected since no esapi-java-logging file is specified
67+
JavaLogFactory.readLoggerConfiguration(testLogManager);
68+
} finally {
69+
//Restore original prop values
70+
if (testName.getMethodName().equals(sysDefault))
71+
System.clearProperty(propKey);
72+
else {
73+
System.setProperty(propKey, sysDefault);
74+
}
75+
}
76+
}
77+
78+
@Test
79+
public void testLogManagerConfigurationAsFile() throws Exception {
80+
String propKey = "java.util.logging.config.file";
81+
//If defined, grab the value; otherwise, set to a known value to allow for prop to be cleared.
82+
String sysDefault = System.getProperties().stringPropertyNames().contains(propKey) ? System.getProperty(propKey) : testName.getMethodName();
83+
84+
System.setProperty(propKey, "some.defined.value");
85+
LogManager testLogManager = new LogManager() {
86+
@Override
87+
public void readConfiguration(InputStream ins) throws IOException, SecurityException {
88+
throw new IOException(testName.getMethodName());
89+
}
90+
};
91+
92+
try {
93+
// This would throw an IOException if the LogManager was not being respected since no esapi-java-logging file is specified
94+
JavaLogFactory.readLoggerConfiguration(testLogManager);
95+
} finally {
96+
//Restore original prop values
97+
if (testName.getMethodName().equals(sysDefault)) {
98+
System.clearProperty(propKey);
99+
} else {
100+
System.setProperty(propKey, sysDefault);
101+
}
102+
}
103+
}
51104
@Test
52105
public void testConfigurationExceptionOnMissingConfiguration() throws Exception {
53106
final IOException originException = new IOException(testName.getMethodName());
@@ -65,7 +118,7 @@ public void readConfiguration(InputStream ins) throws IOException, SecurityExcep
65118
exEx.expectCause(new CustomMatcher<Throwable>("Check for IOException") {
66119
@Override
67120
public boolean matches(Object item) {
68-
return item instanceof IOException;
121+
return item instanceof IOException;
69122
}
70123
});
71124

0 commit comments

Comments
 (0)