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", type = "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 }