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.appender.rolling;
    18
    19  import java.text.NumberFormat;
    20  import java.text.ParseException;
    21  import java.util.Locale;
    22  import java.util.regex.Matcher;
    23  import java.util.regex.Pattern;
    24
    25  import org.apache.logging.log4j.Logger;
    26  import org.apache.logging.log4j.core.LogEvent;
    27  import org.apache.logging.log4j.core.config.plugins.Plugin;
    28  import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
    29  import org.apache.logging.log4j.core.config.plugins.PluginFactory;
    30  import org.apache.logging.log4j.status.StatusLogger;
    31
    32  /**
    33   *
    34   */
    35  @Plugin(name = "SizeBasedTriggeringPolicy", category = "Core", printObject = true)
    36  public class SizeBasedTriggeringPolicy implements TriggeringPolicy {
    37      /**
    38       * Allow subclasses access to the status logger without creating another instance.
    39       */
    40      protected static final Logger LOGGER = StatusLogger.getLogger();
    41
    42      private static final long KB = 1024;
    43      private static final long MB = KB * KB;
    44      private static final long GB = KB * MB;
    45
    46      /**
    47       * Rollover threshold size in bytes.
    48       */
    49      private static final long MAX_FILE_SIZE = 10 * 1024 * 1024; // let 10 MB the default max size
    50
    51
    52      /**
    53       * Pattern for string parsing.
    54       */
    55      private static final Pattern VALUE_PATTERN =
    56          Pattern.compile("([0-9]+([\\.,][0-9]+)?)\\s*(|K|M|G)B?", Pattern.CASE_INSENSITIVE);
    57
    58      private final long maxFileSize;
    59
    60      private RollingFileManager manager;
    61
    62      /**
    63       * Constructs a new instance.
    64       */
    65      protected SizeBasedTriggeringPolicy() {
    66          this.maxFileSize = MAX_FILE_SIZE;
    67      }
    68
    69      /**
    70       * Constructs a new instance.
    71       *
    72       * @param maxFileSize rollover threshold size in bytes.
    73       */
    74      protected SizeBasedTriggeringPolicy(final long maxFileSize) {
    75          this.maxFileSize = maxFileSize;
    76      }
    77
    78      /**
    79       * Initialize the TriggeringPolicy.
    80       * @param manager The RollingFileManager.
    81       */
    82      @Override
    83      public void initialize(final RollingFileManager manager) {
    84          this.manager = manager;
    85      }
    86
    87
    88      /**
    89       * Returns true if a rollover should occur.
    90       * @param event   A reference to the currently event.
    91       * @return true if a rollover should take place, false otherwise.
    92       */
    93      @Override
    94      public boolean isTriggeringEvent(final LogEvent event) {
    95          final boolean triggered = manager.getFileSize() > maxFileSize;
    96          if (triggered) {
    97              manager.getPatternProcessor().updateTime();
    98          }
    99          return triggered;
    100     }
    101
    102     @Override
    103     public String toString() {
    104         return "SizeBasedTriggeringPolicy(size=" + maxFileSize + ')';
    105     }
    106
    107     /**
    108      * Create a SizeBasedTriggeringPolicy.
    109      * @param size The size of the file before rollover is required.
    110      * @return A SizeBasedTriggeringPolicy.
    111      */
    112     @PluginFactory
    113     public static SizeBasedTriggeringPolicy createPolicy(@PluginAttribute("size") final String size) {
    114
    115         final long maxSize = size == null ? MAX_FILE_SIZE : valueOf(size);
    116         return new SizeBasedTriggeringPolicy(maxSize);
    117     }
    118
    119     /**
    120      * Converts a string to a number of bytes. Strings consist of a floating point value followed by
    121      * K, M, or G for kilobytes, megabytes, gigabytes, respectively. The
    122      * abbreviations KB, MB, and GB are also accepted. Matching is case insensitive.
    123      *
    124      * @param string The string to convert
    125      * @return The Bytes value for the string
    126      */
    127     private static long valueOf(final String string) {
    128         final Matcher matcher = VALUE_PATTERN.matcher(string);
    129
    130         // Valid input?
    131         if (matcher.matches()) {
    132             try {
    133                 // Get double precision value
    134                 final long value = NumberFormat.getNumberInstance(Locale.getDefault()).parse(
    135                     matcher.group(1)).longValue();
    136
    137                 // Get units specified
    138                 final String units = matcher.group(3);
    139
    140                 if (units.isEmpty()) {
    141                     return value;
    142                 } else if (units.equalsIgnoreCase("K")) {
    143                     return value * KB;
    144                 } else if (units.equalsIgnoreCase("M")) {
    145                     return value * MB;
    146                 } else if (units.equalsIgnoreCase("G")) {
    147                     return value * GB;
    148                 } else {
    149                     LOGGER.error("Units not recognized: " + string);
    150                     return MAX_FILE_SIZE;
    151                 }
    152             } catch (final ParseException e) {
    153                 LOGGER.error("Unable to parse numeric part: " + string, e);
    154                 return MAX_FILE_SIZE;
    155             }
    156         }
    157         LOGGER.error("Unable to parse bytes: " + string);
    158         return MAX_FILE_SIZE;
    159     }
    160 }