This is an automated email from the ASF dual-hosted git repository.
mridulpathak pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git
The following commit(s) were added to refs/heads/trunk by this push:
new 01bcc0b559 java.util.logging output bypasses Log4j 2
01bcc0b559 is described below
commit 01bcc0b559263cf41083df0eaa40d93c47c5af13
Author: Mridul Pathak <[email protected]>
AuthorDate: Sat Oct 24 14:53:00 2026 +0530
java.util.logging output bypasses Log4j 2
- Route java.util.logging to Log4j 2: log4j-jul was on the runtime
classpath but nothing activated it, so libraries logging through
java.util.logging (Tomcat, Jersey, Geronimo and others) wrote to stdout in the
JDK format, never reached ofbiz.log and ignored the levels set in log4j2.xml.
Start now installs Log4j's Log4jBridgeHandler for the start command, before the
startup configuration is read; it works even when java.util.logging was started
before main() (for example by a JMX agen [...]
- In verbose mode, the REST request logging writes only the headers,
redacting Authorization, Proxy-Authorization, Cookie, Set-Cookie and
Refresh-Token: now that java.util.logging reaches the log files, the bodies and
these headers, which can hold credentials and tokens, would otherwise have been
written there.
Thanks: Jacopo Cappellato for the review and feedback
---
.../apache/ofbiz/ws/rs/core/OFBizApiConfig.java | 9 ++++--
.../java/org/apache/ofbiz/base/start/Start.java | 35 ++++++++++++++++++++++
2 files changed, 42 insertions(+), 2 deletions(-)
diff --git
a/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/core/OFBizApiConfig.java
b/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/core/OFBizApiConfig.java
index 4a07488133..a58796253f 100644
---
a/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/core/OFBizApiConfig.java
+++
b/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/core/OFBizApiConfig.java
@@ -74,8 +74,13 @@ public class OFBizApiConfig extends ResourceConfig {
register(ServiceContextCleanupFilter.class);
//property(ServerProperties.TRACING, "ALL");
if (Debug.verboseOn()) {
- register(new
LoggingFeature(Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME), Level.INFO,
- LoggingFeature.Verbosity.PAYLOAD_ANY, 10000));
+ // headers only, the ones carrying credentials or tokens being
redacted: bodies can hold credentials and tokens
+ register(LoggingFeature.builder()
+
.withLogger(Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME))
+ .level(Level.INFO)
+ .verbosity(LoggingFeature.Verbosity.HEADERS_ONLY)
+ .redactHeaders(List.of("Authorization",
"Proxy-Authorization", "Cookie", "Set-Cookie", "Refresh-Token"))
+ .build());
}
registerDSLResources();
EncodingFilter.enableFor(this, GZipEncoder.class);
diff --git
a/framework/start/src/main/java/org/apache/ofbiz/base/start/Start.java
b/framework/start/src/main/java/org/apache/ofbiz/base/start/Start.java
index 33ed1dfb26..a8c2ef4ecd 100644
--- a/framework/start/src/main/java/org/apache/ofbiz/base/start/Start.java
+++ b/framework/start/src/main/java/org/apache/ofbiz/base/start/Start.java
@@ -22,6 +22,9 @@ import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Handler;
+import java.util.logging.Logger;
import java.util.stream.Collectors;
import org.apache.ofbiz.base.container.ContainerLoader;
@@ -71,6 +74,10 @@ public final class Start {
}
CommandType commandType = CommandType.valueOf(ofbizCommands);
+ if (commandType.equals(CommandType.START)) {
+ // not for the status and shutdown clients: they would open, and
roll over, the log files of the running server
+ routeJavaUtilLoggingToLog4j();
+ }
if (!commandType.equals(CommandType.HELP)) {
INSTANCE.config = StartupControlPanel.init(ofbizCommands);
}
@@ -96,6 +103,34 @@ public final class Start {
}
}
+ /**
+ * Routes java.util.logging (used by Tomcat, Jersey, Geronimo and other
libraries) to Log4j 2,
+ * so that it reaches the OFBiz log files and follows the levels of
log4j2.xml.
+ * The bridge handler also works when java.util.logging was started before
main() (e.g. by a JMX agent),
+ * and it only forwards the records java.util.logging itself lets through
(INFO and above by default).
+ * Only the default console handler of the JDK is removed, and only when
java.util.logging has not been
+ * configured on purpose, so that handlers set up by an operator or an
agent are kept.
+ */
+ private static void routeJavaUtilLoggingToLog4j() {
+ try {
+ Class.forName("org.apache.logging.log4j.jul.Log4jBridgeHandler")
+ .getMethod("install", boolean.class, String.class,
boolean.class)
+ .invoke(null, false, null, false);
+ } catch (ReflectiveOperationException | LinkageError e) {
+ System.err.println("java.util.logging is not routed to Log4j 2
(log4j-jul missing?): " + e);
+ return;
+ }
+ if (System.getProperty("java.util.logging.config.file") == null
+ && System.getProperty("java.util.logging.config.class") ==
null) {
+ Logger rootLogger = Logger.getLogger("");
+ for (Handler handler : rootLogger.getHandlers()) {
+ if (handler.getClass() == ConsoleHandler.class) {
+ rootLogger.removeHandler(handler);
+ }
+ }
+ }
+ }
+
/**
* Returns the <code>Start</code> instance.
*/