You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ck...@apache.org on 2022/01/14 23:49:10 UTC
[logging-log4j2] branch master updated: LOG4J2-3282 Support source class & method in to-jul (#698)
This is an automated email from the ASF dual-hosted git repository.
ckozak pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
The following commit(s) were added to refs/heads/master by this push:
new 35ecbc3 LOG4J2-3282 Support source class & method in to-jul (#698)
35ecbc3 is described below
commit 35ecbc36192f02477e4c7f2324c9656f36cba775
Author: Michael Vorburger ⛑️ <vo...@apache.org>
AuthorDate: Sat Jan 15 00:39:54 2022 +0100
LOG4J2-3282 Support source class & method in to-jul (#698)
---
.../org/apache/logging/log4j/tojul/JULLogger.java | 7 +--
.../logging/log4j/tojul/LazyLog4jLogRecord.java | 70 ++++++++++++++++++++++
.../org/apache/logging/log4j/tojul/LoggerTest.java | 27 ++++++++-
3 files changed, 96 insertions(+), 8 deletions(-)
diff --git a/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/JULLogger.java b/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/JULLogger.java
index 52c5299..5f27ae3 100644
--- a/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/JULLogger.java
+++ b/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/JULLogger.java
@@ -18,7 +18,6 @@ package org.apache.logging.log4j.tojul;
import static java.util.Objects.requireNonNull;
-import java.util.logging.LogRecord;
import java.util.logging.Logger;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
@@ -60,15 +59,11 @@ final class JULLogger extends AbstractLogger {
if (!logger.isLoggable(julLevel)) {
return;
}
- LogRecord record = new LogRecord(julLevel, message.getFormattedMessage()); // NOT getFormat()
+ LazyLog4jLogRecord record = new LazyLog4jLogRecord(fqcn, julLevel, message.getFormattedMessage()); // NOT getFormat()
// NOT record.setParameters(message.getParameters()); BECAUSE getFormattedMessage() NOT getFormat()
record.setLoggerName(getName());
record.setThrown(t == null ? message.getThrowable() : t);
- // Source class/method is not supported (yet)
- record.setSourceClassName(null);
- record.setSourceMethodName(null);
logger.log(record);
- // fqcn is un-used
}
// Convert Level in Log4j scale to JUL scale.
diff --git a/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/LazyLog4jLogRecord.java b/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/LazyLog4jLogRecord.java
new file mode 100644
index 0000000..f7bce8f
--- /dev/null
+++ b/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/LazyLog4jLogRecord.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.tojul;
+
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import org.apache.logging.log4j.util.StackLocatorUtil;
+
+/**
+ * Extension of {@link java.util.logging.LogRecord} with lazy get source related methods based on Log4j's {@link StackLocatorUtil#calcLocation(String)}.
+ */
+final class LazyLog4jLogRecord extends LogRecord {
+
+ private static final long serialVersionUID = 6798134264543826471L;
+
+ // parent class LogRecord already has a needToInferCaller but it's private
+ private transient boolean inferCaller = true;
+
+ private final String fqcn;
+
+ LazyLog4jLogRecord(String fqcn, Level level, String msg) {
+ super(level, msg);
+ this.fqcn = fqcn;
+ }
+
+ @Override
+ public String getSourceClassName() {
+ if (inferCaller) {
+ inferCaller();
+ }
+ return super.getSourceClassName();
+ }
+
+ @Override
+ public String getSourceMethodName() {
+ if (inferCaller) {
+ inferCaller();
+ }
+ return super.getSourceMethodName();
+ }
+
+ private void inferCaller() {
+ StackTraceElement location = null;
+ if (fqcn != null) {
+ location = StackLocatorUtil.calcLocation(fqcn);
+ }
+ if (location != null) {
+ setSourceClassName(location.getClassName());
+ setSourceMethodName(location.getMethodName());
+ } else {
+ setSourceClassName(null);
+ setSourceMethodName(null);
+ }
+ inferCaller = false;
+ }
+}
\ No newline at end of file
diff --git a/log4j-to-jul/src/test/java/org/apache/logging/log4j/tojul/LoggerTest.java b/log4j-to-jul/src/test/java/org/apache/logging/log4j/tojul/LoggerTest.java
index c418376..aabc338 100644
--- a/log4j-to-jul/src/test/java/org/apache/logging/log4j/tojul/LoggerTest.java
+++ b/log4j-to-jul/src/test/java/org/apache/logging/log4j/tojul/LoggerTest.java
@@ -81,8 +81,8 @@ public class LoggerTest {
assertThat(log1.getMessage()).isEqualTo("hello, world");
assertThat(log1.getParameters()).isNull();
assertThat(log1.getThrown()).isNull();
- assertThat(log1.getSourceClassName()).isNull();
- assertThat(log1.getSourceMethodName()).isNull();
+ assertThat(log1.getSourceClassName()).isEqualTo(getClass().getName());
+ assertThat(log1.getSourceMethodName()).isEqualTo("infoAtInfo");
}
@Test public void infoAtInfoWithParameters() {
@@ -201,4 +201,27 @@ public class LoggerTest {
super(name, value);
}
}
+
+ /**
+ * Test that the {@link LogRecord#getSourceClassName()}, which we already tested above in infoAtInfo()
+ * also works as expected if the logging happened in a class that we have called (indirect), not in the test method itself.
+ */
+ @Test public void indirectSource() {
+ java.util.logging.Logger.getLogger(Another.class.getName()).setLevel(Level.INFO);
+ new Another(handler);
+ List<LogRecord> logs = handler.getStoredLogRecords();
+ assertThat(logs).hasSize(1);
+ LogRecord log1 = logs.get(0);
+ assertThat(log1.getSourceClassName()).isEqualTo(Another.class.getName());
+ assertThat(log1.getSourceMethodName()).isEqualTo("<init>");
+ }
+
+ static class Another {
+ org.apache.logging.log4j.Logger anotherLog4jLogger = LogManager.getLogger(getClass());
+ java.util.logging.Logger anotherJULLogger = java.util.logging.Logger.getLogger(getClass().getName());
+ Another(TestLogHandler handler) {
+ anotherJULLogger.addHandler(handler);
+ anotherLog4jLogger.info("hello, another world");
+ }
+ }
}