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 java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Objects;
24
25 import org.apache.logging.log4j.Level;
26 import org.apache.logging.log4j.Marker;
27 import org.apache.logging.log4j.core.Filter;
28 import org.apache.logging.log4j.core.LogEvent;
29 import org.apache.logging.log4j.core.Logger;
30 import org.apache.logging.log4j.core.config.Node;
31 import org.apache.logging.log4j.core.config.plugins.Plugin;
32 import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
33 import org.apache.logging.log4j.core.config.plugins.PluginElement;
34 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
35 import org.apache.logging.log4j.core.util.KeyValuePair;
36 import org.apache.logging.log4j.message.MapMessage;
37 import org.apache.logging.log4j.message.Message;
38
39
40
41
42 @Plugin(name = "MapFilter", category = Node.CATEGORY, elementType = Filter.ELEMENT_TYPE, printObject = true)
43 public class MapFilter extends AbstractFilter {
44
45 private static final long serialVersionUID = 1L;
46
47 private final Map<String, List<String>> map;
48
49 private final boolean isAnd;
50
51 protected MapFilter(final Map<String, List<String>> map, final boolean oper, final Result onMatch,
52 final Result onMismatch) {
53 super(onMatch, onMismatch);
54 Objects.requireNonNull(map, "map cannot be null");
55 this.isAnd = oper;
56 this.map = map;
57 }
58
59 @Override
60 public Result filter(final Logger logger, final Level level, final Marker marker, final Message msg,
61 final Throwable t) {
62 if (msg instanceof MapMessage) {
63 return filter(((MapMessage) msg).getData()) ? onMatch : onMismatch;
64 }
65 return Result.NEUTRAL;
66 }
67
68 @Override
69 public Result filter(final LogEvent event) {
70 final Message msg = event.getMessage();
71 if (msg instanceof MapMessage) {
72 return filter(((MapMessage) msg).getData()) ? onMatch : onMismatch;
73 }
74 return Result.NEUTRAL;
75 }
76
77 protected boolean filter(final Map<String, String> data) {
78 boolean match = false;
79 for (final Map.Entry<String, List<String>> entry : map.entrySet()) {
80 final String toMatch = data.get(entry.getKey());
81 if (toMatch != null) {
82 match = entry.getValue().contains(toMatch);
83 } else {
84 match = false;
85 }
86 if ((!isAnd && match) || (isAnd && !match)) {
87 break;
88 }
89 }
90 return match;
91 }
92
93 @Override
94 public String toString() {
95 final StringBuilder sb = new StringBuilder();
96 sb.append("isAnd=").append(isAnd);
97 if (map.size() > 0) {
98 sb.append(", {");
99 boolean first = true;
100 for (final Map.Entry<String, List<String>> entry : map.entrySet()) {
101 if (!first) {
102 sb.append(", ");
103 }
104 first = false;
105 final List<String> list = entry.getValue();
106 final String value = list.size() > 1 ? list.get(0) : list.toString();
107 sb.append(entry.getKey()).append('=').append(value);
108 }
109 sb.append('}');
110 }
111 return sb.toString();
112 }
113
114 protected boolean isAnd() {
115 return isAnd;
116 }
117
118 protected Map<String, List<String>> getMap() {
119 return map;
120 }
121
122 @PluginFactory
123 public static MapFilter createFilter(
124 @PluginElement("Pairs") final KeyValuePair[] pairs,
125 @PluginAttribute("operator") final String oper,
126 @PluginAttribute("onMatch") final Result match,
127 @PluginAttribute("onMismatch") final Result mismatch) {
128 if (pairs == null || pairs.length == 0) {
129 LOGGER.error("keys and values must be specified for the MapFilter");
130 return null;
131 }
132 final Map<String, List<String>> map = new HashMap<>();
133 for (final KeyValuePair pair : pairs) {
134 final String key = pair.getKey();
135 if (key == null) {
136 LOGGER.error("A null key is not valid in MapFilter");
137 continue;
138 }
139 final String value = pair.getValue();
140 if (value == null) {
141 LOGGER.error("A null value for key " + key + " is not allowed in MapFilter");
142 continue;
143 }
144 List<String> list = map.get(pair.getKey());
145 if (list != null) {
146 list.add(value);
147 } else {
148 list = new ArrayList<>();
149 list.add(value);
150 map.put(pair.getKey(), list);
151 }
152 }
153 if (map.isEmpty()) {
154 LOGGER.error("MapFilter is not configured with any valid key value pairs");
155 return null;
156 }
157 final boolean isAnd = oper == null || !oper.equalsIgnoreCase("or");
158 return new MapFilter(map, isAnd, match, mismatch);
159 }
160 }