| 1 7 package winstone.accesslog; 8 9 import java.io.File ; 10 import java.io.FileOutputStream ; 11 import java.io.IOException ; 12 import java.io.OutputStream ; 13 import java.io.PrintWriter ; 14 import java.text.DateFormat ; 15 import java.text.SimpleDateFormat ; 16 import java.util.Date ; 17 import java.util.Map ; 18 19 import winstone.AccessLogger; 20 import winstone.Logger; 21 import winstone.WebAppConfiguration; 22 import winstone.WinstoneRequest; 23 import winstone.WinstoneResourceBundle; 24 import winstone.WinstoneResponse; 25 26 32 public class SimpleAccessLogger implements AccessLogger { 33 34 public static final WinstoneResourceBundle ACCESSLOG_RESOURCES = 35 new WinstoneResourceBundle("winstone.accesslog.LocalStrings"); 36 37 private static final DateFormat DF = new SimpleDateFormat ("dd/MMM/yyyy:HH:mm:ss Z"); 38 private static final String COMMON = "###ip### - ###user### ###time### \"###uriLine###\" ###status### ###size###"; 39 private static final String COMBINED = COMMON + " \"###referer###\" \"###userAgent###\""; 40 private static final String RESIN = COMMON + " \"###userAgent###\""; 41 42 private OutputStream outStream; 44 private PrintWriter outWriter; 45 private String pattern; 46 private String fileName; 47 48 public SimpleAccessLogger(WebAppConfiguration webAppConfig, Map startupArgs) 49 throws IOException { 50 52 String patternType = WebAppConfiguration.stringArg(startupArgs, "simpleAccessLogger.format", "combined"); 54 if (patternType.equalsIgnoreCase("combined")) { 55 this.pattern = COMBINED; 56 } else if (patternType.equalsIgnoreCase("common")) { 57 this.pattern = COMMON; 58 } else if (patternType.equalsIgnoreCase("resin")) { 59 this.pattern = RESIN; 60 } else { 61 this.pattern = patternType; 62 } 63 64 String filePattern = WebAppConfiguration.stringArg(startupArgs, "simpleAccessLogger.file", 66 "logs/###host###/###webapp###_access.log"); 67 this.fileName = WinstoneResourceBundle.globalReplace(filePattern, 68 new String [][] {{"###host###", webAppConfig.getOwnerHostname()}, 69 {"###webapp###", webAppConfig.getContextName()}}); 70 71 File file = new File (this.fileName); 72 file.getParentFile().mkdirs(); 73 this.outStream = new FileOutputStream (file, true); 74 this.outWriter = new PrintWriter (this.outStream, true); 75 76 Logger.log(Logger.DEBUG, ACCESSLOG_RESOURCES, "SimpleAccessLogger.Init", 77 new String [] {this.fileName, patternType}); 78 } 79 80 public void log(String originalURL, WinstoneRequest request, WinstoneResponse response) { 81 String uriLine = request.getMethod() + " " + originalURL + " " + request.getProtocol(); 82 int status = response.getErrorStatusCode() == null ? response.getStatus() 83 : response.getErrorStatusCode().intValue(); 84 int size = response.getWinstoneOutputStream().getBytesCommitted(); 85 String date = null; 86 synchronized (DF) { 87 date = DF.format(new Date ()); 88 } 89 String logLine = WinstoneResourceBundle.globalReplace(this.pattern, new String [][] { 90 {"###ip###", request.getRemoteHost()}, 91 {"###user###", nvl(request.getRemoteUser())}, 92 {"###time###", "[" + date + "]"}, 93 {"###uriLine###", uriLine}, 94 {"###status###", "" + status}, 95 {"###size###", "" + size}, 96 {"###referer###", nvl(request.getHeader("Referer"))}, 97 {"###userAgent###", nvl(request.getHeader("User-Agent"))} 98 }); 99 this.outWriter.println(logLine); 100 } 101 102 private static String nvl(String input) { 103 return input == null ? "-" : input; 104 } 105 106 public void destroy() { 107 Logger.log(Logger.DEBUG, ACCESSLOG_RESOURCES, "SimpleAccessLogger.Close", this.fileName); 108 if (this.outWriter != null) { 109 this.outWriter.flush(); 110 this.outWriter.close(); 111 this.outWriter = null; 112 } 113 if (this.outStream != null) { 114 try { 115 this.outStream.close(); 116 } catch (IOException err) {} 117 this.outStream = null; 118 } 119 this.fileName = null; 120 } 122 } 123 | Popular Tags |