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 java.util.List;
20  import java.util.regex.Pattern;
21  
22  import org.apache.logging.log4j.core.LogEvent;
23  import org.apache.logging.log4j.core.config.Configuration;
24  import org.apache.logging.log4j.core.config.plugins.Plugin;
25  import org.apache.logging.log4j.core.layout.PatternLayout;
26  
27  /**
28   * Replacement pattern converter.
29   */
30  @Plugin(name = "replace", category = PatternConverter.CATEGORY)
31  @ConverterKeys({ "replace" })
32  public final class RegexReplacementConverter extends LogEventPatternConverter {
33  
34      private final Pattern pattern;
35  
36      private final String substitution;
37  
38      private final List<PatternFormatter> formatters;
39  
40      /**
41       * Construct the converter.
42       * @param formatters The PatternFormatters to generate the text to manipulate.
43       * @param pattern The regular expression Pattern.
44       * @param substitution The substitution string.
45       */
46      private RegexReplacementConverter(final List<PatternFormatter> formatters,
47                                        final Pattern pattern, final String substitution) {
48          super("replace", "replace");
49          this.pattern = pattern;
50          this.substitution = substitution;
51          this.formatters = formatters;
52      }
53  
54      /**
55       * Gets an instance of the class.
56       *
57       * @param config The current Configuration.
58       * @param options pattern options, may be null.  If first element is "short",
59       *                only the first line of the throwable will be formatted.
60       * @return instance of class.
61       */
62      public static RegexReplacementConverter newInstance(final Configuration config, final String[] options) {
63          if (options.length != 3) {
64              LOGGER.error("Incorrect number of options on replace. Expected 3 received " + options.length);
65              return null;
66          }
67          if (options[0] == null) {
68              LOGGER.error("No pattern supplied on replace");
69              return null;
70          }
71          if (options[1] == null) {
72              LOGGER.error("No regular expression supplied on replace");
73              return null;
74          }
75          if (options[2] == null) {
76              LOGGER.error("No substitution supplied on replace");
77              return null;
78          }
79          final Pattern p = Pattern.compile(options[1]);
80          final PatternParser parser = PatternLayout.createPatternParser(config);
81          final List<PatternFormatter> formatters = parser.parse(options[0]);
82          return new RegexReplacementConverter(formatters, p, options[2]);
83      }
84  
85  
86      /**
87       * {@inheritDoc}
88       */
89      @Override
90      public void format(final LogEvent event, final StringBuilder toAppendTo) {
91          final StringBuilder buf = new StringBuilder();
92          for (final PatternFormatter formatter : formatters) {
93              formatter.format(event, buf);
94          }
95          toAppendTo.append(pattern.matcher(buf.toString()).replaceAll(substitution));
96      }
97  }