001: /*
002: * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: */
007: package winstone.accesslog;
008:
009: import java.io.File;
010: import java.io.FileOutputStream;
011: import java.io.IOException;
012: import java.io.OutputStream;
013: import java.io.PrintWriter;
014: import java.text.DateFormat;
015: import java.text.SimpleDateFormat;
016: import java.util.Date;
017: import java.util.Map;
018:
019: import winstone.AccessLogger;
020: import winstone.Logger;
021: import winstone.WebAppConfiguration;
022: import winstone.WinstoneRequest;
023: import winstone.WinstoneResourceBundle;
024: import winstone.WinstoneResponse;
025:
026: /**
027: * Simulates an apache "combined" style logger, which logs User-Agent, Referer, etc
028: *
029: * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
030: * @version $Id: SimpleAccessLogger.java,v 1.5 2006/03/24 17:24:19 rickknowles Exp $
031: */
032: public class SimpleAccessLogger implements AccessLogger {
033:
034: public static final WinstoneResourceBundle ACCESSLOG_RESOURCES = new WinstoneResourceBundle(
035: "winstone.accesslog.LocalStrings");
036:
037: private static final DateFormat DF = new SimpleDateFormat(
038: "dd/MMM/yyyy:HH:mm:ss Z");
039: private static final String COMMON = "###ip### - ###user### ###time### \"###uriLine###\" ###status### ###size###";
040: private static final String COMBINED = COMMON
041: + " \"###referer###\" \"###userAgent###\"";
042: private static final String RESIN = COMMON + " \"###userAgent###\"";
043:
044: // private WebAppConfiguration webAppConfig;
045: private OutputStream outStream;
046: private PrintWriter outWriter;
047: private String pattern;
048: private String fileName;
049:
050: public SimpleAccessLogger(WebAppConfiguration webAppConfig,
051: Map startupArgs) throws IOException {
052: // this.webAppConfig = webAppConfig;
053:
054: // Get pattern
055: String patternType = WebAppConfiguration.stringArg(startupArgs,
056: "simpleAccessLogger.format", "combined");
057: if (patternType.equalsIgnoreCase("combined")) {
058: this .pattern = COMBINED;
059: } else if (patternType.equalsIgnoreCase("common")) {
060: this .pattern = COMMON;
061: } else if (patternType.equalsIgnoreCase("resin")) {
062: this .pattern = RESIN;
063: } else {
064: this .pattern = patternType;
065: }
066:
067: // Get filename
068: String filePattern = WebAppConfiguration.stringArg(startupArgs,
069: "simpleAccessLogger.file",
070: "logs/###host###/###webapp###_access.log");
071: this .fileName = WinstoneResourceBundle
072: .globalReplace(
073: filePattern,
074: new String[][] {
075: { "###host###",
076: webAppConfig.getOwnerHostname() },
077: { "###webapp###",
078: webAppConfig.getContextName() } });
079:
080: File file = new File(this .fileName);
081: file.getParentFile().mkdirs();
082: this .outStream = new FileOutputStream(file, true);
083: this .outWriter = new PrintWriter(this .outStream, true);
084:
085: Logger.log(Logger.DEBUG, ACCESSLOG_RESOURCES,
086: "SimpleAccessLogger.Init", new String[] {
087: this .fileName, patternType });
088: }
089:
090: public void log(String originalURL, WinstoneRequest request,
091: WinstoneResponse response) {
092: String uriLine = request.getMethod() + " " + originalURL + " "
093: + request.getProtocol();
094: int status = response.getErrorStatusCode() == null ? response
095: .getStatus() : response.getErrorStatusCode().intValue();
096: int size = response.getWinstoneOutputStream()
097: .getBytesCommitted();
098: String date = null;
099: synchronized (DF) {
100: date = DF.format(new Date());
101: }
102: String logLine = WinstoneResourceBundle
103: .globalReplace(
104: this .pattern,
105: new String[][] {
106: { "###ip###", request.getRemoteHost() },
107: { "###user###",
108: nvl(request.getRemoteUser()) },
109: { "###time###", "[" + date + "]" },
110: { "###uriLine###", uriLine },
111: { "###status###", "" + status },
112: { "###size###", "" + size },
113: {
114: "###referer###",
115: nvl(request
116: .getHeader("Referer")) },
117: {
118: "###userAgent###",
119: nvl(request
120: .getHeader("User-Agent")) } });
121: this .outWriter.println(logLine);
122: }
123:
124: private static String nvl(String input) {
125: return input == null ? "-" : input;
126: }
127:
128: public void destroy() {
129: Logger.log(Logger.DEBUG, ACCESSLOG_RESOURCES,
130: "SimpleAccessLogger.Close", this .fileName);
131: if (this .outWriter != null) {
132: this .outWriter.flush();
133: this .outWriter.close();
134: this .outWriter = null;
135: }
136: if (this .outStream != null) {
137: try {
138: this .outStream.close();
139: } catch (IOException err) {
140: }
141: this .outStream = null;
142: }
143: this .fileName = null;
144: // this.webAppConfig = null;
145: }
146: }
|