1 16 package org.jboss.logging.jdk.handlers; 17 18 import java.util.Date ; 19 import java.util.TimeZone ; 20 import java.util.Locale ; 21 import java.util.GregorianCalendar ; 22 import java.util.Calendar ; 23 import java.util.logging.Formatter ; 24 import java.util.logging.ErrorManager ; 25 import java.util.logging.LogRecord ; 26 import java.text.SimpleDateFormat ; 27 import java.io.IOException ; 28 import java.io.File ; 29 30 134 public class DailyRollingFileHandler extends FileHandler 135 { 136 static final int TOP_OF_TROUBLE = -1; 139 static final int TOP_OF_MINUTE = 0; 140 static final int TOP_OF_HOUR = 1; 141 static final int HALF_DAY = 2; 142 static final int TOP_OF_DAY = 3; 143 static final int TOP_OF_WEEK = 4; 144 static final int TOP_OF_MONTH = 5; 145 146 147 151 private String datePattern = "'.'yyyy-MM-dd"; 152 153 163 private String scheduledFilename; 164 165 168 private long nextCheck = System.currentTimeMillis() - 1; 169 170 Date now = new Date (); 171 172 SimpleDateFormat sdf; 173 174 RollingCalendar rc = new RollingCalendar(); 175 176 int checkPeriod = TOP_OF_TROUBLE; 177 178 static final TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT"); 180 181 182 185 public DailyRollingFileHandler() 186 { 187 } 188 189 194 public DailyRollingFileHandler(Formatter layout, String filename, 195 String datePattern) throws IOException 196 { 197 super(layout, filename, true); 198 this.datePattern = datePattern; 199 activateOptions(); 200 } 201 202 207 public void setDatePattern(String pattern) 208 { 209 datePattern = pattern; 210 } 211 212 215 public String getDatePattern() 216 { 217 return datePattern; 218 } 219 220 public void activateOptions() 221 { 222 super.activateOptions(); 223 if (datePattern != null && fileName != null) 224 { 225 now.setTime(System.currentTimeMillis()); 226 sdf = new SimpleDateFormat (datePattern); 227 int type = computeCheckPeriod(); 228 printPeriodicity(type); 229 rc.setType(type); 230 File file = new File (fileName); 231 scheduledFilename = fileName + sdf.format(new Date (file.lastModified())); 232 } 233 else 234 { 235 reportError("Either File or DatePattern options are not set for appender [" 236 + name + "].", null, ErrorManager.OPEN_FAILURE); 237 } 238 } 239 240 void printPeriodicity(int type) 241 { 242 switch (type) 243 { 244 case TOP_OF_MINUTE: 245 debug("Appender [" + name + "] to be rolled every minute."); 246 break; 247 case TOP_OF_HOUR: 248 debug("Appender [" + name 249 + "] to be rolled on top of every hour."); 250 break; 251 case HALF_DAY: 252 debug("Appender [" + name 253 + "] to be rolled at midday and midnight."); 254 break; 255 case TOP_OF_DAY: 256 debug("Appender [" + name 257 + "] to be rolled at midnight."); 258 break; 259 case TOP_OF_WEEK: 260 debug("Appender [" + name 261 + "] to be rolled at start of week."); 262 break; 263 case TOP_OF_MONTH: 264 debug("Appender [" + name 265 + "] to be rolled at start of every month."); 266 break; 267 default: 268 reportError("Unknown periodicity for appender [" + name + "].", 269 null, ErrorManager.FORMAT_FAILURE); 270 } 271 } 272 273 282 int computeCheckPeriod() 283 { 284 RollingCalendar rollingCalendar = new RollingCalendar(gmtTimeZone, Locale.ENGLISH); 285 Date epoch = new Date (0); 287 if (datePattern != null) 288 { 289 for (int i = TOP_OF_MINUTE; i <= TOP_OF_MONTH; i++) 290 { 291 SimpleDateFormat simpleDateFormat = new SimpleDateFormat (datePattern); 292 simpleDateFormat.setTimeZone(gmtTimeZone); String r0 = simpleDateFormat.format(epoch); 294 rollingCalendar.setType(i); 295 Date next = new Date (rollingCalendar.getNextCheckMillis(epoch)); 296 String r1 = simpleDateFormat.format(next); 297 if (r0 != null && r1 != null && !r0.equals(r1)) 299 { 300 return i; 301 } 302 } 303 } 304 return TOP_OF_TROUBLE; } 306 307 310 void rollOver() throws IOException 311 { 312 313 314 if (datePattern == null) 315 { 316 reportError("Missing DatePattern option in rollOver().", null, ErrorManager.OPEN_FAILURE); 317 return; 318 } 319 320 String datedFilename = fileName + sdf.format(now); 321 if (scheduledFilename.equals(datedFilename)) 325 { 326 return; 327 } 328 329 this.close(); 331 332 File target = new File (scheduledFilename); 333 if (target.exists()) 334 { 335 target.delete(); 336 } 337 338 File file = new File (fileName); 339 boolean result = file.renameTo(target); 340 if (result) 341 { 342 debug(fileName + " -> " + scheduledFilename); 343 } 344 else 345 { 346 reportError("Failed to rename [" + fileName + "] to [" + scheduledFilename + "].", 347 null, ErrorManager.OPEN_FAILURE); 348 } 349 350 try 351 { 352 this.setFile(fileName, false, this.bufferedIO, this.bufferSize); 355 } 356 catch (IOException e) 357 { 358 reportError("setFile(" + fileName + ", false) call failed.", 359 null, ErrorManager.OPEN_FAILURE); 360 } 361 scheduledFilename = datedFilename; 362 } 363 364 372 protected void subPublish(LogRecord event) 373 { 374 long n = System.currentTimeMillis(); 375 if (n >= nextCheck) 376 { 377 now.setTime(n); 378 nextCheck = rc.getNextCheckMillis(now); 379 try 380 { 381 rollOver(); 382 } 383 catch (IOException ioe) 384 { 385 reportError("rollOver() failed.", ioe, ErrorManager.OPEN_FAILURE); 386 } 387 } 388 super.subPublish(event); 389 } 390 } 391 392 397 class RollingCalendar extends GregorianCalendar 398 { 399 400 int type = DailyRollingFileHandler.TOP_OF_TROUBLE; 401 402 RollingCalendar() 403 { 404 super(); 405 } 406 407 RollingCalendar(TimeZone tz, Locale locale) 408 { 409 super(tz, locale); 410 } 411 412 void setType(int type) 413 { 414 this.type = type; 415 } 416 417 public long getNextCheckMillis(Date now) 418 { 419 return getNextCheckDate(now).getTime(); 420 } 421 422 public Date getNextCheckDate(Date now) 423 { 424 this.setTime(now); 425 426 switch (type) 427 { 428 case DailyRollingFileHandler.TOP_OF_MINUTE: 429 this.set(Calendar.SECOND, 0); 430 this.set(Calendar.MILLISECOND, 0); 431 this.add(Calendar.MINUTE, 1); 432 break; 433 case DailyRollingFileHandler.TOP_OF_HOUR: 434 this.set(Calendar.MINUTE, 0); 435 this.set(Calendar.SECOND, 0); 436 this.set(Calendar.MILLISECOND, 0); 437 this.add(Calendar.HOUR_OF_DAY, 1); 438 break; 439 case DailyRollingFileHandler.HALF_DAY: 440 this.set(Calendar.MINUTE, 0); 441 this.set(Calendar.SECOND, 0); 442 this.set(Calendar.MILLISECOND, 0); 443 int hour = get(Calendar.HOUR_OF_DAY); 444 if (hour < 12) 445 { 446 this.set(Calendar.HOUR_OF_DAY, 12); 447 } 448 else 449 { 450 this.set(Calendar.HOUR_OF_DAY, 0); 451 this.add(Calendar.DAY_OF_MONTH, 1); 452 } 453 break; 454 case DailyRollingFileHandler.TOP_OF_DAY: 455 this.set(Calendar.HOUR_OF_DAY, 0); 456 this.set(Calendar.MINUTE, 0); 457 this.set(Calendar.SECOND, 0); 458 this.set(Calendar.MILLISECOND, 0); 459 this.add(Calendar.DATE, 1); 460 break; 461 case DailyRollingFileHandler.TOP_OF_WEEK: 462 this.set(Calendar.DAY_OF_WEEK, getFirstDayOfWeek()); 463 this.set(Calendar.HOUR_OF_DAY, 0); 464 this.set(Calendar.SECOND, 0); 465 this.set(Calendar.MILLISECOND, 0); 466 this.add(Calendar.WEEK_OF_YEAR, 1); 467 break; 468 case DailyRollingFileHandler.TOP_OF_MONTH: 469 this.set(Calendar.DATE, 1); 470 this.set(Calendar.HOUR_OF_DAY, 0); 471 this.set(Calendar.SECOND, 0); 472 this.set(Calendar.MILLISECOND, 0); 473 this.add(Calendar.MONTH, 1); 474 break; 475 default: 476 throw new IllegalStateException ("Unknown periodicity type."); 477 } 478 return getTime(); 479 } 480 } 481 482 | Popular Tags |