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.filter;
18  
19  import org.apache.logging.log4j.Level;
20  import org.apache.logging.log4j.Marker;
21  import org.apache.logging.log4j.ThreadContext;
22  import org.apache.logging.log4j.core.LogEvent;
23  import org.apache.logging.log4j.core.Logger;
24  import org.apache.logging.log4j.core.config.plugins.Plugin;
25  import org.apache.logging.log4j.core.config.plugins.PluginAttr;
26  import org.apache.logging.log4j.core.config.plugins.PluginElement;
27  import org.apache.logging.log4j.core.config.plugins.PluginFactory;
28  import org.apache.logging.log4j.core.helpers.KeyValuePair;
29  import org.apache.logging.log4j.message.Message;
30  
31  import java.util.HashMap;
32  import java.util.Locale;
33  import java.util.Map;
34  
35  /**
36   * Compare against a log level that is associated with an MDC value.
37   */
38  @Plugin(name = "DynamicThresholdFilter", type = "Core", elementType = "filter", printObject = true)
39  public final class DynamicThresholdFilter extends AbstractFilter {
40      private Map<String, Level> levelMap = new HashMap<String, Level>();
41      private Level defaultThreshold = Level.ERROR;
42      private String key;
43  
44      private DynamicThresholdFilter(String key, Map<String, Level> pairs, Level defaultLevel,
45                                     Result onMatch, Result onMismatch) {
46          super(onMatch, onMismatch);
47          if (key == null) {
48              throw new NullPointerException("key cannot be null");
49          }
50          this.key = key;
51          this.levelMap = pairs;
52          this.defaultThreshold = defaultLevel;
53      }
54  
55      public String getKey() {
56          return this.key;
57      }
58  
59      @Override
60      public Result filter(Logger logger, Level level, Marker marker, String msg, Object[] params) {
61          return filter(level);
62      }
63  
64      @Override
65      public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) {
66          return filter(level);
67      }
68  
69      @Override
70      public Result filter(Logger logger, Level level, Marker marker, Message msg, Throwable t) {
71          return filter(level);
72      }
73  
74      @Override
75      public Result filter(LogEvent event) {
76          return filter(event.getLevel());
77      }
78  
79      private Result filter(Level level) {
80          Object value = ThreadContext.get(key);
81          if (value != null) {
82              Level ctxLevel = levelMap.get(value);
83              if (ctxLevel == null) {
84                  ctxLevel = defaultThreshold;
85              }
86              return level.isAtLeastAsSpecificAs(ctxLevel) ? onMatch : onMismatch;
87          }
88          return Result.NEUTRAL;
89  
90      }
91  
92      public Map<String, Level> getLevelMap() {
93          return levelMap;
94      }
95  
96      @Override
97      public String toString() {
98          StringBuilder sb = new StringBuilder();
99          sb.append("key=").append(key);
100         sb.append(", default=").append(defaultThreshold);
101         if (levelMap.size() > 0) {
102             sb.append("{");
103             boolean first = true;
104             for (Map.Entry<String, Level> entry : levelMap.entrySet()) {
105                 if (!first) {
106                     sb.append(", ");
107                     first = false;
108                 }
109                 sb.append(entry.getKey()).append("=").append(entry.getValue());
110             }
111             sb.append("}");
112         }
113         return sb.toString();
114     }
115 
116     /**
117      * Create the DynamicThresholdFilter.
118      * @param key The name of the key to compare.
119      * @param pairs An array of value and Level pairs.
120      * @param levelName The default Level.
121      * @param match The action to perform if a match occurs.
122      * @param mismatch The action to perform if no match occurs.
123      * @return The DynamicThresholdFilter.
124      */
125     @PluginFactory
126     public static DynamicThresholdFilter createFilter(@PluginAttr("key") String key,
127                                                       @PluginElement("pairs") KeyValuePair[] pairs,
128                                                       @PluginAttr("defaultThreshold") String levelName,
129                                                       @PluginAttr("onmatch") String match,
130                                                       @PluginAttr("onmismatch") String mismatch) {
131         Result onMatch = Result.toResult(match);
132         Result onMismatch = Result.toResult(mismatch);
133         Map<String, Level> map = new HashMap<String, Level>();
134         for (KeyValuePair pair : pairs) {
135             map.put(pair.getKey(), Level.toLevel(pair.getValue()));
136         }
137         Level level = Level.toLevel(levelName, Level.ERROR);
138         return new DynamicThresholdFilter(key, map, level, onMatch, onMismatch);
139     }
140 }