1//
2//  ========================================================================
3//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4//  ------------------------------------------------------------------------
5//  All rights reserved. This program and the accompanying materials
6//  are made available under the terms of the Eclipse Public License v1.0
7//  and Apache License v2.0 which accompanies this distribution.
8//
9//      The Eclipse Public License is available at
10//      http://www.eclipse.org/legal/epl-v10.html
11//
12//      The Apache License v2.0 is available at
13//      http://www.opensource.org/licenses/apache2.0.php
14//
15//  You may elect to redistribute this code under either of these licenses.
16//  ========================================================================
17//
18
19package org.eclipse.jetty.server.handler;
20
21import java.io.IOException;
22
23import javax.servlet.DispatcherType;
24import javax.servlet.ServletException;
25import javax.servlet.http.HttpServletRequest;
26import javax.servlet.http.HttpServletResponse;
27
28import org.eclipse.jetty.continuation.Continuation;
29import org.eclipse.jetty.continuation.ContinuationListener;
30import org.eclipse.jetty.server.AsyncContinuation;
31import org.eclipse.jetty.server.Request;
32import org.eclipse.jetty.server.RequestLog;
33import org.eclipse.jetty.server.Response;
34import org.eclipse.jetty.server.Server;
35import org.eclipse.jetty.util.component.AbstractLifeCycle;
36import org.eclipse.jetty.util.log.Log;
37import org.eclipse.jetty.util.log.Logger;
38
39
40/**
41 * RequestLogHandler.
42 * This handler can be used to wrap an individual context for context logging.
43 *
44 * @org.apache.xbean.XBean
45 */
46public class RequestLogHandler extends HandlerWrapper
47{
48    private static final Logger LOG = Log.getLogger(RequestLogHandler.class);
49
50    private RequestLog _requestLog;
51
52    /* ------------------------------------------------------------ */
53    /*
54     * @see org.eclipse.jetty.server.server.Handler#handle(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
55     */
56    @Override
57    public void handle(String target, final Request baseRequest, HttpServletRequest request, final HttpServletResponse response)
58            throws IOException, ServletException
59    {
60        AsyncContinuation continuation = baseRequest.getAsyncContinuation();
61        if (!continuation.isInitial())
62        {
63            baseRequest.setDispatchTime(System.currentTimeMillis());
64        }
65
66        try
67        {
68            super.handle(target, baseRequest, request, response);
69        }
70        finally
71        {
72            if (_requestLog != null && baseRequest.getDispatcherType().equals(DispatcherType.REQUEST))
73            {
74                if (continuation.isAsync())
75                {
76                    if (continuation.isInitial())
77                        continuation.addContinuationListener(new ContinuationListener()
78                        {
79
80                            public void onTimeout(Continuation continuation)
81                            {
82
83                            }
84
85                            public void onComplete(Continuation continuation)
86                            {
87                                _requestLog.log(baseRequest, (Response)response);
88                            }
89                        });
90                }
91                else
92                    _requestLog.log(baseRequest, (Response)response);
93            }
94        }
95    }
96
97    /* ------------------------------------------------------------ */
98    public void setRequestLog(RequestLog requestLog)
99    {
100        //are we changing the request log impl?
101        try
102        {
103            if (_requestLog != null)
104                _requestLog.stop();
105        }
106        catch (Exception e)
107        {
108            LOG.warn (e);
109        }
110
111        if (getServer()!=null)
112            getServer().getContainer().update(this, _requestLog, requestLog, "logimpl",true);
113
114        _requestLog = requestLog;
115
116        //if we're already started, then start our request log
117        try
118        {
119            if (isStarted() && (_requestLog != null))
120                _requestLog.start();
121        }
122        catch (Exception e)
123        {
124            throw new RuntimeException (e);
125        }
126    }
127
128    /* ------------------------------------------------------------ */
129    /*
130     * @see org.eclipse.jetty.server.server.handler.HandlerWrapper#setServer(org.eclipse.jetty.server.server.Server)
131     */
132    @Override
133    public void setServer(Server server)
134    {
135        if (_requestLog!=null)
136        {
137            if (getServer()!=null && getServer()!=server)
138                getServer().getContainer().update(this, _requestLog, null, "logimpl",true);
139            super.setServer(server);
140            if (server!=null && server!=getServer())
141                server.getContainer().update(this, null,_requestLog, "logimpl",true);
142        }
143        else
144            super.setServer(server);
145    }
146
147    /* ------------------------------------------------------------ */
148    public RequestLog getRequestLog()
149    {
150        return _requestLog;
151    }
152
153    /* ------------------------------------------------------------ */
154    /*
155     * @see org.eclipse.jetty.server.server.handler.HandlerWrapper#doStart()
156     */
157    @Override
158    protected void doStart() throws Exception
159    {
160        if (_requestLog==null)
161        {
162            LOG.warn("!RequestLog");
163            _requestLog=new NullRequestLog();
164        }
165        super.doStart();
166        _requestLog.start();
167    }
168
169    /* ------------------------------------------------------------ */
170    /*
171     * @see org.eclipse.jetty.server.server.handler.HandlerWrapper#doStop()
172     */
173    @Override
174    protected void doStop() throws Exception
175    {
176        super.doStop();
177        _requestLog.stop();
178        if (_requestLog instanceof NullRequestLog)
179            _requestLog=null;
180    }
181
182    /* ------------------------------------------------------------ */
183    /* ------------------------------------------------------------ */
184    /* ------------------------------------------------------------ */
185    private static class NullRequestLog extends AbstractLifeCycle implements RequestLog
186    {
187        public void log(Request request, Response response)
188        {
189        }
190    }
191
192}
193