1 17 18 19 package org.apache.catalina.valves; 20 21 22 import java.io.BufferedWriter ; 23 import java.io.File ; 24 import java.io.FileWriter ; 25 import java.io.IOException ; 26 import java.io.PrintWriter ; 27 import java.text.SimpleDateFormat ; 28 import java.util.Calendar ; 29 import java.util.Date ; 30 import java.util.TimeZone ; 31 32 import javax.servlet.ServletException ; 33 34 import org.apache.catalina.Lifecycle; 35 import org.apache.catalina.LifecycleException; 36 import org.apache.catalina.LifecycleListener; 37 import org.apache.catalina.connector.Request; 38 import org.apache.catalina.connector.Response; 39 import org.apache.catalina.util.LifecycleSupport; 40 import org.apache.catalina.util.StringManager; 41 42 43 60 61 public final class FastCommonAccessLogValve 62 extends ValveBase 63 implements Lifecycle { 64 65 66 68 69 72 public FastCommonAccessLogValve() { 73 74 super(); 75 setPattern("common"); 76 77 78 } 79 80 81 83 84 88 private String dateStamp = ""; 89 90 91 94 private String directory = "logs"; 95 96 97 100 protected static final String info = 101 "org.apache.catalina.valves.FastCommonAccessLogValve/1.0"; 102 103 104 107 protected LifecycleSupport lifecycle = new LifecycleSupport(this); 108 109 110 113 protected static final String months[] = 114 { "Jan", "Feb", "Mar", "Apr", "May", "Jun", 115 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; 116 117 118 123 private boolean common = false; 124 125 126 130 private boolean combined = false; 131 132 133 136 private String pattern = null; 137 138 139 142 private String prefix = "access_log."; 143 144 145 148 private boolean rotatable = true; 149 150 151 154 private StringManager sm = 155 StringManager.getManager(Constants.Package); 156 157 158 161 private boolean started = false; 162 163 164 167 private String suffix = ""; 168 169 170 173 private PrintWriter writer = null; 174 175 176 180 private SimpleDateFormat dateFormatter = null; 181 182 183 187 private SimpleDateFormat dayFormatter = null; 188 189 190 194 private SimpleDateFormat monthFormatter = null; 195 196 197 201 private SimpleDateFormat yearFormatter = null; 202 203 204 208 private SimpleDateFormat timeFormatter = null; 209 210 211 214 private TimeZone timezone = null; 215 216 217 221 private String timeZoneNoDST = null; 222 223 227 private String timeZoneDST = null; 228 229 230 234 private String currentDateString = null; 235 236 237 240 private long currentDate = 0L; 241 242 243 246 private String space = " "; 247 248 249 252 private boolean resolveHosts = false; 253 254 255 258 private long rotationLastChecked = 0L; 259 260 261 264 private String condition = null; 265 266 267 270 private String fileDateFormat = null; 271 272 273 275 276 279 public String getDirectory() { 280 281 return (directory); 282 283 } 284 285 286 291 public void setDirectory(String directory) { 292 293 this.directory = directory; 294 295 } 296 297 298 301 public String getInfo() { 302 303 return (info); 304 305 } 306 307 308 311 public String getPattern() { 312 313 return (this.pattern); 314 315 } 316 317 318 323 public void setPattern(String pattern) { 324 325 if (pattern == null) 326 pattern = ""; 327 if (pattern.equals(Constants.AccessLog.COMMON_ALIAS)) 328 pattern = Constants.AccessLog.COMMON_PATTERN; 329 if (pattern.equals(Constants.AccessLog.COMBINED_ALIAS)) 330 pattern = Constants.AccessLog.COMBINED_PATTERN; 331 this.pattern = pattern; 332 333 if (this.pattern.equals(Constants.AccessLog.COMBINED_PATTERN)) 334 combined = true; 335 else 336 combined = false; 337 338 } 339 340 341 344 public String getPrefix() { 345 346 return (prefix); 347 348 } 349 350 351 356 public void setPrefix(String prefix) { 357 358 this.prefix = prefix; 359 360 } 361 362 363 366 public boolean isRotatable() { 367 368 return rotatable; 369 370 } 371 372 373 378 public void setRotatable(boolean rotatable) { 379 380 this.rotatable = rotatable; 381 382 } 383 384 385 388 public String getSuffix() { 389 390 return (suffix); 391 392 } 393 394 395 400 public void setSuffix(String suffix) { 401 402 this.suffix = suffix; 403 404 } 405 406 407 412 public void setResolveHosts(boolean resolveHosts) { 413 414 this.resolveHosts = resolveHosts; 415 416 } 417 418 419 422 public boolean isResolveHosts() { 423 424 return resolveHosts; 425 426 } 427 428 429 434 public String getCondition() { 435 436 return condition; 437 438 } 439 440 441 447 public void setCondition(String condition) { 448 449 this.condition = condition; 450 451 } 452 453 456 public String getFileDateFormat() { 457 return fileDateFormat; 458 } 459 460 461 464 public void setFileDateFormat(String fileDateFormat) { 465 this.fileDateFormat = fileDateFormat; 466 } 467 468 470 471 476 public void backgroundProcess() { 477 if (writer != null) 478 writer.flush(); 479 } 480 481 482 492 public void invoke(Request request, Response response) 493 throws IOException , ServletException { 494 495 getNext().invoke(request, response); 497 498 if (condition!=null && 499 null!=request.getRequest().getAttribute(condition)) { 500 return; 501 } 502 503 StringBuffer result = new StringBuffer (); 504 505 String value = null; 507 508 if (isResolveHosts()) 509 result.append(request.getRemoteHost()); 510 else 511 result.append(request.getRemoteAddr()); 512 513 result.append(" - "); 514 515 value = request.getRemoteUser(); 516 if (value == null) 517 result.append("- "); 518 else { 519 result.append(value); 520 result.append(space); 521 } 522 523 result.append(getCurrentDateString()); 524 525 result.append(request.getMethod()); 526 result.append(space); 527 result.append(request.getRequestURI()); 528 if (request.getQueryString() != null) { 529 result.append('?'); 530 result.append(request.getQueryString()); 531 } 532 result.append(space); 533 result.append(request.getProtocol()); 534 result.append("\" "); 535 536 result.append(response.getStatus()); 537 538 result.append(space); 539 540 int length = response.getContentCount(); 541 542 if (length <= 0) 543 value = "-"; 544 else 545 value = "" + length; 546 result.append(value); 547 548 if (combined) { 549 result.append(space); 550 result.append("\""); 551 String referer = request.getHeader("referer"); 552 if(referer != null) 553 result.append(referer); 554 else 555 result.append("-"); 556 result.append("\""); 557 558 result.append(space); 559 result.append("\""); 560 String ua = request.getHeader("user-agent"); 561 if(ua != null) 562 result.append(ua); 563 else 564 result.append("-"); 565 result.append("\""); 566 } 567 568 log(result.toString()); 569 570 } 571 572 573 575 576 579 private synchronized void close() { 580 581 if (writer == null) 582 return; 583 writer.flush(); 584 writer.close(); 585 writer = null; 586 dateStamp = ""; 587 588 } 589 590 591 597 public void log(String message) { 598 599 if (writer != null) { 601 writer.println(message); 602 } 603 604 } 605 606 607 613 private String lookup(String month) { 614 615 int index; 616 try { 617 index = Integer.parseInt(month) - 1; 618 } catch (Throwable t) { 619 index = 0; } 621 return (months[index]); 622 623 } 624 625 626 629 private synchronized void open() { 630 631 File dir = new File (directory); 633 if (!dir.isAbsolute()) 634 dir = new File (System.getProperty("catalina.base"), directory); 635 dir.mkdirs(); 636 637 try { 639 String pathname; 640 if (rotatable){ 642 pathname = dir.getAbsolutePath() + File.separator + 643 prefix + dateStamp + suffix; 644 } else { 645 pathname = dir.getAbsolutePath() + File.separator + 646 prefix + suffix; 647 } 648 writer = new PrintWriter (new BufferedWriter 649 (new FileWriter (pathname, true), 128000), false); 650 } catch (IOException e) { 651 writer = null; 652 } 653 654 } 655 656 657 666 private String getCurrentDateString() { 667 long systime = System.currentTimeMillis(); 669 if ((systime - currentDate) > 1000) { 670 synchronized (this) { 671 if ((systime - currentDate) > 1000) { 675 676 Date date = new Date (); 678 StringBuffer result = new StringBuffer (32); 679 result.append("["); 680 result.append(dayFormatter.format(date)); 682 result.append('/'); 683 result.append(lookup(monthFormatter.format(date))); 685 result.append('/'); 686 result.append(yearFormatter.format(date)); 688 result.append(':'); 689 result.append(timeFormatter.format(date)); 691 result.append(space); 692 result.append(getTimeZone(date)); 694 result.append("] \""); 695 696 if (rotatable) { 698 String tsDate = dateFormatter.format(date); 700 if (!dateStamp.equals(tsDate)) { 702 synchronized (this) { 703 if (!dateStamp.equals(tsDate)) { 704 close(); 705 dateStamp = tsDate; 706 open(); 707 } 708 } 709 } 710 } 711 712 currentDateString = result.toString(); 713 currentDate = date.getTime(); 714 } 715 } 716 } 717 return currentDateString; 718 } 719 720 721 private String getTimeZone(Date date) { 722 if (timezone.inDaylightTime(date)) { 723 return timeZoneDST; 724 } else { 725 return timeZoneNoDST; 726 } 727 } 728 729 730 private String calculateTimeZoneOffset(long offset) { 731 StringBuffer tz = new StringBuffer (); 732 if ((offset<0)) { 733 tz.append("-"); 734 offset = -offset; 735 } else { 736 tz.append("+"); 737 } 738 739 long hourOffset = offset/(1000*60*60); 740 long minuteOffset = (offset/(1000*60)) % 60; 741 742 if (hourOffset<10) 743 tz.append("0"); 744 tz.append(hourOffset); 745 746 if (minuteOffset<10) 747 tz.append("0"); 748 tz.append(minuteOffset); 749 750 return tz.toString(); 751 } 752 753 754 756 757 762 public void addLifecycleListener(LifecycleListener listener) { 763 764 lifecycle.addLifecycleListener(listener); 765 766 } 767 768 769 773 public LifecycleListener[] findLifecycleListeners() { 774 775 return lifecycle.findLifecycleListeners(); 776 777 } 778 779 780 785 public void removeLifecycleListener(LifecycleListener listener) { 786 787 lifecycle.removeLifecycleListener(listener); 788 789 } 790 791 792 800 public void start() throws LifecycleException { 801 802 if (started) 804 throw new LifecycleException 805 (sm.getString("accessLogValve.alreadyStarted")); 806 lifecycle.fireLifecycleEvent(START_EVENT, null); 807 started = true; 808 809 timezone = TimeZone.getDefault(); 811 timeZoneNoDST = calculateTimeZoneOffset(timezone.getRawOffset()); 812 Calendar calendar = Calendar.getInstance(timezone); 813 int offset = calendar.get(Calendar.DST_OFFSET); 814 timeZoneDST = calculateTimeZoneOffset(timezone.getRawOffset()+offset); 815 816 if (fileDateFormat==null || fileDateFormat.length()==0) 817 fileDateFormat = "yyyy-MM-dd"; 818 dateFormatter = new SimpleDateFormat (fileDateFormat); 819 dateFormatter.setTimeZone(timezone); 820 dayFormatter = new SimpleDateFormat ("dd"); 821 dayFormatter.setTimeZone(timezone); 822 monthFormatter = new SimpleDateFormat ("MM"); 823 monthFormatter.setTimeZone(timezone); 824 yearFormatter = new SimpleDateFormat ("yyyy"); 825 yearFormatter.setTimeZone(timezone); 826 timeFormatter = new SimpleDateFormat ("HH:mm:ss"); 827 timeFormatter.setTimeZone(timezone); 828 currentDateString = getCurrentDateString(); 829 dateStamp = dateFormatter.format(new Date ()); 830 831 open(); 832 833 } 834 835 836 844 public void stop() throws LifecycleException { 845 846 if (!started) 848 throw new LifecycleException 849 (sm.getString("accessLogValve.notStarted")); 850 lifecycle.fireLifecycleEvent(STOP_EVENT, null); 851 started = false; 852 853 close(); 854 855 } 856 } 857 | Popular Tags |