]> WPIA git - gigi.git/blobdiff - lib/jetty/org/eclipse/jetty/server/AbstractNCSARequestLog.java
Importing upstream Jetty jetty-9.2.1.v20140609
[gigi.git] / lib / jetty / org / eclipse / jetty / server / AbstractNCSARequestLog.java
diff --git a/lib/jetty/org/eclipse/jetty/server/AbstractNCSARequestLog.java b/lib/jetty/org/eclipse/jetty/server/AbstractNCSARequestLog.java
new file mode 100644 (file)
index 0000000..dcaecbe
--- /dev/null
@@ -0,0 +1,483 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+package org.eclipse.jetty.server;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import javax.servlet.http.Cookie;
+
+import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.http.PathMap;
+import org.eclipse.jetty.server.handler.StatisticsHandler;
+import org.eclipse.jetty.util.DateCache;
+import org.eclipse.jetty.util.annotation.ManagedAttribute;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ * Base implementation of the {@link RequestLog} outputs logs in the pseudo-standard NCSA common log format.
+ * Configuration options allow a choice between the standard Common Log Format (as used in the 3 log format) and the
+ * Combined Log Format (single log format). This log format can be output by most web servers, and almost all web log
+ * analysis software can understand these formats.
+ */
+public abstract class AbstractNCSARequestLog extends AbstractLifeCycle implements RequestLog
+{
+    protected static final Logger LOG = Log.getLogger(AbstractNCSARequestLog.class);
+
+    private static ThreadLocal<StringBuilder> _buffers = new ThreadLocal<StringBuilder>()
+    {
+        @Override
+        protected StringBuilder initialValue()
+        {
+            return new StringBuilder(256);
+        }
+    };
+
+
+    private String[] _ignorePaths;
+    private boolean _extended;
+    private transient PathMap<String> _ignorePathMap;
+    private boolean _logLatency = false;
+    private boolean _logCookies = false;
+    private boolean _logServer = false;
+    private boolean _preferProxiedForAddress;
+    private transient DateCache _logDateCache;
+    private String _logDateFormat = "dd/MMM/yyyy:HH:mm:ss Z";
+    private Locale _logLocale = Locale.getDefault();
+    private String _logTimeZone = "GMT";
+
+    /* ------------------------------------------------------------ */
+
+    /**
+     * Is logging enabled
+     */
+    protected abstract boolean isEnabled();
+    
+    /* ------------------------------------------------------------ */
+
+    /**
+     * Write requestEntry out. (to disk or slf4j log)
+     */
+    public abstract void write(String requestEntry) throws IOException;
+
+    /* ------------------------------------------------------------ */
+
+    /**
+     * Writes the request and response information to the output stream.
+     *
+     * @see org.eclipse.jetty.server.RequestLog#log(org.eclipse.jetty.server.Request,
+     *      org.eclipse.jetty.server.Response)
+     */
+    @Override
+    public void log(Request request, Response response)
+    {
+        try
+        {
+            if (_ignorePathMap != null && _ignorePathMap.getMatch(request.getRequestURI()) != null)
+                return;
+
+            if (!isEnabled())
+                return;
+
+            StringBuilder buf = _buffers.get();
+            buf.setLength(0);
+
+            if (_logServer)
+            {
+                buf.append(request.getServerName());
+                buf.append(' ');
+            }
+
+            String addr = null;
+            if (_preferProxiedForAddress)
+            {
+                addr = request.getHeader(HttpHeader.X_FORWARDED_FOR.toString());
+            }
+
+            if (addr == null)
+                addr = request.getRemoteAddr();
+
+            buf.append(addr);
+            buf.append(" - ");
+            Authentication authentication = request.getAuthentication();
+            if (authentication instanceof Authentication.User)
+                buf.append(((Authentication.User)authentication).getUserIdentity().getUserPrincipal().getName());
+            else
+                buf.append(" - ");
+
+            buf.append(" [");
+            if (_logDateCache != null)
+                buf.append(_logDateCache.format(request.getTimeStamp()));
+            else
+                buf.append(request.getTimeStamp());
+
+            buf.append("] \"");
+            buf.append(request.getMethod());
+            buf.append(' ');
+            buf.append(request.getUri().toString());
+            buf.append(' ');
+            buf.append(request.getProtocol());
+            buf.append("\" ");
+
+            int status = response.getStatus();
+            if (status <= 0)
+                status = 404;
+            buf.append((char)('0' + ((status / 100) % 10)));
+            buf.append((char)('0' + ((status / 10) % 10)));
+            buf.append((char)('0' + (status % 10)));
+
+            long responseLength = response.getLongContentLength();
+            if (responseLength >= 0)
+            {
+                buf.append(' ');
+                if (responseLength > 99999)
+                    buf.append(responseLength);
+                else
+                {
+                    if (responseLength > 9999)
+                        buf.append((char)('0' + ((responseLength / 10000) % 10)));
+                    if (responseLength > 999)
+                        buf.append((char)('0' + ((responseLength / 1000) % 10)));
+                    if (responseLength > 99)
+                        buf.append((char)('0' + ((responseLength / 100) % 10)));
+                    if (responseLength > 9)
+                        buf.append((char)('0' + ((responseLength / 10) % 10)));
+                    buf.append((char)('0' + (responseLength) % 10));
+                }
+                buf.append(' ');
+            }
+            else
+                buf.append(" - ");
+
+
+            if (_extended)
+                logExtended(request, response, buf);
+
+            if (_logCookies)
+            {
+                Cookie[] cookies = request.getCookies();
+                if (cookies == null || cookies.length == 0)
+                    buf.append(" -");
+                else
+                {
+                    buf.append(" \"");
+                    for (int i = 0; i < cookies.length; i++)
+                    {
+                        if (i != 0)
+                            buf.append(';');
+                        buf.append(cookies[i].getName());
+                        buf.append('=');
+                        buf.append(cookies[i].getValue());
+                    }
+                    buf.append('\"');
+                }
+            }
+
+            if (_logLatency)
+            {
+                long now = System.currentTimeMillis();
+
+                if (_logLatency)
+                {
+                    buf.append(' ');
+                    buf.append(now - request.getTimeStamp());
+                }
+            }
+
+            String log = buf.toString();
+            write(log);
+        }
+        catch (IOException e)
+        {
+            LOG.warn(e);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+
+    /**
+     * Writes extended request and response information to the output stream.
+     *
+     * @param request  request object
+     * @param response response object
+     * @param b        StringBuilder to write to
+     * @throws IOException
+     */
+    protected void logExtended(Request request,
+                               Response response,
+                               StringBuilder b) throws IOException
+    {
+        String referer = request.getHeader(HttpHeader.REFERER.toString());
+        if (referer == null)
+            b.append("\"-\" ");
+        else
+        {
+            b.append('"');
+            b.append(referer);
+            b.append("\" ");
+        }
+
+        String agent = request.getHeader(HttpHeader.USER_AGENT.toString());
+        if (agent == null)
+            b.append("\"-\" ");
+        else
+        {
+            b.append('"');
+            b.append(agent);
+            b.append('"');
+        }
+    }
+
+
+    /**
+     * Set request paths that will not be logged.
+     *
+     * @param ignorePaths array of request paths
+     */
+    public void setIgnorePaths(String[] ignorePaths)
+    {
+        _ignorePaths = ignorePaths;
+    }
+
+    /**
+     * Retrieve the request paths that will not be logged.
+     *
+     * @return array of request paths
+     */
+    public String[] getIgnorePaths()
+    {
+        return _ignorePaths;
+    }
+
+    /**
+     * Controls logging of the request cookies.
+     *
+     * @param logCookies true - values of request cookies will be logged, false - values of request cookies will not be
+     *                   logged
+     */
+    public void setLogCookies(boolean logCookies)
+    {
+        _logCookies = logCookies;
+    }
+
+    /**
+     * Retrieve log cookies flag
+     *
+     * @return value of the flag
+     */
+    public boolean getLogCookies()
+    {
+        return _logCookies;
+    }
+
+    /**
+     * Controls logging of the request hostname.
+     *
+     * @param logServer true - request hostname will be logged, false - request hostname will not be logged
+     */
+    public void setLogServer(boolean logServer)
+    {
+        _logServer = logServer;
+    }
+
+    /**
+     * Retrieve log hostname flag.
+     *
+     * @return value of the flag
+     */
+    public boolean getLogServer()
+    {
+        return _logServer;
+    }
+
+    /**
+     * Controls logging of request processing time.
+     *
+     * @param logLatency true - request processing time will be logged false - request processing time will not be
+     *                   logged
+     */
+    public void setLogLatency(boolean logLatency)
+    {
+        _logLatency = logLatency;
+    }
+
+    /**
+     * Retrieve log request processing time flag.
+     *
+     * @return value of the flag
+     */
+    public boolean getLogLatency()
+    {
+        return _logLatency;
+    }
+
+    /**
+     * @deprecated use {@link StatisticsHandler}
+     */
+    public void setLogDispatch(boolean value)
+    {
+    }
+
+    /**
+     * @deprecated use {@link StatisticsHandler}
+     */
+    public boolean isLogDispatch()
+    {
+        return false;
+    }
+
+    /**
+     * Controls whether the actual IP address of the connection or the IP address from the X-Forwarded-For header will
+     * be logged.
+     *
+     * @param preferProxiedForAddress true - IP address from header will be logged, false - IP address from the
+     *                                connection will be logged
+     */
+    public void setPreferProxiedForAddress(boolean preferProxiedForAddress)
+    {
+        _preferProxiedForAddress = preferProxiedForAddress;
+    }
+
+    /**
+     * Retrieved log X-Forwarded-For IP address flag.
+     *
+     * @return value of the flag
+     */
+    public boolean getPreferProxiedForAddress()
+    {
+        return _preferProxiedForAddress;
+    }
+
+    /**
+     * Set the extended request log format flag.
+     *
+     * @param extended true - log the extended request information, false - do not log the extended request information
+     */
+    public void setExtended(boolean extended)
+    {
+        _extended = extended;
+    }
+
+    /**
+     * Retrieve the extended request log format flag.
+     *
+     * @return value of the flag
+     */
+    @ManagedAttribute("use extended NCSA format")
+    public boolean isExtended()
+    {
+        return _extended;
+    }
+
+    /**
+     * Set up request logging and open log file.
+     *
+     * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
+     */
+    @Override
+    protected synchronized void doStart() throws Exception
+    {
+        if (_logDateFormat != null)
+        {
+            _logDateCache = new DateCache(_logDateFormat, _logLocale ,_logTimeZone);
+        }
+
+        if (_ignorePaths != null && _ignorePaths.length > 0)
+        {
+            _ignorePathMap = new PathMap<>();
+            for (int i = 0; i < _ignorePaths.length; i++)
+                _ignorePathMap.put(_ignorePaths[i], _ignorePaths[i]);
+        }
+        else
+            _ignorePathMap = null;
+
+        super.doStart();
+    }
+
+    @Override
+    protected void doStop() throws Exception
+    {
+        _logDateCache = null;
+        super.doStop();
+    }
+
+    /**
+     * Set the timestamp format for request log entries in the file. If this is not set, the pre-formated request
+     * timestamp is used.
+     *
+     * @param format timestamp format string
+     */
+    public void setLogDateFormat(String format)
+    {
+        _logDateFormat = format;
+    }
+
+    /**
+     * Retrieve the timestamp format string for request log entries.
+     *
+     * @return timestamp format string.
+     */
+    public String getLogDateFormat()
+    {
+        return _logDateFormat;
+    }
+
+    /**
+     * Set the locale of the request log.
+     *
+     * @param logLocale locale object
+     */
+    public void setLogLocale(Locale logLocale)
+    {
+        _logLocale = logLocale;
+    }
+
+    /**
+     * Retrieve the locale of the request log.
+     *
+     * @return locale object
+     */
+    public Locale getLogLocale()
+    {
+        return _logLocale;
+    }
+
+    /**
+     * Set the timezone of the request log.
+     *
+     * @param tz timezone string
+     */
+    public void setLogTimeZone(String tz)
+    {
+        _logTimeZone = tz;
+    }
+
+    /**
+     * Retrieve the timezone of the request log.
+     *
+     * @return timezone string
+     */
+    @ManagedAttribute("the timezone")
+    public String getLogTimeZone()
+    {
+        return _logTimeZone;
+    }
+}