File D:\maven-qcr-plugin-testsunitaires\qcr4java\jenkins-master\target\site\qc\core\src\main\java\hudson\tasks\LogRotator.java.html

1 /*
2 * The MIT License
3 *
4 * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Martin Eigenbrodt
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24 package hudson.tasks;
25
26 import com.google.common.collect.Lists;
27 import hudson.Extension;
28 import hudson.model.Job;
29 import hudson.model.Run;
30 import jenkins.model.BuildDiscarder;
31 import jenkins.model.BuildDiscarderDescriptor;
32 import org.kohsuke.stapler.DataBoundConstructor;
33
34 import java.io.IOException;
35 import java.util.Calendar;
36 import java.util.Collection;
37 import java.util.GregorianCalendar;
38 import java.util.List;
39 import java.util.logging.Logger;
40
41 import static java.util.logging.Level.*;
42
43 /**
44 * Default implementation of {@link BuildDiscarder}.
45 *
46 * For historical reason, this is called LogRotator, but it does not rotate logs :-)
47 *
48 * Since 1.350 it has also the option to keep the build, but delete its recorded artifacts.
49 *
50 * @author Kohsuke Kawaguchi
51 */
52 public class LogRotator extends BuildDiscarder {
53
54 /**
55 * If not -1, history is only kept up to this days.
56 */
57 private final int daysToKeep;
58
59 /**
60 * If not -1, only this number of build logs are kept.
61 */
62 private final int numToKeep;
63
64 /**
65 * If not -1 nor null, artifacts are only kept up to this days.
66 * Null handling is necessary to remain data compatible with old versions.
67 * @since 1.350
68 */
69 private final Integer artifactDaysToKeep;
70
71 /**
72 * If not -1 nor null, only this number of builds have their artifacts kept.
73 * Null handling is necessary to remain data compatible with old versions.
74 * @since 1.350
75 */
76 private final Integer artifactNumToKeep;
77
78 @DataBoundConstructor
79 public LogRotator (String daysToKeepStr, String numToKeepStr, String artifactDaysToKeepStr, String artifactNumToKeepStr) {
80 this (parse(daysToKeepStr),parse(numToKeepStr),
81 parse(artifactDaysToKeepStr),parse(artifactNumToKeepStr));
82 }
83
84 public static int parse(String p) {
85 if(p==null) return -1;
86 try {
87 return Integer.parseInt(p);
88 } catch (NumberFormatException e) {
89 return -1;
90 }
91 }
92
93 /**
94 * @deprecated since 1.350.
95 * Use {@link #LogRotator(int, int, int, int)}
96 */
97 public LogRotator(int daysToKeep, int numToKeep) {
98 this(daysToKeep, numToKeep, -1, -1);
99 }
100
101 public LogRotator(int daysToKeep, int numToKeep, int artifactDaysToKeep, int artifactNumToKeep) {
102 this.daysToKeep = daysToKeep;
103 this.numToKeep = numToKeep;
104 this.artifactDaysToKeep = artifactDaysToKeep;
105 this.artifactNumToKeep = artifactNumToKeep;
106
107 }
108
109 @SuppressWarnings("rawtypes")
110 public void perform(Job<?,?> job) throws IOException, InterruptedException {
111 LOGGER.log(FINE, "Running the log rotation for {0}", job);
112
113 // always keep the last successful and the last stable builds
114 Run lsb = job.getLastSuccessfulBuild();
115 Run lstb = job.getLastStableBuild();
116
117 if(numToKeep!=-1) {
118 List<? extends Run<?,?>> builds = job.getBuilds();
119 for (Run r : copy(builds.subList(Math.min(builds.size(), numToKeep), builds.size()))) {
120 if (r.isKeepLog()) {
121 LOGGER.log(FINER, "{0} is not GC-ed because it''s marked as a keeper", r);
122 continue;
123 }
124 if (r==lsb) {
125 LOGGER.log(FINER, "{0} is not GC-ed because it''s the last successful build", r);
126 continue;
127 }
128 if (r==lstb) {
129 LOGGER.log(FINER, "{0} is not GC-ed because it''s the last stable build", r);
130 continue;
131 }
132 LOGGER.log(FINE, "{0} is to be removed", r);
133 r.delete();
134 }
135 }
136
137 if(daysToKeep!=-1) {
138 Calendar cal = new GregorianCalendar();
139 cal.add(Calendar.DAY_OF_YEAR,-daysToKeep);
140 for( Run r : copy(job.getBuilds()) ) {
141 if (r.isKeepLog()) {
142 LOGGER.log(FINER, "{0} is not GC-ed because it''s marked as a keeper", r);
143 continue;
144 }
145 if (r==lsb) {
146 LOGGER.log(FINER, "{0} is not GC-ed because it''s the last successful build", r);
147 continue;
148 }
149 if (r==lstb) {
150 LOGGER.log(FINER, "{0} is not GC-ed because it''s the last stable build", r);
151 continue;
152 }
153 if (!r.getTimestamp().before(cal)) {
154 LOGGER.log(FINER, "{0} is not GC-ed because it''s still new", r);
155 continue;
156 }
157 LOGGER.log(FINE, "{0} is to be removed", r);
158 r.delete();
159 }
160 }
161
162 if(artifactNumToKeep!=null && artifactNumToKeep!=-1) {
163 List<? extends Run<?,?>> builds = job.getBuilds();
164 for (Run r : copy(builds.subList(Math.min(builds.size(), artifactNumToKeep), builds.size()))) {
165 if (r.isKeepLog()) {
166 LOGGER.log(FINER, "{0} is not purged of artifacts because it''s marked as a keeper", r);
167 continue;
168 }
169 if (r==lsb) {
170 LOGGER.log(FINER, "{0} is not purged of artifacts because it''s the last successful build", r);
171 continue;
172 }
173 if (r==lstb) {
174 LOGGER.log(FINER, "{0} is not purged of artifacts because it''s the last stable build", r);
175 continue;
176 }
177 LOGGER.log(FINE, "{0} is to be purged of artifacts", r);
178 r.deleteArtifacts();
179 }
180 }
181
182 if(artifactDaysToKeep!=null && artifactDaysToKeep!=-1) {
183 Calendar cal = new GregorianCalendar();
184 cal.add(Calendar.DAY_OF_YEAR,-artifactDaysToKeep);
185 for( Run r : copy(job.getBuilds())) {
186 if (r.isKeepLog()) {
187 LOGGER.log(FINER, "{0} is not purged of artifacts because it''s marked as a keeper", r);
188 continue;
189 }
190 if (r==lsb) {
191 LOGGER.log(FINER, "{0} is not purged of artifacts because it''s the last successful build", r);
192 continue;
193 }
194 if (r==lstb) {
195 LOGGER.log(FINER, "{0} is not purged of artifacts because it''s the last stable build", r);
196 continue;
197 }
198 if (!r.getTimestamp().before(cal)) {
199 LOGGER.log(FINER, "{0} is not purged of artifacts because it''s still new", r);
200 continue;
201 }
202 LOGGER.log(FINE, "{0} is to be purged of artifacts", r);
203 r.deleteArtifacts();
204 }
205 }
206 }
207
208 /**
209 * Creates a copy since we'll be deleting some entries from them.
210 */
211 private <R> Collection<R> copy(Iterable<R> src) {
212 return Lists.newArrayList(src);
213 }
214
215 public int getDaysToKeep() {
216 return daysToKeep;
217 }
218
219 public int getNumToKeep() {
220 return numToKeep;
221 }
222
223 public int getArtifactDaysToKeep() {
224 return unbox(artifactDaysToKeep);
225 }
226
227 public int getArtifactNumToKeep() {
228 return unbox(artifactNumToKeep);
229 }
230
231 public String getDaysToKeepStr() {
232 return toString(daysToKeep);
233 }
234
235 public String getNumToKeepStr() {
236 return toString(numToKeep);
237 }
238
239 public String getArtifactDaysToKeepStr() {
240 return toString(artifactDaysToKeep);
241 }
242
243 public String getArtifactNumToKeepStr() {
244 return toString(artifactNumToKeep);
245 }
246
247 private int unbox(Integer i) {
248 return i==null ? -1: i;
249 }
250
251 private String toString(Integer i) {
252 if (i==null || i==-1) return "";
253 return String.valueOf(i);
254 }
255
256 @Extension
257 public static final class LRDescriptor extends BuildDiscarderDescriptor {
258 public String getDisplayName() {
259 return "Log Rotation";
260 }
261 }
262
263 private static final Logger LOGGER = Logger.getLogger(LogRotator.class.getName());
264 }
265