//
//  ========================================================================
//  Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//  ========================================================================
//  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.
//  ========================================================================
//

[[configuring-jetty-request-logs]]
=== Configuring Jetty Request Logs

Request logs are a record of the requests that the server has processed.
There is one entry per request received, and commonly in the standard NCSA format, so you can use tools like http://en.wikipedia.org/wiki/Webalizer[Webalizer] to analyze them conveniently.

[[constructing-request-log-entry]]
==== Constructing a Request Log Entry

A standard request log entry includes the client IP address, date, method, URL, result, size, referrer, user agent and latency.
For example:

....
123.4.5.6 - - [20/Jul/2016:10:16:17 +0000]
  "GET /jetty/tut/XmlConfiguration.html HTTP/1.1"
  200 76793 "http://localhost:8080/jetty/tut/logging.html"
  "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040614 Firefox/0.8" 342
....

[[implementing-request-log]]
==== Implementing a Request Log

Jetty provides an implementation called `NCSARequestLog` which supports the NCSA format in files that will roll over on a daily basis.

The http://logback.qos.ch/[Logback Project] offers http://logback.qos.ch/access.html[another implementation] of a `RequestLog` interface, providing rich and powerful HTTP-access log functionality.

If neither of these options meets your needs, you can implement a custom request logger by implementing Jetty's link:{JDURL}/org/eclipse/jetty/server/RequestLog.html[`RequestLog.java`] interface and plugging it in similar to the `NCSARequestLog`, as shown below.

[[configuring-request-log]]
==== Configuring the Request Log module

To enable the Request Log module for the entire server via the Jetty distribution, it first needs to be enabled on the command line:

[source, screen, subs="{sub-order}"]
----
$ java -jar ../start.jar --add-to-start=requestlog

INFO: requestlog      initialised in ${jetty.base}/start.d/requestlog.ini
MKDIR: ${jetty.base}/logs
INFO: Base directory was modified
----

The above command will add a new `requestlog.ini` file to your link:#start-vs-startd[`{$jetty.base}/start.d` directory].

____
[NOTE]
By default, request logs are not set to be appended, meaning a the log file is wiped clean upon sever restart.
You can change this setting by editing the `requestlog.ini` and un-commenting the line that reads `jetty.requestlog.append=true`.
____

The equivalent code for embedded usages of Jetty is:

[source, java, subs="{sub-order}"]
----
NCSARequestLog requestLog = new NCSARequestLog("/var/logs/jetty/jetty-yyyy_mm_dd.request.log");
requestLog.setAppend(true);
requestLog.setExtended(false);
requestLog.setLogTimeZone("GMT");
requestLog.setLogLatency(true);
requestLog.setRetainDays("90");

server.setRequestLog(requestLog);
----

This configures a request log in `{$jetty.home}/logs` with filenames including the date.
Existing log files are appended to and the extended NCSA format is used in the GMT time zone.

The above configuration enables Log Latency, which is the amount of time it took the server to handle the request.
This value is measured in milliseconds and is appended to the the log file for each request.

You can also customize the number of days you wish to keep request logs.
By default, log files are kept for 90 days before being deleted.
The value for `retainDays` (xml) or `setRetainDays` (Java) should be configured as _1 + n_ days.
For example, if you wanted to keep the logs for the current day and the day prior you would set the `retainDays` (or `setRetainDays`) value to 2.


[[request-log-custom-writer]]
==== Introducing RequestLog.Writer

The concept of a `RequestLog.Writer`, introduced in Jetty 9.4.15, manages the writing to a log the string generated by the `RequestLog`.
This allows the `CustomRequestLog` to match the functionality of other `RequestLogger` implementations by plugging in any `RequestLog.Writer` and a custom format string.
Jetty currently has implementations of `RequestLog.Writer`, `RequestLogWriter`, `AsyncRequestLogWriter`, and `Slf4jRequestLogWriter`.

So, the way to create an asynchronous `RequestLog` using the extended NCSA format has been changed from:

`new AsyncNcsaRequestLog(filename)`

to:

`new CustomRequestLog(new AsyncRequestLogWriter(filename), CustomRequestLog.EXTENDED_NCSA_FORMAT)`

Additionally, there are now two settings for the log timezone to be configured.
There is the configuration for logging the request time, which is set in the `timeZone` parameter in the `%t` format code of the string, given in the format `%{format|timeZone|locale}t`.

The other `timeZone` parameter relates to the generation of the log file name (both at creation and roll over).
This is configured in the `requestlog` module file, or can be used as a setter on `RequestLogWriter` via XML.

Both timezones are set to GMT by default.

[[configuring-separate-request-log-for-web-application]]
==== Configuring a Separate Request Log For a Web Application

To configure a separate request log for specific a web application, add the following to the context XML file.

[source, xml, subs="{sub-order}"]
----
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
  ...
  <Call name="insertHandler">
    <Arg>
      <New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler">
        <Set name="requestLog">
          <New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog">
            <Set name="filename"><Property name="jetty.logs" default="./logs"/>/test-yyyy_mm_dd.request.log</Set>
            <Set name="filenameDateFormat">yyyy_MM_dd</Set>
            <Set name="LogTimeZone">GMT</Set>
            <Set name="retainDays">90</Set>
            <Set name="append">true</Set>
            <Set name="LogLatency">true</Set>
          </New>
        </Set>
      </New>
    </Arg>
  </Call>
  ...
</Configure>
----
