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 
119         nextRolloverMillis = ThreadLocalRandom.current().nextLong(0, 1 + maxRandomDelayMillis)
120                 + aManager.getPatternProcessor().getNextTime(current, interval, modulate);
121     }
122 
123     /**
124      * Determines whether a rollover should occur.
125      * @param event   A reference to the currently event.
126      * @return true if a rollover should occur.
127      */
128     @Override
129     public boolean isTriggeringEvent(final LogEvent event) {
130         final long nowMillis = event.getTimeMillis();
131         if (nowMillis >= nextRolloverMillis) {
132             nextRolloverMillis = ThreadLocalRandom.current().nextLong(0, 1 + maxRandomDelayMillis)
133                     + manager.getPatternProcessor().getNextTime(nowMillis, interval, modulate);
134             manager.getPatternProcessor().setCurrentFileTime(System.currentTimeMillis());
135             return true;
136         }
137         return false;
138     }
139 
140     /**
141      * Creates a TimeBasedTriggeringPolicy.
142      * @param interval The interval between rollovers.
143      * @param modulate If true the time will be rounded to occur on a boundary aligned with the increment.
144      * @return a TimeBasedTriggeringPolicy.
145      * @deprecated Use {@link #newBuilder()}.
146      */
147     @Deprecated
148     public static TimeBasedTriggeringPolicy createPolicy(
149             @PluginAttribute("interval") final String interval,
150             @PluginAttribute("modulate") final String modulate) {
151         return newBuilder()
152                 .withInterval(Integers.parseInt(interval, 1))
153                 .withModulate(Boolean.parseBoolean(modulate))
154                 .build();
155     }
156 
157     @PluginBuilderFactory
158     public static TimeBasedTriggeringPolicy.Builder newBuilder() {
159         return new Builder();
160     }
161 
162     @Override
163     public String toString() {
164         return "TimeBasedTriggeringPolicy(nextRolloverMillis=" + nextRolloverMillis + ", interval=" + interval
165                 + ", modulate=" + modulate + ")";
166     }
167 
168 }