001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache license, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the license for the specific language governing permissions and
015 * limitations under the license.
016 */
017 package org.apache.logging.log4j.core.filter;
018
019 import org.apache.logging.log4j.core.LogEvent;
020 import org.apache.logging.log4j.core.config.plugins.Plugin;
021 import org.apache.logging.log4j.core.config.plugins.PluginAttr;
022 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
023
024 import java.text.ParseException;
025 import java.text.SimpleDateFormat;
026 import java.util.Calendar;
027 import java.util.TimeZone;
028
029 /**
030 * Filters events that fall within a specified time period in each day.
031 */
032 @Plugin(name = "TimeFilter", category = "Core", elementType = "filter", printObject = true)
033 public final class TimeFilter extends AbstractFilter {
034 /**
035 * Length of hour in milliseconds.
036 */
037 private static final long HOUR_MS = 3600000;
038
039 /**
040 * Length of minute in milliseconds.
041 */
042 private static final long MINUTE_MS = 60000;
043
044 /**
045 * Length of second in milliseconds.
046 */
047 private static final long SECOND_MS = 1000;
048
049 /**
050 * Starting offset from midnight in milliseconds.
051 */
052 private final long start;
053 /**
054 * Ending offset from midnight in milliseconds.
055 */
056 private final long end;
057 /**
058 * Timezone.
059 */
060 private final TimeZone timezone;
061
062
063 private TimeFilter(final long start, final long end, final TimeZone tz, final Result onMatch,
064 final Result onMismatch) {
065 super(onMatch, onMismatch);
066 this.start = start;
067 this.end = end;
068 timezone = tz;
069 }
070
071 @Override
072 public Result filter(final LogEvent event) {
073 final Calendar calendar = Calendar.getInstance(timezone);
074 calendar.setTimeInMillis(event.getMillis());
075 //
076 // get apparent number of milliseconds since midnight
077 // (ignores extra or missing hour on daylight time changes).
078 //
079 final long apparentOffset = calendar.get(Calendar.HOUR_OF_DAY) * HOUR_MS +
080 calendar.get(Calendar.MINUTE) * MINUTE_MS +
081 calendar.get(Calendar.SECOND) * SECOND_MS +
082 calendar.get(Calendar.MILLISECOND);
083 return apparentOffset >= start && apparentOffset < end ? onMatch : onMismatch;
084 }
085
086 @Override
087 public String toString() {
088 final StringBuilder sb = new StringBuilder();
089 sb.append("start=").append(start);
090 sb.append(", end=").append(end);
091 sb.append(", timezone=").append(timezone.toString());
092 return sb.toString();
093 }
094
095 /**
096 * Create a TimeFilter.
097 * @param start The start time.
098 * @param end The end time.
099 * @param tz timezone.
100 * @param match Action to perform if the time matches.
101 * @param mismatch Action to perform if the action does not match.
102 * @return A TimeFilter.
103 */
104 @PluginFactory
105 public static TimeFilter createFilter(@PluginAttr("start") final String start,
106 @PluginAttr("end") final String end,
107 @PluginAttr("timezone") final String tz,
108 @PluginAttr("onMatch") final String match,
109 @PluginAttr("onMismatch") final String mismatch) {
110 final SimpleDateFormat stf = new SimpleDateFormat("HH:mm:ss");
111 long s = 0;
112 if (start != null) {
113 stf.setTimeZone(TimeZone.getTimeZone("UTC"));
114 try {
115 s = stf.parse(start).getTime();
116 } catch (final ParseException ex) {
117 LOGGER.warn("Error parsing start value " + start, ex);
118 }
119 }
120 long e = Long.MAX_VALUE;
121 if (end != null) {
122 stf.setTimeZone(TimeZone.getTimeZone("UTC"));
123 try {
124 e = stf.parse(end).getTime();
125 } catch (final ParseException ex) {
126 LOGGER.warn("Error parsing start value " + end, ex);
127 }
128 }
129 final TimeZone timezone = tz == null ? TimeZone.getDefault() : TimeZone.getTimeZone(tz);
130 final Result onMatch = Result.toResult(match, Result.NEUTRAL);
131 final Result onMismatch = Result.toResult(mismatch, Result.DENY);
132 return new TimeFilter(s, e, timezone, onMatch, onMismatch);
133 }
134
135 }