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