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.pattern;
    18
    19  import java.util.HashMap;
    20  import java.util.Locale;
    21  import java.util.Map;
    22
    23  import org.apache.logging.log4j.Level;
    24  import org.apache.logging.log4j.core.LogEvent;
    25  import org.apache.logging.log4j.core.config.plugins.Plugin;
    26  import org.apache.logging.log4j.core.util.Patterns;
    27
    28  /**
    29   * Returns the event's level in a StringBuilder.
    30   */
    31  @Plugin(name = "LevelPatternConverter", category = PatternConverter.CATEGORY)
    32  @ConverterKeys({ "p", "level" })
    33  public final class LevelPatternConverter extends LogEventPatternConverter {
    34      private static final String OPTION_LENGTH = "length";
    35      private static final String OPTION_LOWER = "lowerCase";
    36
    37      /**
    38       * Singleton.
    39       */
    40      private static final LevelPatternConverter INSTANCE = new LevelPatternConverter(null);
    41
    42      private final Map<Level, String> levelMap;
    43
    44      /**
    45       * Private constructor.
    46       */
    47      private LevelPatternConverter(final Map<Level, String> map) {
    48          super("Level", "level");
    49          this.levelMap = map;
    50      }
    51
    52      /**
    53       * Obtains an instance of pattern converter.
    54       *
    55       * @param options
    56       *            options, may be null. May contain a list of level names and The value that should be displayed for the
    57       *            Level.
    58       * @return instance of pattern converter.
    59       */
    60      public static LevelPatternConverter newInstance(final String[] options) {
    61          if (options == null || options.length == 0) {
    62              return INSTANCE;
    63          }
    64          final Map<Level, String> levelMap = new HashMap<Level, String>();
    65          int length = Integer.MAX_VALUE; // More than the longest level name.
    66          boolean lowerCase = false;
    67          final String[] definitions = options[0].split(Patterns.COMMA_SEPARATOR);
    68          for (final String def : definitions) {
    69              final String[] pair = def.split("=");
    70              if (pair == null || pair.length != 2) {
    71                  LOGGER.error("Invalid option {}", def);
    72                  continue;
    73              }
    74              final String key = pair[0].trim();
    75              final String value = pair[1].trim();
    76              if (OPTION_LENGTH.equalsIgnoreCase(key)) {
    77                  length = Integer.parseInt(value);
    78              } else if (OPTION_LOWER.equalsIgnoreCase(key)) {
    79                  lowerCase = Boolean.parseBoolean(value);
    80              } else {
    81                  final Level level = Level.toLevel(key, null);
    82                  if (level == null) {
    83                      LOGGER.error("Invalid Level {}", key);
    84                  } else {
    85                      levelMap.put(level, value);
    86                  }
    87              }
    88          }
    89          if (levelMap.isEmpty() && length == Integer.MAX_VALUE && !lowerCase) {
    90              return INSTANCE;
    91          }
    92          for (final Level level : Level.values()) {
    93              if (!levelMap.containsKey(level)) {
    94                  final String left = left(level, length);
    95                  levelMap.put(level, lowerCase ? left.toLowerCase(Locale.US) : left);
    96              }
    97          }
    98          return new LevelPatternConverter(levelMap);
    99      }
    100
    101     /**
    102      * Returns the leftmost chars of the level name for the given level.
    103      *
    104      * @param level
    105      *            The level
    106      * @param length
    107      *            How many chars to return
    108      * @return The abbreviated level name, or the whole level name if the {@code length} is greater than the level name
    109      *         length,
    110      */
    111     private static String left(final Level level, final int length) {
    112         final String string = level.toString();
    113         if (length >= string.length()) {
    114             return string;
    115         }
    116         return string.substring(0, length);
    117     }
    118
    119     /**
    120      * {@inheritDoc}
    121      */
    122     @Override
    123     public void format(final LogEvent event, final StringBuilder output) {
    124         output.append(levelMap == null ? event.getLevel().toString() : levelMap.get(event.getLevel()));
    125     }
    126
    127     /**
    128      * {@inheritDoc}
    129      */
    130     @Override
    131     public String getStyleClass(final Object e) {
    132         if (e instanceof LogEvent) {
    133             return "level " + ((LogEvent) e).getLevel().name().toLowerCase(Locale.ENGLISH);
    134         }
    135
    136         return "level";
    137     }
    138 }