1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.pattern;
18
19 import java.util.Locale;
20
21 import org.apache.logging.log4j.core.LogEvent;
22 import org.apache.logging.log4j.core.config.Configuration;
23 import org.apache.logging.log4j.core.config.plugins.Plugin;
24 import org.apache.logging.log4j.core.util.ArrayUtils;
25 import org.apache.logging.log4j.core.util.Constants;
26 import org.apache.logging.log4j.core.util.Loader;
27 import org.apache.logging.log4j.message.Message;
28 import org.apache.logging.log4j.message.MultiformatMessage;
29 import org.apache.logging.log4j.status.StatusLogger;
30 import org.apache.logging.log4j.util.MultiFormatStringBuilderFormattable;
31 import org.apache.logging.log4j.util.PerformanceSensitive;
32 import org.apache.logging.log4j.util.StringBuilderFormattable;
33
34
35
36
37 @Plugin(name = "MessagePatternConverter", category = PatternConverter.CATEGORY)
38 @ConverterKeys({ "m", "msg", "message" })
39 @PerformanceSensitive("allocation")
40 public final class MessagePatternConverter extends LogEventPatternConverter {
41
42 private static final String NOLOOKUPS = "nolookups";
43
44 private final String[] formats;
45 private final Configuration config;
46 private final TextRenderer textRenderer;
47
48
49
50
51
52
53
54 private MessagePatternConverter(final Configuration config, final String[] options) {
55 super("Message", "message");
56 this.formats = options;
57 this.config = config;
58 final int noLookupsIdx = loadNoLookups(options);
59 this.textRenderer = loadMessageRenderer(noLookupsIdx >= 0 ? ArrayUtils.remove(options, noLookupsIdx) : options);
60 }
61
62 private int loadNoLookups(final String[] options) {
63 if (options != null) {
64 for (int i = 0; i < options.length; i++) {
65 final String option = options[i];
66 if (NOLOOKUPS.equalsIgnoreCase(option)) {
67 return i;
68 }
69 }
70 }
71 return -1;
72 }
73
74 private TextRenderer loadMessageRenderer(final String[] options) {
75 if (options != null) {
76 for (final String option : options) {
77 switch (option.toUpperCase(Locale.ROOT)) {
78 case "ANSI":
79 if (Loader.isJansiAvailable()) {
80 return new JAnsiTextRenderer(options, JAnsiTextRenderer.DefaultMessageStyleMap);
81 }
82 StatusLogger.getLogger()
83 .warn("You requested ANSI message rendering but JANSI is not on the classpath.");
84 return null;
85 case "HTML":
86 return new HtmlTextRenderer(options);
87 }
88 }
89 }
90 return null;
91 }
92
93
94
95
96
97
98
99
100
101
102 public static MessagePatternConverter newInstance(final Configuration config, final String[] options) {
103 return new MessagePatternConverter(config, options);
104 }
105
106
107
108
109 @Override
110 public void format(final LogEvent event, final StringBuilder toAppendTo) {
111 final Message msg = event.getMessage();
112 if (msg instanceof StringBuilderFormattable) {
113
114 final boolean doRender = textRenderer != null;
115 final StringBuilder workingBuilder = doRender ? new StringBuilder(80) : toAppendTo;
116
117 if (msg instanceof MultiFormatStringBuilderFormattable) {
118 ((MultiFormatStringBuilderFormattable) msg).formatTo(formats, workingBuilder);
119 } else {
120 ((StringBuilderFormattable) msg).formatTo(workingBuilder);
121 }
122
123 if (doRender) {
124 textRenderer.render(workingBuilder, toAppendTo);
125 }
126 return;
127 }
128 if (msg != null) {
129 String result;
130 if (msg instanceof MultiformatMessage) {
131 result = ((MultiformatMessage) msg).getFormattedMessage(formats);
132 } else {
133 result = msg.getFormattedMessage();
134 }
135 if (result != null) {
136 toAppendTo.append(result);
137 } else {
138 toAppendTo.append("null");
139 }
140 }
141 }
142 }