1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.slf4j;
20
21 import java.io.PrintStream;
22 import java.util.function.Consumer;
23
24 import org.apache.maven.api.services.MessageBuilder;
25
26 import static org.apache.maven.jline.MessageUtils.builder;
27
28
29
30
31
32
33
34 public class MavenSimpleLogger extends MavenBaseLogger {
35
36 private String traceRenderedLevel;
37 private String debugRenderedLevel;
38 private String infoRenderedLevel;
39 private String warnRenderedLevel;
40 private String errorRenderedLevel;
41
42 static Consumer<String> logSink;
43
44 public static final String DEFAULT_LOG_LEVEL_KEY = "org.slf4j.simpleLogger.defaultLogLevel";
45
46 public static void setLogSink(Consumer<String> logSink) {
47 MavenSimpleLogger.logSink = logSink;
48 }
49
50 MavenSimpleLogger(String name) {
51 super(name);
52 }
53
54 @Override
55 protected String renderLevel(int level) {
56 if (traceRenderedLevel == null) {
57 traceRenderedLevel = builder().trace("TRACE").build();
58 debugRenderedLevel = builder().debug("DEBUG").build();
59 infoRenderedLevel = builder().info("INFO").build();
60 warnRenderedLevel = builder().warning("WARNING").build();
61 errorRenderedLevel = builder().error("ERROR").build();
62 }
63 return switch (level) {
64 case LOG_LEVEL_TRACE -> traceRenderedLevel;
65 case LOG_LEVEL_DEBUG -> debugRenderedLevel;
66 case LOG_LEVEL_INFO -> infoRenderedLevel;
67 case LOG_LEVEL_WARN -> warnRenderedLevel;
68 default -> errorRenderedLevel;
69 };
70 }
71
72 protected void write(StringBuilder buf, Throwable t) {
73 Consumer<String> sink = logSink;
74 if (sink != null) {
75 sink.accept(buf.toString());
76 if (t != null) {
77 writeThrowable(t, sink);
78 }
79 } else {
80 super.write(buf, t);
81 }
82 }
83
84 @Override
85 protected void writeThrowable(Throwable t, PrintStream stream) {
86 writeThrowable(t, stream::println);
87 }
88
89 protected void writeThrowable(Throwable t, Consumer<String> stream) {
90 if (t == null) {
91 return;
92 }
93 MessageBuilder builder = builder().failure(t.getClass().getName());
94 if (t.getMessage() != null) {
95 builder.a(": ").failure(t.getMessage());
96 }
97 stream.accept(builder.toString());
98
99 printStackTrace(t, stream, "");
100 }
101
102 protected void printStackTrace(Throwable t, Consumer<String> stream, String prefix) {
103 MessageBuilder builder = builder();
104 for (StackTraceElement e : t.getStackTrace()) {
105 builder.a(prefix);
106 builder.a(" ");
107 builder.strong("at");
108 builder.a(" ");
109 builder.a(e.getClassName());
110 builder.a(".");
111 builder.a(e.getMethodName());
112 builder.a("(");
113 builder.strong(getLocation(e));
114 builder.a(")");
115 stream.accept(builder.toString());
116 builder.setLength(0);
117 }
118 for (Throwable se : t.getSuppressed()) {
119 writeThrowable(se, stream, "Suppressed", prefix + " ");
120 }
121 Throwable cause = t.getCause();
122 if (cause != null && t != cause) {
123 writeThrowable(cause, stream, "Caused by", prefix);
124 }
125 }
126
127 protected void writeThrowable(Throwable t, Consumer<String> stream, String caption, String prefix) {
128 MessageBuilder builder =
129 builder().a(prefix).strong(caption).a(": ").a(t.getClass().getName());
130 if (t.getMessage() != null) {
131 builder.a(": ").failure(t.getMessage());
132 }
133 stream.accept(builder.toString());
134
135 printStackTrace(t, stream, prefix);
136 }
137
138 protected String getLocation(final StackTraceElement e) {
139 assert e != null;
140
141 if (e.isNativeMethod()) {
142 return "Native Method";
143 } else if (e.getFileName() == null) {
144 return "Unknown Source";
145 } else if (e.getLineNumber() >= 0) {
146 return e.getFileName() + ":" + e.getLineNumber();
147 } else {
148 return e.getFileName();
149 }
150 }
151
152 public void configure(int defaultLogLevel) {
153 String levelString = recursivelyComputeLevelString();
154 if (levelString != null) {
155 this.currentLogLevel = SimpleLoggerConfiguration.stringToLevel(levelString);
156 } else {
157 this.currentLogLevel = defaultLogLevel;
158 }
159 traceRenderedLevel = builder().trace("TRACE").build();
160 debugRenderedLevel = builder().debug("DEBUG").build();
161 infoRenderedLevel = builder().info("INFO").build();
162 warnRenderedLevel = builder().warning("WARNING").build();
163 errorRenderedLevel = builder().error("ERROR").build();
164 }
165
166 public void setLogLevel(int logLevel) {
167 this.currentLogLevel = logLevel;
168 }
169 }