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.log4j.pattern;
18  
19  import org.apache.logging.log4j.core.LogEvent;
20  import org.apache.logging.log4j.core.config.plugins.Plugin;
21  import org.apache.logging.log4j.core.pattern.ConverterKeys;
22  import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;
23  import org.apache.logging.log4j.core.pattern.PatternConverter;
24  import org.apache.logging.log4j.util.TriConsumer;
25  
26  /**
27   * Able to handle the contents of the LogEvent's MDC and either
28   * output the entire contents of the properties, or to output the value of a specific key
29   * within the property bundle when this pattern converter has the option set.
30   */
31  @Plugin(name = "Log4j1MdcPatternConverter", category = PatternConverter.CATEGORY)
32  @ConverterKeys({ "properties" })
33  public final class Log4j1MdcPatternConverter extends LogEventPatternConverter {
34      /**
35       * Name of property to output.
36       */
37      private final String key;
38  
39      /**
40       * Private constructor.
41       *
42       * @param options options, may be null.
43       */
44      private Log4j1MdcPatternConverter(final String[] options) {
45          super(options != null && options.length > 0 ? "Log4j1MDC{" + options[0] + '}' : "Log4j1MDC", "property");
46          if (options != null && options.length > 0) {
47              key = options[0];
48          } else {
49              key = null;
50          }
51      }
52  
53      /**
54       * Obtains an instance of PropertiesPatternConverter.
55       *
56       * @param options options, may be null or first element contains name of property to format.
57       * @return instance of PropertiesPatternConverter.
58       */
59      public static Log4j1MdcPatternConverter newInstance(final String[] options) {
60          return new Log4j1MdcPatternConverter(options);
61      }
62  
63      /**
64       * {@inheritDoc}
65       */
66      @Override
67      public void format(final LogEvent event, final StringBuilder toAppendTo) {
68          if (key == null) {
69              // if there is no additional options, we output every single Key/Value pair for the MDC
70              toAppendTo.append('{');
71              event.getContextData().forEach(APPEND_EACH, toAppendTo);
72              toAppendTo.append('}');
73          } else {
74              // otherwise they just want a single key output
75              final Object val = event.getContextData().getValue(key);
76              if (val != null) {
77                  toAppendTo.append(val);
78              }
79          }
80      }
81  
82      private static TriConsumer<String, Object, StringBuilder> APPEND_EACH = new TriConsumer<String, Object, StringBuilder>() {
83          @Override
84          public void accept(final String key, final Object value, final StringBuilder toAppendTo) {
85              toAppendTo.append('{').append(key).append(',').append(value).append('}');
86          }
87      };
88  }