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