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.text.ParseException;
    20  import java.text.SimpleDateFormat;
    21  import java.util.Calendar;
    22  import java.util.TimeZone;
    23
    24  import org.apache.logging.log4j.core.Filter;
    25  import org.apache.logging.log4j.core.LogEvent;
    26  import org.apache.logging.log4j.core.config.Node;
    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
    31  /**
    32   * Filters events that fall within a specified time period in each day.
    33   */
    34  @Plugin(name = "TimeFilter", category = Node.CATEGORY, elementType = Filter.ELEMENT_TYPE, printObject = true)
    35  public final class TimeFilter extends AbstractFilter {
    36
    37      private static final long serialVersionUID = 1L;
    38
    39      /**
    40       * Length of hour in milliseconds.
    41       */
    42      private static final long HOUR_MS = 3600000;
    43
    44      /**
    45       * Length of minute in milliseconds.
    46       */
    47      private static final long MINUTE_MS = 60000;
    48
    49      /**
    50       * Length of second in milliseconds.
    51       */
    52      private static final long SECOND_MS = 1000;
    53
    54      /**
    55       * Starting offset from midnight in milliseconds.
    56       */
    57      private final long start;
    58      /**
    59       * Ending offset from midnight in milliseconds.
    60       */
    61      private final long end;
    62      /**
    63       * Timezone.
    64       */
    65      private final TimeZone timezone;
    66
    67
    68      private TimeFilter(final long start, final long end, final TimeZone tz, final Result onMatch,
    69                         final Result onMismatch) {
    70          super(onMatch, onMismatch);
    71          this.start = start;
    72          this.end = end;
    73          timezone = tz;
    74      }
    75
    76      @Override
    77      public Result filter(final LogEvent event) {
    78          final Calendar calendar = Calendar.getInstance(timezone);
    79          calendar.setTimeInMillis(event.getTimeMillis());
    80          //
    81          //   get apparent number of milliseconds since midnight
    82          //      (ignores extra or missing hour on daylight time changes).
    83          //
    84          final long apparentOffset = calendar.get(Calendar.HOUR_OF_DAY) * HOUR_MS +
    85              calendar.get(Calendar.MINUTE) * MINUTE_MS +
    86              calendar.get(Calendar.SECOND) * SECOND_MS +
    87              calendar.get(Calendar.MILLISECOND);
    88          return apparentOffset >= start && apparentOffset < end ? onMatch : onMismatch;
    89      }
    90
    91      @Override
    92      public String toString() {
    93          final StringBuilder sb = new StringBuilder();
    94          sb.append("start=").append(start);
    95          sb.append(", end=").append(end);
    96          sb.append(", timezone=").append(timezone.toString());
    97          return sb.toString();
    98      }
    99
    100     /**
    101      * Create a TimeFilter.
    102      * @param start The start time.
    103      * @param end The end time.
    104      * @param tz timezone.
    105      * @param match Action to perform if the time matches.
    106      * @param mismatch Action to perform if the action does not match.
    107      * @return A TimeFilter.
    108      */
    109     @PluginFactory
    110     public static TimeFilter createFilter(
    111             @PluginAttribute("start") final String start,
    112             @PluginAttribute("end") final String end,
    113             @PluginAttribute("timezone") final String tz,
    114             @PluginAttribute("onMatch") final Result match,
    115             @PluginAttribute("onMismatch") final Result mismatch) {
    116         final SimpleDateFormat stf = new SimpleDateFormat("HH:mm:ss");
    117         long s = 0;
    118         if (start != null) {
    119             stf.setTimeZone(TimeZone.getTimeZone("UTC"));
    120             try {
    121                 s = stf.parse(start).getTime();
    122             } catch (final ParseException ex) {
    123                 LOGGER.warn("Error parsing start value " + start, ex);
    124             }
    125         }
    126         long e = Long.MAX_VALUE;
    127         if (end != null) {
    128             stf.setTimeZone(TimeZone.getTimeZone("UTC"));
    129             try {
    130                 e = stf.parse(end).getTime();
    131             } catch (final ParseException ex) {
    132                 LOGGER.warn("Error parsing start value " + end, ex);
    133             }
    134         }
    135         final TimeZone timezone = tz == null ? TimeZone.getDefault() : TimeZone.getTimeZone(tz);
    136         final Result onMatch = match == null ? Result.NEUTRAL : match;
    137         final Result onMismatch = mismatch == null ? Result.DENY : mismatch;
    138         return new TimeFilter(s, e, timezone, onMatch, onMismatch);
    139     }
    140
    141 }