1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.appender.rolling;
18
19 import java.text.ParseException;
20 import java.util.Calendar;
21 import java.util.Date;
22 import java.util.Objects;
23 import java.util.concurrent.TimeUnit;
24
25 import org.apache.logging.log4j.core.Core;
26 import org.apache.logging.log4j.core.LifeCycle;
27 import org.apache.logging.log4j.core.LogEvent;
28 import org.apache.logging.log4j.core.config.Configuration;
29 import org.apache.logging.log4j.core.config.ConfigurationScheduler;
30 import org.apache.logging.log4j.core.config.CronScheduledFuture;
31 import org.apache.logging.log4j.core.config.Scheduled;
32 import org.apache.logging.log4j.core.config.plugins.Plugin;
33 import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
34 import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
35 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
36 import org.apache.logging.log4j.core.util.CronExpression;
37
38
39
40
41 @Plugin(name = "CronTriggeringPolicy", category = Core.CATEGORY_NAME, printObject = true)
42 @Scheduled
43 public final class CronTriggeringPolicy extends AbstractTriggeringPolicy {
44
45 private static final String defaultSchedule = "0 0 0 * * ?";
46 private RollingFileManager manager;
47 private final CronExpression cronExpression;
48 private final Configuration configuration;
49 private final boolean checkOnStartup;
50 private volatile Date lastRollDate;
51 private CronScheduledFuture<?> future;
52
53 private CronTriggeringPolicy(final CronExpression schedule, final boolean checkOnStartup,
54 final Configuration configuration) {
55 this.cronExpression = Objects.requireNonNull(schedule, "schedule");
56 this.configuration = Objects.requireNonNull(configuration, "configuration");
57 this.checkOnStartup = checkOnStartup;
58 }
59
60
61
62
63
64
65
66 @Override
67 public void initialize(final RollingFileManager aManager) {
68 this.manager = aManager;
69 final Date now = new Date();
70 final Date lastRollForFile = cronExpression.getPrevFireTime(new Date(this.manager.getFileTime()));
71 final Date lastRegularRoll = cronExpression.getPrevFireTime(new Date());
72 aManager.getPatternProcessor().setCurrentFileTime(lastRegularRoll.getTime());
73 LOGGER.debug("LastRollForFile {}, LastRegularRole {}", lastRollForFile, lastRegularRoll);
74 aManager.getPatternProcessor().setPrevFileTime(lastRegularRoll.getTime());
75 if (checkOnStartup && lastRollForFile != null && lastRegularRoll != null &&
76 lastRollForFile.before(lastRegularRoll)) {
77 lastRollDate = lastRollForFile;
78 rollover();
79 }
80
81 final ConfigurationScheduler scheduler = configuration.getScheduler();
82 if (!scheduler.isExecutorServiceSet()) {
83
84 scheduler.incrementScheduledItems();
85 }
86 if (!scheduler.isStarted()) {
87 scheduler.start();
88 }
89 lastRollDate = lastRegularRoll;
90 future = scheduler.scheduleWithCron(cronExpression, now, new CronTrigger());
91 LOGGER.debug(scheduler.toString());
92 }
93
94
95
96
97
98
99
100
101 @Override
102 public boolean isTriggeringEvent(final LogEvent event) {
103 return false;
104 }
105
106 public CronExpression getCronExpression() {
107 return cronExpression;
108 }
109
110
111
112
113
114
115
116
117
118
119
120
121 @PluginFactory
122 public static CronTriggeringPolicy createPolicy(@PluginConfiguration final Configuration configuration,
123 @PluginAttribute("evaluateOnStartup") final String evaluateOnStartup,
124 @PluginAttribute("schedule") final String schedule) {
125 CronExpression cronExpression;
126 final boolean checkOnStartup = Boolean.parseBoolean(evaluateOnStartup);
127 if (schedule == null) {
128 LOGGER.info("No schedule specified, defaulting to Daily");
129 cronExpression = getSchedule(defaultSchedule);
130 } else {
131 cronExpression = getSchedule(schedule);
132 if (cronExpression == null) {
133 LOGGER.error("Invalid expression specified. Defaulting to Daily");
134 cronExpression = getSchedule(defaultSchedule);
135 }
136 }
137 return new CronTriggeringPolicy(cronExpression, checkOnStartup, configuration);
138 }
139
140 private static CronExpression getSchedule(final String expression) {
141 try {
142 return new CronExpression(expression);
143 } catch (final ParseException pe) {
144 LOGGER.error("Invalid cron expression - " + expression, pe);
145 return null;
146 }
147 }
148
149 private void rollover() {
150 manager.getPatternProcessor().setPrevFileTime(lastRollDate.getTime());
151 final Date thisRoll = cronExpression.getPrevFireTime(new Date());
152 manager.getPatternProcessor().setCurrentFileTime(thisRoll.getTime());
153 manager.rollover();
154 if (future != null) {
155 lastRollDate = future.getFireTime();
156 }
157 }
158
159 @Override
160 public boolean stop(final long timeout, final TimeUnit timeUnit) {
161 setStopping();
162 final boolean stopped = stop(future);
163 setStopped();
164 return stopped;
165 }
166
167 @Override
168 public String toString() {
169 return "CronTriggeringPolicy(schedule=" + cronExpression.getCronExpression() + ")";
170 }
171
172 private class CronTrigger implements Runnable {
173
174 @Override
175 public void run() {
176 rollover();
177 }
178 }
179 }