1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.filter;
18
19 import org.apache.logging.log4j.Level;
20 import org.apache.logging.log4j.ThreadContext;
21 import org.apache.logging.log4j.Marker;
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.ArrayList;
32 import java.util.HashMap;
33 import java.util.Iterator;
34 import java.util.List;
35 import java.util.Locale;
36 import java.util.Map;
37
38
39
40
41 @Plugin(name = "ThreadContextMapFilter", type = "Core", elementType = "filter", printObject = true)
42 public class ThreadContextMapFilter extends MapFilter {
43
44 private final String key;
45 private final String value;
46
47 private final boolean useMap;
48
49 public ThreadContextMapFilter(Map<String, List<String>> pairs, boolean oper, Result onMatch, Result onMismatch) {
50 super(pairs, oper, onMatch, onMismatch);
51 if (pairs.size() == 1) {
52 Iterator<Map.Entry<String, List<String>>> iter = pairs.entrySet().iterator();
53 Map.Entry<String, List<String>> entry = iter.next();
54 if (entry.getValue().size() == 1) {
55 this.key = entry.getKey();
56 this.value = entry.getValue().get(0);
57 this.useMap = false;
58 } else {
59 this.key = null;
60 this.value = null;
61 this.useMap = true;
62 }
63 } else {
64 this.key = null;
65 this.value = null;
66 this.useMap = true;
67 }
68 }
69
70 @Override
71 public Result filter(Logger logger, Level level, Marker marker, String msg, Object[] params) {
72 return filter();
73 }
74
75 @Override
76 public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) {
77 return filter();
78 }
79
80 @Override
81 public Result filter(Logger logger, Level level, Marker marker, Message msg, Throwable t) {
82 return filter();
83 }
84
85 private Result filter() {
86 boolean match = false;
87 if (useMap) {
88 for (Map.Entry<String, List<String>> entry : getMap().entrySet()) {
89 String toMatch = ThreadContext.get(entry.getKey());
90 if (toMatch != null) {
91 match = entry.getValue().contains(toMatch);
92 } else {
93 match = false;
94 }
95 if ((!isAnd() && match) || (isAnd() && !match)) {
96 break;
97 }
98 }
99 } else {
100 match = key.equals(ThreadContext.get(key));
101 }
102 return match ? onMatch : onMismatch;
103 }
104
105 @Override
106 public Result filter(LogEvent event) {
107 return super.filter(event.getContextMap()) ? onMatch : onMismatch;
108 }
109
110 @PluginFactory
111 public static ThreadContextMapFilter createFilter(@PluginElement("pairs") KeyValuePair[] pairs,
112 @PluginAttr("operator") String oper,
113 @PluginAttr("onmatch") String match,
114 @PluginAttr("onmismatch") String mismatch) {
115 if (pairs == null || pairs.length == 0) {
116 LOGGER.error("key and value pairs must be specified for the ThreadContextMapFilter");
117 return null;
118 }
119 Map<String, List<String>> map = new HashMap<String, List<String>>();
120 for (KeyValuePair pair : pairs) {
121 String key = pair.getKey();
122 if (key == null) {
123 LOGGER.error("A null key is not valid in MapFilter");
124 continue;
125 }
126 String value = pair.getValue();
127 if (value == null) {
128 LOGGER.error("A null value for key " + key + " is not allowed in MapFilter");
129 continue;
130 }
131 List<String> list = map.get(pair.getKey());
132 if (list != null) {
133 list.add(value);
134 } else {
135 list = new ArrayList<String>();
136 list.add(value);
137 map.put(pair.getKey(), list);
138 }
139 }
140 if (map.size() == 0) {
141 LOGGER.error("ThreadContextMapFilter is not configured with any valid key value pairs");
142 return null;
143 }
144 boolean isAnd = oper == null || !oper.equalsIgnoreCase("or");
145 Result onMatch = Result.toResult(match);
146 Result onMismatch = Result.toResult(mismatch);
147 return new ThreadContextMapFilter(map, isAnd, onMatch, onMismatch);
148 }
149 }