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 import org.slf4j.simple.ExtSimpleLogger;
26
27 import static org.apache.maven.jline.MessageUtils.builder;
28
29
30
31
32
33
34
35 public class MavenSimpleLogger extends ExtSimpleLogger {
36
37 private String traceRenderedLevel;
38 private String debugRenderedLevel;
39 private String infoRenderedLevel;
40 private String warnRenderedLevel;
41 private String errorRenderedLevel;
42
43 static Consumer<String> logSink;
44
45 public static void setLogSink(Consumer<String> logSink) {
46 MavenSimpleLogger.logSink = logSink;
47 }
48
49 MavenSimpleLogger(String name) {
50 super(name);
51 }
52
53 @Override
54 protected String renderLevel(int level) {
55 if (traceRenderedLevel == null) {
56 traceRenderedLevel = builder().trace("TRACE").build();
57 debugRenderedLevel = builder().debug("DEBUG").build();
58 infoRenderedLevel = builder().info("INFO").build();
59 warnRenderedLevel = builder().warning("WARNING").build();
60 errorRenderedLevel = builder().error("ERROR").build();
61 }
62 switch (level) {
63 case LOG_LEVEL_TRACE:
64 return traceRenderedLevel;
65 case LOG_LEVEL_DEBUG:
66 return debugRenderedLevel;
67 case LOG_LEVEL_INFO:
68 return infoRenderedLevel;
69 case LOG_LEVEL_WARN:
70 return warnRenderedLevel;
71 case LOG_LEVEL_ERROR:
72 default:
73 return errorRenderedLevel;
74 }
75 }
76
77 @Override
78 protected void doWrite(StringBuilder buf, Throwable t) {
79 Consumer<String> sink = logSink;
80 if (sink != null) {
81 sink.accept(buf.toString());
82 } else {
83 super.doWrite(buf, t);
84 }
85 }
86
87 @Override
88 protected void writeThrowable(Throwable t, PrintStream stream) {
89 if (t == null) {
90 return;
91 }
92 MessageBuilder builder = builder().failure(t.getClass().getName());
93 if (t.getMessage() != null) {
94 builder.a(": ").failure(t.getMessage());
95 }
96 stream.println(builder);
97
98 printStackTrace(t, stream, "");
99 }
100
101 private void printStackTrace(Throwable t, PrintStream stream, String prefix) {
102 MessageBuilder builder = builder();
103 for (StackTraceElement e : t.getStackTrace()) {
104 builder.a(prefix);
105 builder.a(" ");
106 builder.strong("at");
107 builder.a(" ");
108 builder.a(e.getClassName());
109 builder.a(".");
110 builder.a(e.getMethodName());
111 builder.a("(");
112 builder.strong(getLocation(e));
113 builder.a(")");
114 stream.println(builder);
115 builder.setLength(0);
116 }
117 for (Throwable se : t.getSuppressed()) {
118 writeThrowable(se, stream, "Suppressed", prefix + " ");
119 }
120 Throwable cause = t.getCause();
121 if (cause != null && t != cause) {
122 writeThrowable(cause, stream, "Caused by", prefix);
123 }
124 }
125
126 private void writeThrowable(Throwable t, PrintStream stream, String caption, String prefix) {
127 MessageBuilder builder =
128 builder().a(prefix).strong(caption).a(": ").a(t.getClass().getName());
129 if (t.getMessage() != null) {
130 builder.a(": ").failure(t.getMessage());
131 }
132 stream.println(builder);
133
134 printStackTrace(t, stream, prefix);
135 }
136
137 protected String getLocation(final StackTraceElement e) {
138 assert e != null;
139
140 if (e.isNativeMethod()) {
141 return "Native Method";
142 } else if (e.getFileName() == null) {
143 return "Unknown Source";
144 } else if (e.getLineNumber() >= 0) {
145 return e.getFileName() + ":" + e.getLineNumber();
146 } else {
147 return e.getFileName();
148 }
149 }
150 }