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.util.concurrent.ThreadLocalRandom;
20  import java.util.concurrent.TimeUnit;
21  
22  import org.apache.logging.log4j.core.Core;
23  import org.apache.logging.log4j.core.LogEvent;
24  import org.apache.logging.log4j.core.config.plugins.Plugin;
25  import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
26  import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
27  import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
28  import org.apache.logging.log4j.core.util.Integers;
29  
30  /**
31   * Rolls a file over based on time.
32   */
33  @Plugin(name = "TimeBasedTriggeringPolicy", category = Core.CATEGORY_NAME, printObject = true)
34  public final class TimeBasedTriggeringPolicy extends AbstractTriggeringPolicy {
35  
36  
37      public static class Builder implements org.apache.logging.log4j.core.util.Builder<TimeBasedTriggeringPolicy> {
38  
39          @PluginBuilderAttribute
40          private int interval = 1;
41  
42          @PluginBuilderAttribute
43          private boolean modulate = false;
44  
45          @PluginBuilderAttribute
46          private int maxRandomDelay = 0;
47  
48          @Override
49          public TimeBasedTriggeringPolicy build() {
50              final long maxRandomDelayMillis = TimeUnit.SECONDS.toMillis(maxRandomDelay);
51              return new TimeBasedTriggeringPolicy(interval, modulate, maxRandomDelayMillis);
52          }
53  
54          public int getInterval() {
55              return interval;
56          }
57  
58          public boolean isModulate() {
59              return modulate;
60          }
61  
62          public int getMaxRandomDelay() {
63              return maxRandomDelay;
64          }
65  
66          public Builder withInterval(final int interval){
67              this.interval = interval;
68              return this;
69          }
70  
71          public Builder withModulate(final boolean modulate){
72              this.modulate = modulate;
73              return this;
74          }
75  
76          public Builder withMaxRandomDelay(final int maxRandomDelay){
77              this.maxRandomDelay = maxRandomDelay;
78              return this;
79          }
80  
81      }
82  
83      private long nextRolloverMillis;
84      private final int interval;
85      private final boolean modulate;
86      private final long maxRandomDelayMillis;
87  
88      private RollingFileManager manager;
89  
90      private TimeBasedTriggeringPolicy(final int interval, final boolean modulate, final long maxRandomDelayMillis) {
91          this.interval = interval;
92          this.modulate = modulate;
93          this.maxRandomDelayMillis = maxRandomDelayMillis;
94      }
95  
96      public int getInterval() {
97          return interval;
98      }
99  
100     public long getNextRolloverMillis() {
101         return nextRolloverMillis;
102     }
103 
104     /**
105      * Initializes the policy.
106      * @param aManager The RollingFileManager.
107      */
108     @Override
109     public void initialize(final RollingFileManager aManager) {
110         this.manager = aManager;
111         long current = aManager.getFileTime();
112         if (current == 0) {
113             current = System.currentTimeMillis();
114         }
115 
116         // LOG4J2-531: call getNextTime twice to force initialization of both prevFileTime and nextFileTime
117         aManager.getPatternProcessor().getNextTime(current, interval, modulate);
118         aManager.getPatternProcessor().setTimeBased(true);
119 
120         nextRolloverMillis = ThreadLocalRandom.current().nextLong(0, 1 + maxRandomDelayMillis)
121                 + aManager.getPatternProcessor().getNextTime(current, interval, modulate);
122     }
123 
124     /**
125      * Determines whether a rollover should occur.
126      * @param event   A reference to the currently event.
127      * @return true if a rollover should occur.
128      */
129     @Override
130     public boolean isTriggeringEvent(final LogEvent event) {
131         final long nowMillis = event.getTimeMillis();
132         if (nowMillis >= nextRolloverMillis) {
133             nextRolloverMillis = ThreadLocalRandom.current().nextLong(0, 1 + maxRandomDelayMillis)
134                     + manager.getPatternProcessor().getNextTime(nowMillis, interval, modulate);
135             manager.getPatternProcessor().setCurrentFileTime(System.currentTimeMillis());
136             return true;
137         }
138         return false;
139     }
140 
141     /**
142      * Creates a TimeBasedTriggeringPolicy.
143      * @param interval The interval between rollovers.
144      * @param modulate If true the time will be rounded to occur on a boundary aligned with the increment.
145      * @return a TimeBasedTriggeringPolicy.
146      * @deprecated Use {@link #newBuilder()}.
147      */
148     @Deprecated
149     public static TimeBasedTriggeringPolicy createPolicy(
150             @PluginAttribute("interval") final String interval,
151             @PluginAttribute("modulate") final String modulate) {
152         return newBuilder()
153                 .withInterval(Integers.parseInt(interval, 1))
154                 .withModulate(Boolean.parseBoolean(modulate))
155                 .build();
156     }
157 
158     @PluginBuilderFactory
159     public static TimeBasedTriggeringPolicy.Builder newBuilder() {
160         return new Builder();
161     }
162 
163     @Override
164     public String toString() {
165         return "TimeBasedTriggeringPolicy(nextRolloverMillis=" + nextRolloverMillis + ", interval=" + interval
166                 + ", modulate=" + modulate + ")";
167     }
168 
169 }