View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.log4j.core.pattern;
18  
19  import org.apache.logging.log4j.core.LogEvent;
20  import org.apache.logging.log4j.core.config.Configuration;
21  import org.apache.logging.log4j.core.config.plugins.Plugin;
22  import org.apache.logging.log4j.message.Message;
23  import org.apache.logging.log4j.message.MultiformatMessage;
24  import org.apache.logging.log4j.util.StringBuilderFormattable;
25  
26  /**
27   * Returns the event's rendered message in a StringBuilder.
28   */
29  @Plugin(name = "MessagePatternConverter", category = PatternConverter.CATEGORY)
30  @ConverterKeys({ "m", "msg", "message" })
31  public final class MessagePatternConverter extends LogEventPatternConverter {
32  
33      private final String[] formats;
34      private final Configuration config;
35  
36      /**
37       * Private constructor.
38       * @param options options, may be null.
39       */
40      private MessagePatternConverter(final Configuration config, final String[] options) {
41          super("Message", "message");
42          formats = options;
43          this.config = config;
44      }
45  
46      /**
47       * Obtains an instance of pattern converter.
48       *
49       * @param config The Configuration.
50       * @param options options, may be null.
51       * @return instance of pattern converter.
52       */
53      public static MessagePatternConverter newInstance(final Configuration config, final String[] options) {
54          return new MessagePatternConverter(config, options);
55      }
56  
57      /**
58       * {@inheritDoc}
59       */
60      @Override
61      public void format(final LogEvent event, final StringBuilder toAppendTo) {
62          final Message msg = event.getMessage();
63          if (msg instanceof StringBuilderFormattable) {
64              final int offset = toAppendTo.length();
65              ((StringBuilderFormattable) msg).formatTo(toAppendTo);
66  
67              // TODO can we optimize this?
68              if (config != null) {
69                  for (int i = offset; i < toAppendTo.length() - 1; i++) {
70                      if (toAppendTo.charAt(i) == '$' && toAppendTo.charAt(i + 1) == '{') {
71                          final String value = toAppendTo.substring(offset, toAppendTo.length());
72                          toAppendTo.setLength(offset);
73                          toAppendTo.append(config.getStrSubstitutor().replace(event, value));
74                      }
75                  }
76              }
77              return;
78          }
79          if (msg != null) {
80              String result;
81              if (msg instanceof MultiformatMessage) {
82                  result = ((MultiformatMessage) msg).getFormattedMessage(formats);
83              } else {
84                  result = msg.getFormattedMessage();
85              }
86              if (result != null) {
87                  toAppendTo.append(config != null && result.contains("${") ?
88                          config.getStrSubstitutor().replace(event, result) : result);
89              } else {
90                  toAppendTo.append("null");
91              }
92          }
93      }
94  }