1 23 24 package com.sun.enterprise.web; 25 26 27 import java.io.File ; 28 import java.io.FileWriter ; 29 import java.io.IOException ; 30 import java.io.FileOutputStream ; 31 32 import java.net.InetAddress ; 33 34 import java.nio.ByteBuffer ; 35 import java.nio.CharBuffer ; 36 import java.nio.BufferOverflowException ; 37 import java.nio.channels.FileChannel ; 38 39 import java.text.SimpleDateFormat ; 40 import java.text.DecimalFormat ; 41 42 import java.util.Date ; 43 import java.util.LinkedList ; 44 import java.util.TimeZone ; 45 import java.util.logging.Logger ; 46 import java.util.logging.Level ; 47 48 import javax.servlet.ServletException ; 49 import javax.servlet.ServletRequest ; 50 import javax.servlet.ServletResponse ; 51 import javax.servlet.http.Cookie ; 52 import javax.servlet.http.HttpServletRequest ; 53 import javax.servlet.http.HttpServletResponse ; 54 import javax.servlet.http.HttpSession ; 55 56 import org.apache.catalina.Container; 57 import org.apache.catalina.HttpResponse; 58 import org.apache.catalina.Lifecycle; 59 import org.apache.catalina.LifecycleEvent; 60 import org.apache.catalina.LifecycleException; 61 import org.apache.catalina.LifecycleListener; 62 import org.apache.catalina.Request; 63 import org.apache.catalina.Response; 64 import org.apache.catalina.util.LifecycleSupport; 65 import org.apache.catalina.util.StringManager; 66 import org.apache.catalina.valves.ValveBase; 67 68 import com.sun.logging.LogDomains; 69 70 83 84 public final class PEAccessLogValve 85 extends ValveBase 86 implements Lifecycle, Runnable { 87 88 private static final Logger _logger = 89 LogDomains.getLogger(LogDomains.WEB_LOGGER); 90 91 101 private static final String LOGGING_MAX_HISTORY_FILES = 102 "com.sun.enterprise.server.logging.max_history_files"; 103 104 107 private static final String HTTP_HEADER_ACCEPT = "Accept"; 108 private static final String HTTP_HEADER_AUTHORIZATION = "Authorization"; 109 private static final String HTTP_HEADER_DATE = "Date"; 110 private static final String HTTP_HEADER_IF_MODIFIED_SINCE = "If-Modified-Since"; 111 112 115 private static final String AUTH_USER_NAME = "auth-user-name"; 116 private static final String CLIENT_DNS = "client.dns"; 117 private static final String CLIENT_NAME = "client.name"; 118 private static final String COOKIE_VALUE = "cookie.value"; 119 private static final String DATE_TIME = "datetime"; 120 private static final String HEADER_ACCEPT = "header.accept"; 121 private static final String HEADER_ANY = "header."; 122 private static final int HEADER_ANY_LEN = HEADER_ANY.length(); 123 private static final String HEADER_AUTH = "header.auth"; 124 private static final String HEADER_DATE = "header.date"; 125 private static final String HEADER_IF_MOD_SINCE = "header.if-mod-since"; 126 private static final String HEADER_USER_AGENT = "header.user-agent"; 127 private static final String HEADER_REFERER = "header.referer"; 128 private static final String HTTP_METHOD = "http-method"; 129 private static final String HTTP_URI = "http-uri"; 130 private static final String HTTP_VERSION = "http-version"; 131 private static final String QUERY_STR = "query-str"; 132 private static final String REFERER = "referer"; 133 private static final String REQUEST = "request"; 134 private static final String RESPONSE_LENGTH = "response.length"; 135 private static final String STATUS = "status"; 136 private static final String USER_AGENT = "user.agent"; 137 private static final String VS_ID = "vs.id"; 138 139 140 142 143 146 private String directory = "logs"; 147 148 149 152 protected static final String info = 153 "com.sun.enterprise.web.PEAccessLogValve/1.0"; 154 155 156 159 protected LifecycleSupport lifecycle = new LifecycleSupport(this); 160 161 162 165 protected static final String months[] = 166 { "Jan", "Feb", "Mar", "Apr", "May", "Jun", 167 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; 168 169 170 173 private String pattern = null; 174 175 176 179 private String prefix = ""; 180 181 182 185 private boolean rotatable; 186 187 188 191 private StringManager sm = 192 StringManager.getManager(Constants.Package); 193 194 195 198 private boolean started = false; 199 200 201 204 private String suffix = ""; 205 206 207 211 private boolean removeLeadingDotFromSuffix = false; 212 213 214 218 private String dotLessSuffix = null; 219 220 221 225 private SimpleDateFormat dateFormatter = null; 226 227 228 232 private SimpleDateFormat dayFormatter = null; 233 234 235 239 private SimpleDateFormat monthFormatter = null; 240 241 242 246 private SimpleDateFormat yearFormatter = null; 247 248 249 253 private SimpleDateFormat timeFormatter = null; 254 255 256 259 private String timeZone = null; 260 261 262 266 private Date currentDate = null; 267 268 269 272 private String space = " "; 273 274 275 278 private boolean resolveHosts = false; 279 280 281 284 private long lastAccessLogCreationTime = 0L; 285 286 287 290 private String condition = null; 291 292 293 296 private String fileDateFormat = null; 297 298 299 302 protected FileChannel fileChannel; 303 304 305 308 FileOutputStream fos; 309 310 311 314 private int writeInterval; 315 316 317 320 private int rotationInterval; 321 322 323 326 private Thread writerThread = null; 327 328 329 332 private boolean threadDone = false; 333 334 335 338 private CharBuffer charBuffer; 339 340 341 346 public int chunkSize = 0; 347 348 349 352 protected int bufferSize = 512 * 1024; 353 private int expandedBufferSize; 354 355 356 360 protected boolean flushRealTime = true; 361 362 363 370 private boolean addDateStampToFirstAccessLogFile; 371 372 373 376 private LinkedList <String > patternComponents; 377 378 379 382 private File logFile; 383 384 385 388 private int maxHistoryFiles; 389 390 391 394 private boolean deleteAllHistoryFiles; 395 396 397 401 private LinkedList <File > historyFiles; 402 403 404 407 public int getWriterInterval() { 408 return writeInterval; 409 } 410 411 412 415 public void setWriterInterval(int t) { 416 if ( t > 0 ){ 417 flushRealTime = false; 418 } 419 writeInterval = t; 420 } 421 422 423 426 public int geRotationInterval() { 427 return rotationInterval; 428 } 429 430 431 434 public void setRotationInterval(int t) { 435 rotationInterval = t; 436 } 437 438 439 442 public void setBufferSize(int size){ 443 if ( size > 0 ){ 444 flushRealTime = false; 445 } 446 bufferSize = size; 447 } 448 449 452 public int getBufferSize(){ 453 return bufferSize; 454 } 455 456 458 459 463 public void setAddDateStampToFirstAccessLogFile(boolean add) { 464 this.addDateStampToFirstAccessLogFile = add; 465 } 466 467 468 471 public String getDirectory() { 472 473 return (directory); 474 475 } 476 477 478 483 public void setDirectory(String directory) { 484 485 this.directory = directory; 486 487 } 488 489 490 493 public String getInfo() { 494 495 return (this.info); 496 497 } 498 499 500 503 public String getPattern() { 504 505 return (this.pattern); 506 507 } 508 509 510 515 public void setPattern(String p) { 516 this.pattern = p; 517 this.patternComponents = parsePattern(); 518 } 519 520 521 524 public String getPrefix() { 525 526 return (prefix); 527 528 } 529 530 531 536 public void setPrefix(String p) { 537 538 prefix = p; 539 540 if (prefix != null && suffix != null && prefix.endsWith(".") 541 && suffix.startsWith(".")) { 542 removeLeadingDotFromSuffix = true; 543 dotLessSuffix = suffix.substring(1); 544 } else { 545 removeLeadingDotFromSuffix = false; 546 } 547 } 548 549 550 553 public boolean isRotatable() { 554 555 return rotatable; 556 557 } 558 559 560 565 public void setRotatable(boolean rotatable) { 566 567 this.rotatable = rotatable; 568 569 } 570 571 572 575 public String getSuffix() { 576 577 return (suffix); 578 579 } 580 581 582 587 public void setSuffix(String s) { 588 589 suffix = s; 590 591 if (prefix != null && suffix != null && prefix.endsWith(".") 592 && suffix.startsWith(".")) { 593 removeLeadingDotFromSuffix = true; 594 dotLessSuffix = suffix.substring(1); 595 } else { 596 removeLeadingDotFromSuffix = false; 597 } 598 } 599 600 601 606 public void setResolveHosts(boolean resolveHosts) { 607 608 this.resolveHosts = resolveHosts; 609 610 } 611 612 613 616 public boolean isResolveHosts() { 617 618 return resolveHosts; 619 620 } 621 622 623 628 public String getCondition() { 629 630 return condition; 631 632 } 633 634 635 641 public void setCondition(String condition) { 642 643 this.condition = condition; 644 645 } 646 647 650 public String getFileDateFormat() { 651 return fileDateFormat; 652 } 653 654 655 658 public void setFileDateFormat(String fileDateFormat) { 659 this.fileDateFormat = fileDateFormat; 660 } 661 662 663 665 666 678 public int invoke(Request request, Response response) 679 throws IOException , ServletException { 680 return INVOKE_NEXT; 681 } 682 683 684 public synchronized void postInvoke(Request request, Response response){ 685 686 if (condition!=null && 687 null!=request.getRequest().getAttribute(condition)) { 688 return; 689 690 } 691 692 int lastPosition = charBuffer.position(); 693 694 if (charBuffer.position() == charBuffer.limit()){ 697 charBuffer.limit(charBuffer.capacity()); 698 } 699 700 boolean flushBuffer = !charBuffer.hasRemaining(); 701 702 if ( (chunkSize + charBuffer.position()) > charBuffer.limit()){ 704 flushBuffer = true; 705 } 706 707 if ( !flushBuffer ){ 708 709 try{ 710 createLogEntry(request, response, patternComponents); 711 chunkSize = charBuffer.position() - lastPosition; 714 } catch (BufferOverflowException ex ){ 715 flushBuffer = true; 719 charBuffer.position(lastPosition); 720 } 721 } 722 723 730 if ( flushBuffer || flushRealTime 731 || (charBuffer.position() - lastPosition > bufferSize)) { 732 log(); 733 } 734 735 if (flushBuffer) { 736 boolean expand = true; 739 while (expand) { 740 try { 741 createLogEntry(request, response, patternComponents); 742 expand = false; 743 log(); 744 } catch (BufferOverflowException ex) { 745 if (!flushRealTime) { 749 _logger.log( 750 Level.WARNING, 751 "peaccesslogvalve.bufferSizeTooSmall", 752 new Object [] { 753 Integer.toString(expandedBufferSize) }); 754 } 755 expandedBufferSize *= 2; 756 charBuffer = CharBuffer.allocate(expandedBufferSize); 757 } 758 } 759 } 760 761 } 762 763 764 766 767 private void createLogEntry(Request request, 768 Response response, 769 LinkedList <String > patternComponents) { 770 771 ServletRequest req = request.getRequest(); 772 HttpServletRequest hreq = (HttpServletRequest ) req; 773 774 for (int i=0; i<patternComponents.size(); i++) { 775 String pc = patternComponents.get(i); 776 if (AUTH_USER_NAME.equals(pc)) { 777 appendAuthUserName(charBuffer, hreq); 778 } else if (CLIENT_DNS.equals(pc)) { 779 appendClientDNS(charBuffer, req); 780 } else if (CLIENT_NAME.equals(pc)) { 781 appendClientName(charBuffer, req); 782 } else if (COOKIE_VALUE.equals(pc)) { 783 appendCookieValue(charBuffer, hreq); 784 } else if (DATE_TIME.equals(pc)) { 785 appendCurrentDate(charBuffer); 786 } else if (HEADER_ACCEPT.equals(pc)) { 787 appendHeaderAccept(charBuffer, hreq); 788 } else if (HEADER_AUTH.equals(pc)) { 789 appendHeaderAuth(charBuffer, hreq); 790 } else if (HEADER_DATE.equals(pc)) { 791 appendHeaderDate(charBuffer, hreq); 792 } else if (HEADER_IF_MOD_SINCE.equals(pc)) { 793 appendHeaderIfModSince(charBuffer, hreq); 794 } else if (HEADER_USER_AGENT.equals(pc)) { 795 appendUserAgent(charBuffer, hreq); 796 } else if (HEADER_REFERER.equals(pc)) { 797 appendReferer(charBuffer, hreq); 798 } else if (HTTP_METHOD.equals(pc)) { 799 appendHTTPMethod(charBuffer, hreq); 800 } else if (HTTP_URI.equals(pc)) { 801 appendHTTPUri(charBuffer, hreq); 802 } else if (HTTP_VERSION.equals(pc)) { 803 appendHTTPVersion(charBuffer, hreq); 804 } else if (QUERY_STR.equals(pc)) { 805 appendQueryString(charBuffer, hreq); 806 } else if (REFERER.equals(pc)) { 807 appendReferer(charBuffer, hreq); 808 } else if (REQUEST.equals(pc)) { 809 appendRequestInfo(charBuffer, hreq); 810 } else if (RESPONSE_LENGTH.equals(pc)) { 811 appendResponseLength(charBuffer, response); 812 } else if (STATUS.equals(pc)) { 813 appendResponseStatus(charBuffer, response); 814 } else if (USER_AGENT.equals(pc)) { 815 appendUserAgent(charBuffer, hreq); 816 } else if (VS_ID.equals(pc)) { 817 appendVirtualServerId(charBuffer); 818 } else if (pc.startsWith(HEADER_ANY)) { 819 appendHeaderAny(charBuffer, pc.substring(HEADER_ANY_LEN), 820 hreq); 821 } 822 823 charBuffer.put(space); 824 } 825 826 charBuffer.put("\n"); 827 } 828 829 830 836 private LinkedList <String > parsePattern() { 837 838 LinkedList list = new LinkedList (); 839 840 int from = 0; 841 int end = -1; 842 int index = -1; 843 while ((index = pattern.indexOf('%', from)) >= 0) { 844 end = pattern.indexOf('%', index+1); 845 if (end < 0) { 846 _logger.log( 847 Level.SEVERE, 848 "peaccesslogvalve.missingAccessLogPatternEndDelimiter", 849 pattern); 850 } 851 String component = pattern.substring(index+1, end); 852 853 if (!AUTH_USER_NAME.equals(component) 854 && !CLIENT_DNS.equals(component) 855 && !CLIENT_NAME.equals(component) 856 && !COOKIE_VALUE.equals(component) 857 && !DATE_TIME.equals(component) 858 && !HEADER_ACCEPT.equals(component) 859 && !HEADER_AUTH.equals(component) 860 && !HEADER_DATE.equals(component) 861 && !HEADER_IF_MOD_SINCE.equals(component) 862 && !HEADER_USER_AGENT.equals(component) 863 && !HEADER_REFERER.equals(component) 864 && !HTTP_METHOD.equals(component) 865 && !HTTP_URI.equals(component) 866 && !HTTP_VERSION.equals(component) 867 && !QUERY_STR.equals(component) 868 && !REFERER.equals(component) 869 && !REQUEST.equals(component) 870 && !RESPONSE_LENGTH.equals(component) 871 && !STATUS.equals(component) 872 && !USER_AGENT.equals(component) 873 && !VS_ID.equals(component) 874 && !component.startsWith(HEADER_ANY)) { 875 _logger.log( 876 Level.SEVERE, 877 "peaccesslogvalve.invalidAccessLogPatternComponent", 878 new Object [] { component, pattern }); 879 } 880 881 list.add(component); 882 from = end + 1; 883 } 884 885 return list; 886 } 887 888 889 893 private void appendClientName(CharBuffer cb, ServletRequest req) { 894 cb.put("\""); 895 String value = req.getRemoteHost(); 896 if (value == null) { 897 value = "NULL-CLIENT-NAME"; 898 } 899 cb.put(value); 900 cb.put("\""); 901 } 902 903 904 908 private void appendClientDNS(CharBuffer cb, ServletRequest req) { 909 cb.put("\""); 910 String value = req.getRemoteAddr(); 911 if (value == null) { 912 value = "NULL-CLIENT-DNS"; 913 } 914 cb.put(value); 915 cb.put("\""); 916 } 917 918 919 922 private void appendAuthUserName(CharBuffer cb, HttpServletRequest hreq) { 923 cb.put("\""); 924 String user = hreq.getRemoteUser(); 925 if (user == null) { 926 user = "NULL-AUTH-USER"; 927 } 928 cb.put(user); 929 cb.put("\""); 930 } 931 932 933 936 private void appendCurrentDate(CharBuffer cb) { 937 cb.put("\""); 938 Date date = getDate(); 939 cb.put(dayFormatter.format(date)); cb.put('/'); 941 cb.put(lookup(monthFormatter.format(date))); cb.put('/'); 943 cb.put(yearFormatter.format(date)); cb.put(':'); 945 cb.put(timeFormatter.format(date)); cb.put(space); 947 cb.put(timeZone); cb.put("\""); 949 } 950 951 952 955 private void appendRequestInfo(CharBuffer cb, HttpServletRequest hreq) { 956 cb.put("\""); 957 cb.put(hreq.getMethod()); 958 cb.put(space); 959 cb.put(hreq.getRequestURI()); 960 if (hreq.getQueryString() != null) { 961 cb.put('?'); 962 cb.put(hreq.getQueryString()); 963 } 964 cb.put(space); 965 cb.put(hreq.getProtocol()); 966 cb.put("\""); 967 } 968 969 970 973 private void appendResponseStatus(CharBuffer cb, Response response) { 974 cb.put(String.valueOf(((HttpResponse) response).getStatus())); 975 } 976 977 978 982 private void appendResponseLength(CharBuffer cb, Response response) { 983 cb.put("" + response.getContentCount()); 984 } 985 986 987 991 private void appendUserAgent(CharBuffer cb, HttpServletRequest hreq) { 992 cb.put("\""); 993 String ua = hreq.getHeader("user-agent"); 994 if (ua == null) { 995 ua = "NULL-USER-AGENT"; 996 } 997 cb.put(ua); 998 cb.put("\""); 999 } 1000 1001 1002 1006 private void appendReferer(CharBuffer cb, HttpServletRequest hreq) { 1007 cb.put("\""); 1008 String referer = hreq.getHeader("referer"); 1009 if (referer == null) { 1010 referer = "NULL-REFERER"; 1011 } 1012 cb.put(referer); 1013 cb.put("\""); 1014 } 1015 1016 1017 1021 private void appendHeaderAccept(CharBuffer cb, HttpServletRequest hreq) { 1022 cb.put("\""); 1023 String accept = hreq.getHeader(HTTP_HEADER_ACCEPT); 1024 if (accept == null) { 1025 accept = "NULL-HEADER-ACCEPT"; 1026 } 1027 cb.put(accept); 1028 cb.put("\""); 1029 } 1030 1031 1032 1036 private void appendHeaderAuth(CharBuffer cb, HttpServletRequest hreq) { 1037 cb.put("\""); 1038 String auth = hreq.getHeader(HTTP_HEADER_AUTHORIZATION); 1039 if (auth == null) { 1040 auth = "NULL-HEADER-AUTHORIZATION"; 1041 } 1042 cb.put(auth); 1043 cb.put("\""); 1044 } 1045 1046 1047 1050 private void appendHeaderDate(CharBuffer cb, HttpServletRequest hreq) { 1051 cb.put("\""); 1052 String date = hreq.getHeader(HTTP_HEADER_DATE); 1053 if (date == null) { 1054 date = "NULL-HEADER-DATE"; 1055 } 1056 cb.put(date); 1057 cb.put("\""); 1058 } 1059 1060 1061 1065 private void appendHeaderIfModSince(CharBuffer cb, 1066 HttpServletRequest hreq) { 1067 cb.put("\""); 1068 String ifModSince = hreq.getHeader(HTTP_HEADER_IF_MODIFIED_SINCE); 1069 if (ifModSince == null) { 1070 ifModSince = "NULL-HEADER-IF-MODIFIED-SINCE"; 1071 } 1072 cb.put(ifModSince); 1073 cb.put("\""); 1074 } 1075 1076 1077 1081 private void appendHeaderAny(CharBuffer cb, 1082 String headerName, 1083 HttpServletRequest hreq) { 1084 cb.put("\""); 1085 String value = hreq.getHeader(headerName); 1086 if (value == null) { 1087 value = "NULL-HEADER-" + headerName.toUpperCase(); 1088 } 1089 cb.put(value); 1090 cb.put("\""); 1091 } 1092 1093 1094 1098 private void appendCookieValue(CharBuffer cb, HttpServletRequest hreq) { 1099 cb.put("\""); 1100 String cookieValue = "NULL-COOKIE-VALUE"; 1101 Cookie [] cookies = hreq.getCookies(); 1102 if (cookies != null && cookies.length > 0) { 1103 cookieValue = cookies[0].getValue(); 1104 } 1105 cb.put(cookieValue); 1106 cb.put("\""); 1107 } 1108 1109 1110 1113 private void appendHTTPMethod(CharBuffer cb, HttpServletRequest hreq) { 1114 cb.put("\""); 1115 String method = hreq.getMethod(); 1116 if (method == null) { 1117 method = "NULL-HTTP-METHOD"; 1118 } 1119 cb.put(method); 1120 cb.put("\""); 1121 } 1122 1123 1124 1127 private void appendHTTPUri(CharBuffer cb, HttpServletRequest hreq) { 1128 cb.put("\""); 1129 String uri = hreq.getRequestURI(); 1130 if (uri == null) { 1131 uri = "NULL-HTTP-URI"; 1132 } 1133 cb.put(uri); 1134 cb.put("\""); 1135 } 1136 1137 1138 1142 private void appendHTTPVersion(CharBuffer cb, HttpServletRequest hreq) { 1143 cb.put("\""); 1144 String protocol = hreq.getProtocol(); 1145 if (protocol == null) { 1146 protocol = "NULL-HTTP-PROTOCOL"; 1147 } 1148 cb.put(protocol); 1149 cb.put("\""); 1150 } 1151 1152 1153 1156 private void appendQueryString(CharBuffer cb, HttpServletRequest hreq) { 1157 cb.put("\""); 1158 String query = hreq.getQueryString(); 1159 if (query == null) { 1160 query = "NULL-QUERY"; 1161 } 1162 cb.put(query); 1163 cb.put("\""); 1164 } 1165 1166 1167 1171 private void appendVirtualServerId(CharBuffer cb) { 1172 String vsId = "NULL-VIRTUAL-SERVER"; 1173 Container cont = getContainer(); 1174 if (cont != null) { 1175 vsId = cont.getName(); 1176 } 1177 cb.put(vsId); 1178 } 1179 1180 1181 1184 private synchronized void close() { 1185 1186 try{ 1187 log(); 1189 fileChannel.close(); 1190 fos.close(); 1191 } catch (IOException ex){ 1192 ; 1193 } 1194 } 1195 1196 1197 1205 public void log() { 1206 1207 if (rotatable){ 1208 1209 long systime = System.currentTimeMillis(); 1210 if ((systime-lastAccessLogCreationTime) > (rotationInterval*1000)) { 1211 synchronized (this) { 1212 systime = System.currentTimeMillis(); 1213 if ((systime-lastAccessLogCreationTime) > 1214 (rotationInterval*1000)) { 1215 1216 String lastDateStamp = dateFormatter.format( 1219 new Date (lastAccessLogCreationTime)); 1220 String newDateStamp = dateFormatter.format( 1221 new Date (systime)); 1222 1223 lastAccessLogCreationTime = systime; 1224 1225 if (!lastDateStamp.equals(newDateStamp)) { 1226 close(); 1227 open(newDateStamp, false); 1228 } 1229 } 1230 } 1231 } 1232 } 1233 1234 try{ 1235 charBuffer.flip(); 1236 ByteBuffer byteBuffer = 1237 ByteBuffer.wrap(charBuffer.toString().getBytes()); 1238 while (byteBuffer.hasRemaining()){ 1239 fileChannel.write(byteBuffer); 1240 } 1241 charBuffer.clear(); 1242 } catch (IOException ex){ 1243 ; 1244 } 1245 1246 } 1247 1248 1249 1255 private String lookup(String month) { 1256 1257 int index; 1258 try { 1259 index = Integer.parseInt(month) - 1; 1260 } catch (Throwable t) { 1261 index = 0; } 1263 return (months[index]); 1264 1265 } 1266 1267 1268 1276 private synchronized void open(String dateStamp, 1277 boolean firstAccessLogFile) { 1278 1279 File dir = new File (directory); 1281 if (!dir.isAbsolute()) 1282 dir = new File (System.getProperty("catalina.base"), directory); 1283 dir.mkdirs(); 1284 1285 try { 1287 String pathname; 1288 if (rotatable && addDateStampToFirstAccessLogFile) { 1290 pathname = dir.getAbsolutePath() + File.separator + 1291 prefix + dateStamp + suffix; 1292 } else { 1293 if (removeLeadingDotFromSuffix) { 1294 pathname = dir.getAbsolutePath() + File.separator + 1295 prefix + dotLessSuffix; 1296 } else { 1297 pathname = dir.getAbsolutePath() + File.separator + 1298 prefix + suffix; 1299 } 1300 } 1301 1302 if (rotatable 1303 && !addDateStampToFirstAccessLogFile 1304 && !firstAccessLogFile) { 1305 String dateStampedPathname = dir.getAbsolutePath() 1308 + File.separator 1309 + prefix + dateStamp + suffix; 1310 File renameToFile = new File (dateStampedPathname); 1311 if (!logFile.renameTo(renameToFile)) { 1312 _logger.log( 1313 Level.WARNING, 1314 "peaccesslogvalve.unableToRenameLogFile", 1315 new Object [] { 1316 logFile.toString(), dateStampedPathname }); 1317 } 1318 File removeFile = null; 1319 if (deleteAllHistoryFiles) { 1320 removeFile = renameToFile; 1321 } else { 1322 if (historyFiles != null) { 1323 historyFiles.addLast(renameToFile); 1324 if (historyFiles.size() > maxHistoryFiles) { 1325 removeFile = historyFiles.removeFirst(); 1326 } 1327 } 1328 } 1329 if (removeFile != null && !removeFile.delete()) { 1330 _logger.log(Level.WARNING, 1331 "peaccesslogvalve.unableToRemoveLogFile", 1332 removeFile.toString()); 1333 } 1334 } 1335 1336 logFile = new File (pathname); 1338 fos = new FileOutputStream (logFile, true); 1339 fileChannel = fos.getChannel(); 1340 1341 } catch (IOException e) { 1342 try{ 1343 if ( fileChannel != null ) 1344 fileChannel.close(); 1345 } catch (IOException ex){ 1346 ; 1347 } 1348 } 1349 1350 } 1351 1352 1353 1360 private synchronized Date getDate() { 1361 1362 long systime = System.currentTimeMillis(); 1364 if ((systime - currentDate.getTime()) > 5000) { 1365 currentDate = new Date (systime); 1366 } 1367 1368 return currentDate; 1369 1370 } 1371 1372 1373 private String calculateTimeZoneOffset(long offset) { 1374 StringBuffer tz = new StringBuffer (); 1375 if ((offset<0)) { 1376 tz.append("-"); 1377 offset = -offset; 1378 } else { 1379 tz.append("+"); 1380 } 1381 1382 long hourOffset = offset/(1000*60*60); 1383 long minuteOffset = (offset/(1000*60)) % 60; 1384 1385 if (hourOffset<10) 1386 tz.append("0"); 1387 tz.append(hourOffset); 1388 1389 if (minuteOffset<10) 1390 tz.append("0"); 1391 tz.append(minuteOffset); 1392 1393 return tz.toString(); 1394 } 1395 1396 1397 1399 1400 1405 public void addLifecycleListener(LifecycleListener listener) { 1406 1407 lifecycle.addLifecycleListener(listener); 1408 1409 } 1410 1411 1412 1416 public LifecycleListener[] findLifecycleListeners() { 1417 1418 return lifecycle.findLifecycleListeners(); 1419 1420 } 1421 1422 1423 1428 public void removeLifecycleListener(LifecycleListener listener) { 1429 1430 lifecycle.removeLifecycleListener(listener); 1431 1432 } 1433 1434 1435 1443 public void start() throws LifecycleException { 1444 1445 if (started) { 1447 throw new LifecycleException 1448 (sm.getString("accessLogValve.alreadyStarted")); 1449 } 1450 1451 lifecycle.fireLifecycleEvent(START_EVENT, null); 1452 started = true; 1453 1454 deleteAllHistoryFiles = false; 1455 historyFiles = null; 1456 String prop = System.getProperty(LOGGING_MAX_HISTORY_FILES); 1457 if (prop != null) { 1458 maxHistoryFiles = 10; 1459 if (!"".equals(prop)) { 1460 try { 1461 maxHistoryFiles = Integer.parseInt(prop); 1462 } catch (NumberFormatException e) {}; 1463 } 1464 if (maxHistoryFiles == 0) { 1465 deleteAllHistoryFiles = true; 1466 } else if (maxHistoryFiles > 0) { 1467 historyFiles = new LinkedList <File >(); 1468 } 1469 } 1470 1471 expandedBufferSize = bufferSize; 1472 if (bufferSize <= 0) { 1473 expandedBufferSize = 1; 1476 } 1477 1478 charBuffer = CharBuffer.allocate(expandedBufferSize); 1479 1480 TimeZone tz = TimeZone.getDefault(); 1482 timeZone = calculateTimeZoneOffset(tz.getRawOffset()); 1483 1484 if (fileDateFormat==null || fileDateFormat.length()==0) 1485 fileDateFormat = "yyyy-MM-dd"; 1486 dateFormatter = new SimpleDateFormat (fileDateFormat); 1487 dateFormatter.setTimeZone(tz); 1488 dayFormatter = new SimpleDateFormat ("dd"); 1489 dayFormatter.setTimeZone(tz); 1490 monthFormatter = new SimpleDateFormat ("MM"); 1491 monthFormatter.setTimeZone(tz); 1492 yearFormatter = new SimpleDateFormat ("yyyy"); 1493 yearFormatter.setTimeZone(tz); 1494 timeFormatter = new SimpleDateFormat ("HH:mm:ss"); 1495 timeFormatter.setTimeZone(tz); 1496 1497 long systime = System.currentTimeMillis(); 1498 currentDate = new Date (systime); 1499 open(dateFormatter.format(currentDate), true); 1500 lastAccessLogCreationTime = systime; 1501 1502 if (!flushRealTime){ 1503 threadStart(); 1505 } 1506 } 1507 1508 1509 1517 public void stop() throws LifecycleException { 1518 1519 if (!started) 1521 throw new LifecycleException 1522 (sm.getString("accessLogValve.notStarted")); 1523 lifecycle.fireLifecycleEvent(STOP_EVENT, null); 1524 started = false; 1525 1526 if (!flushRealTime){ 1527 threadStop(); 1529 } 1530 1531 close(); 1532 1533 } 1534 1535 1536 1539 public void run() { 1540 1541 while (!threadDone) { 1543 threadSleep(); 1544 log(); 1545 } 1546 1547 } 1548 1549 1550 1554 private void threadSleep() { 1555 1556 try { 1557 writerThread.sleep(writeInterval * 1000L); 1558 } catch (InterruptedException e) { 1559 ; 1560 } 1561 1562 } 1563 1564 1565 1568 private void threadStart() { 1569 1570 if (writerThread != null) 1571 return; 1572 1573 threadDone = false; 1574 String threadName = "AccessLogWriter"; 1575 writerThread = new Thread (this, threadName); 1576 writerThread.setDaemon(true); 1577 writerThread.start(); 1578 1579 } 1580 1581 1582 1585 private void threadStop() { 1586 1587 if (writerThread == null) 1588 return; 1589 1590 threadDone = true; 1591 writerThread.interrupt(); 1592 try { 1593 writerThread.join(); 1594 } catch (InterruptedException e) { 1595 ; 1596 } 1597 1598 writerThread = null; 1599 1600 } 1601} 1602 | Popular Tags |