Skip to content

Commit 14cae24

Browse files
Support for java.lang.System.Logger in recipes that handles System.out to logger framework (#272)
* Adding the SYSTEM ability last in the enum list. Added JavaTemplate for System.Logger. * Added test case for use of System.Logger. * Support for the SYSTEM option. - Added option in as valid Logging framwork - Special case for adding java.lang.System.Logger.Level as import, same as with JUL. - Added SYSTEM case and JavaTemplate * Added support for SYSTEM in switch. Implemented new method addSystemLogger. * JavaTemplate for error logging with System.Logger * Added System.Logger.Level and util.logging.Level as markable types to be able to parameterize them correctly. * Support for SYSTEM logging in Err and Out. Matching method patterns for the log(...) in ParameterizedLogging. * Support for SYSTEM for the Print StackTrace case. * Formating changed files using IntelliJ formatter. * Apply best practices * Restore original formatting --------- Co-authored-by: Tim te Beek <[email protected]>
1 parent 924b426 commit 14cae24

File tree

10 files changed

+277
-114
lines changed

10 files changed

+277
-114
lines changed

src/main/java/org/openrewrite/java/logging/AddLogger.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ public static TreeVisitor<J, ExecutionContext> addLogger(J.ClassDeclaration scop
5959
return addLog4j2Logger(scope, loggerName, ctx);
6060
case JUL:
6161
return addJulLogger(scope, loggerName, ctx);
62+
case SYSTEM:
63+
return addSystemLogger(scope, loggerName, ctx);
6264
case SLF4J:
6365
default:
6466
return addSlf4jLogger(scope, loggerName, ctx);
@@ -87,6 +89,16 @@ public static AddLogger addJulLogger(J.ClassDeclaration scope, String loggerName
8789
);
8890
}
8991

92+
public static AddLogger addSystemLogger(J.ClassDeclaration scope, String loggerName, @SuppressWarnings("unused") ExecutionContext ctx) {
93+
return new AddLogger(scope, "java.lang.System.Logger", "java.lang.System", loggerName, visitor ->
94+
JavaTemplate
95+
.builder(getModifiers(scope) + " Logger #{} = System.getLogger(\"#{}\");")
96+
.contextSensitive()
97+
.imports("java.lang.System.Logger")
98+
.build()
99+
);
100+
}
101+
90102
public static AddLogger addLog4j1Logger(J.ClassDeclaration scope, String loggerName, ExecutionContext ctx) {
91103
return new AddLogger(scope, "org.apache.log4j.Logger", "org.apache.log4j.LogManager", loggerName, visitor ->
92104
JavaTemplate

src/main/java/org/openrewrite/java/logging/LoggingFramework.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ public enum LoggingFramework {
2525
Log4J1("org.apache.log4j.Logger"),
2626
Log4J2("org.apache.logging.log4j.Logger"),
2727
JUL("java.util.logging.Logger"),
28-
COMMONS("org.apache.commons.logging.Log");
28+
COMMONS("org.apache.commons.logging.Log"),
29+
SYSTEM("java.lang.System.Logger");
2930

3031
private final String loggerType;
3132

@@ -71,6 +72,11 @@ public JavaTemplate getErrorTemplate(String message, ExecutionContext ctx) {
7172
.builder("#{any(org.apache.commons.logging.Log)}.error(" + message + ", #{any(java.lang.Throwable)})")
7273
.javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "commons-logging-1.3.+"))
7374
.build();
75+
case SYSTEM:
76+
return JavaTemplate
77+
.builder("#{any(java.lang.System.Logger)}.log(Level.ERROR, " + message + ", #{any(java.lang.Throwable)})")
78+
.imports("java.lang.System.Logger.Level")
79+
.build();
7480
case JUL:
7581
default:
7682
return JavaTemplate

src/main/java/org/openrewrite/java/logging/ParameterizedLogging.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ public class ParameterizedLogging extends Recipe {
5353
String displayName = "Parameterize logging statements";
5454

5555
String description = "Transform logging statements using concatenation for messages and variables into a parameterized format. " +
56-
"For example, `logger.info(\"hi \" + userName)` becomes `logger.info(\"hi {}\", userName)`. This can " +
57-
"significantly boost performance for messages that otherwise would be assembled with String concatenation. " +
58-
"Particularly impactful when the log level is not enabled, as no work is done to assemble the message.";
56+
"For example, `logger.info(\"hi \" + userName)` becomes `logger.info(\"hi {}\", userName)`. This can " +
57+
"significantly boost performance for messages that otherwise would be assembled with String concatenation. " +
58+
"Particularly impactful when the log level is not enabled, as no work is done to assemble the message.";
5959

6060
Set<String> tags = new HashSet<>(Arrays.asList("RSPEC-S2629", "RSPEC-S3457"));
6161

@@ -168,7 +168,9 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu
168168
private boolean isMarker(Expression expression) {
169169
JavaType expressionType = expression.getType();
170170
return TypeUtils.isAssignableTo("org.slf4j.Marker", expressionType) ||
171-
TypeUtils.isAssignableTo("org.apache.logging.log4j.Marker", expressionType);
171+
TypeUtils.isAssignableTo("org.apache.logging.log4j.Marker", expressionType) ||
172+
TypeUtils.isAssignableTo("java.lang.System.Logger.Level", expressionType) ||
173+
TypeUtils.isAssignableTo("java.util.logging.Level", expressionType);
172174
}
173175
});
174176
}

src/main/java/org/openrewrite/java/logging/PrintStackTraceToLogError.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public class PrintStackTraceToLogError extends Recipe {
5151

5252
@Option(displayName = "Logging framework",
5353
description = "The logging framework to use.",
54-
valid = {"SLF4J", "Log4J1", "Log4J2", "JUL", "COMMONS"},
54+
valid = {"SLF4J", "Log4J1", "Log4J2", "JUL", "COMMONS", "SYSTEM"},
5555
required = false)
5656
@Nullable
5757
String loggingFramework;
@@ -92,6 +92,10 @@ private J.MethodInvocation replaceMethodInvocation(J.MethodInvocation m, J.Ident
9292
if (framework == LoggingFramework.JUL) {
9393
maybeAddImport("java.util.logging.Level");
9494
}
95+
if (framework == LoggingFramework.SYSTEM) {
96+
maybeAddImport("java.lang.System.Logger.Level");
97+
}
98+
9599
return framework.getErrorTemplate("\"Exception\"", ctx).apply(
96100
new Cursor(getCursor().getParent(), m),
97101
m.getCoordinates().replace(),

src/main/java/org/openrewrite/java/logging/SystemErrToLogging.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public class SystemErrToLogging extends Recipe {
5555

5656
@Option(displayName = "Logging framework",
5757
description = "The logging framework to use.",
58-
valid = {"SLF4J", "Log4J1", "Log4J2", "JUL", "COMMONS"},
58+
valid = {"SLF4J", "Log4J1", "Log4J2", "JUL", "COMMONS", "SYSTEM"},
5959
required = false)
6060
@Nullable
6161
String loggingFramework;
@@ -180,7 +180,18 @@ private J.MethodInvocation replaceMethodInvocation(Cursor printCursor, Execution
180180
maybeAddImport("java.util.logging.Level");
181181
}
182182

183-
return (J.MethodInvocation) new ParameterizedLogging(framework.getLoggerType() + " error(..)", false)
183+
if (framework == LoggingFramework.SYSTEM) {
184+
maybeAddImport("java.lang.System.Logger.Level");
185+
}
186+
187+
String methodPattern;
188+
if (framework == LoggingFramework.SYSTEM) {
189+
methodPattern = framework.getLoggerType() + " log(..)";
190+
} else {
191+
methodPattern = framework.getLoggerType() + " error(..)";
192+
}
193+
194+
return (J.MethodInvocation) new ParameterizedLogging(methodPattern, false)
184195
.getVisitor()
185196
.visitNonNull(print, ctx, printCursor);
186197
}
@@ -203,6 +214,11 @@ public JavaTemplate getErrorTemplateNoException(ExecutionContext ctx) {
203214
.builder("#{any(org.apache.logging.log4j.Logger)}.error(#{any(String)});")
204215
.javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "log4j-api-2.+"))
205216
.build();
217+
case SYSTEM:
218+
return JavaTemplate
219+
.builder("#{any(java.lang.System.Logger)}.log(Level.ERROR, #{any(String)});")
220+
.imports("java.lang.System.Logger.Level")
221+
.build();
206222
case JUL:
207223
default:
208224
return JavaTemplate

src/main/java/org/openrewrite/java/logging/SystemOutToLogging.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public class SystemOutToLogging extends Recipe {
5050

5151
@Option(displayName = "Logging framework",
5252
description = "The logging framework to use.",
53-
valid = {"SLF4J", "Log4J1", "Log4J2", "JUL", "COMMONS"},
53+
valid = {"SLF4J", "Log4J1", "Log4J2", "JUL", "COMMONS", "SYSTEM"},
5454
required = false)
5555
@Nullable
5656
String loggingFramework;
@@ -112,13 +112,24 @@ private J.MethodInvocation replaceMethodInvocation(Cursor printCursor, Execution
112112
computedLoggerName,
113113
print.getArguments().get(0));
114114

115-
print = (J.MethodInvocation) new ParameterizedLogging(framework.getLoggerType() + " " + getLevel() + "(..)", false)
115+
String methodPattern;
116+
if (framework == LoggingFramework.SYSTEM) {
117+
methodPattern = framework.getLoggerType() + " log(..)";
118+
} else {
119+
methodPattern = framework.getLoggerType() + " " + getLevel() + "(..)";
120+
}
121+
print = (J.MethodInvocation) new ParameterizedLogging(methodPattern, false)
116122
.getVisitor()
117123
.visitNonNull(print, ctx, printCursor);
118124

119125
if (framework == LoggingFramework.JUL) {
120126
maybeAddImport("java.util.logging.Level");
121127
}
128+
129+
if (framework == LoggingFramework.SYSTEM) {
130+
maybeAddImport("java.lang.System.Logger.Level");
131+
}
132+
122133
return print;
123134
}
124135

@@ -144,9 +155,13 @@ private JavaTemplate getInfoTemplate(ExecutionContext ctx) {
144155
.javaParser(JavaParser.fromJavaVersion()
145156
.classpathFromResources(ctx, "log4j-api-2.+"))
146157
.build();
158+
case SYSTEM:
159+
return JavaTemplate
160+
.builder("#{any(java.lang.System.Logger)}.log(Level." + levelOrDefault.toUpperCase() + ", #{any(String)})")
161+
.imports("java.lang.System.Logger.Level")
162+
.build();
147163
case JUL:
148164
default:
149-
150165
return JavaTemplate
151166
.builder("#{any(java.util.logging.Logger)}.log(Level." + levelOrDefault + ", #{any(String)})")
152167
.imports("java.util.logging.Level")

src/main/java/org/openrewrite/java/logging/slf4j/CompleteExceptionLogging.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
package org.openrewrite.java.logging.slf4j;
1717

1818
import lombok.Getter;
19-
import org.jspecify.annotations.Nullable;
2019
import org.openrewrite.ExecutionContext;
2120
import org.openrewrite.Preconditions;
2221
import org.openrewrite.Recipe;

0 commit comments

Comments
 (0)