From d055c1c52494ffc97903d4352de0ac3b3bd7e0aa Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 12 Jan 2022 15:14:31 +0100 Subject: [PATCH 1/3] Changed URLs from adoptopenjdk.net to adoptium.net. Signed-off-by: Simone Bordet --- .../src/main/asciidoc/operations-guide/jmx/jmx-local.adoc | 2 +- .../src/main/asciidoc/operations-guide/jmx/jmx-remote.adoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jmx/jmx-local.adoc b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jmx/jmx-local.adoc index 7058f44071c..c9fa5e1c179 100644 --- a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jmx/jmx-local.adoc +++ b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jmx/jmx-local.adoc @@ -28,7 +28,7 @@ Note that the Jetty MBeans are registered into the platform `MBeanServer`, but a This configuration is useful when you develop and test your Jetty server locally. -JMX compliant tools such as link:https://adoptopenjdk.net/jmc.html[Java Mission Control (JMC)] can be started locally on your machine and can attach to other JVMs running on your machine, showing you the registered MBeans among which you will find the Jetty MBeans. +JMX compliant tools such as link:https://adoptium.net/jmc.html[Java Mission Control (JMC)] can be started locally on your machine and can attach to other JVMs running on your machine, showing you the registered MBeans among which you will find the Jetty MBeans. NOTE: Enabling only the local JMX support is the most secure option for monitoring and management, but only users that have local access to the JVM will be able to browse the MBeans. If you need to access the MBeans from a remote machine, read xref:og-jmx-remote[this section]. diff --git a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jmx/jmx-remote.adoc b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jmx/jmx-remote.adoc index 6695047e362..f70ac3364e0 100644 --- a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jmx/jmx-remote.adoc +++ b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jmx/jmx-remote.adoc @@ -242,7 +242,7 @@ If you are using self-signed certificates, the KeyStore already contains the sel JMX compliant tools that offer a graphical user interface also must be started specifying the TrustStore path and password. -For example, to launch link:https://adoptopenjdk.net/jmc.html[Java Mission Control (JMC)]: +For example, to launch link:https://adoptium.net/jmc.html[Java Mission Control (JMC)]: ---- $ jmc -vmargs -Djavax.net.ssl.trustStore=/path/to/trustStore.p12 -Djavax.net.ssl.trustStorePassword=password From 251649f0a98c6ef331280a6db1e78a20ab2e3e5b Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 12 Jan 2022 15:52:00 +0100 Subject: [PATCH 2/3] Generate plantuml images in the images/ directory. Signed-off-by: Simone Bordet --- .../src/main/asciidoc/programming-guide/.asciidoctorconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/.asciidoctorconfig b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/.asciidoctorconfig index b195ce90a82..32851d8dfbd 100644 --- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/.asciidoctorconfig +++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/.asciidoctorconfig @@ -1,4 +1,5 @@ // Asciidoctor IDE configuration file. // See https://github.com/asciidoctor/asciidoctor-intellij-plugin/wiki/Support-project-specific-configurations :experimental: +:imagesdir: images :doc_code: ../../java From 51123c7cd15a922e00fac41ad4cb3352ce8e5d2b Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 12 Jan 2022 17:12:01 +0100 Subject: [PATCH 3/3] Fixes #7369 - Document CustomRequestLog Added documentation to the programming guide. Removed related old documentation. Signed-off-by: Simone Bordet --- documentation/jetty-documentation/pom.xml | 1 - .../asciidoc/old_docs/logging/chapter.adoc | 1 - .../configuring-jetty-request-logs.adoc | 140 ------------------ .../server/http/server-http-handler.adoc | 2 +- .../server/http/server-http.adoc | 45 +++++- .../server/http/HTTPServerDocs.java | 56 +++++++ 6 files changed, 101 insertions(+), 144 deletions(-) delete mode 100644 documentation/jetty-documentation/src/main/asciidoc/old_docs/logging/configuring-jetty-request-logs.adoc diff --git a/documentation/jetty-documentation/pom.xml b/documentation/jetty-documentation/pom.xml index 881dbcdd16b..517a3244587 100644 --- a/documentation/jetty-documentation/pom.xml +++ b/documentation/jetty-documentation/pom.xml @@ -168,7 +168,6 @@ org.eclipse.jetty jetty-servlets - ${project.version} org.eclipse.jetty diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/logging/chapter.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/logging/chapter.adoc index 7e0e2f58c5c..d37895e8f8e 100644 --- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/logging/chapter.adoc +++ b/documentation/jetty-documentation/src/main/asciidoc/old_docs/logging/chapter.adoc @@ -18,6 +18,5 @@ This chapter discusses various options for configuring logging. include::configuring-jetty-logging.adoc[] include::default-logging-with-stderrlog.adoc[] -include::configuring-jetty-request-logs.adoc[] include::configuring-logging-modules.adoc[] include::example-logback-centralized-logging.adoc[] diff --git a/documentation/jetty-documentation/src/main/asciidoc/old_docs/logging/configuring-jetty-request-logs.adoc b/documentation/jetty-documentation/src/main/asciidoc/old_docs/logging/configuring-jetty-request-logs.adoc deleted file mode 100644 index 7227f4970c9..00000000000 --- a/documentation/jetty-documentation/src/main/asciidoc/old_docs/logging/configuring-jetty-request-logs.adoc +++ /dev/null @@ -1,140 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -[[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}"] ----- -[my-base]$ java -jar /path/to/jetty-home/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}"] ----- - - ... - - - - - - /test-yyyy_mm_dd.request.log - yyyy_MM_dd - GMT - 90 - true - true - - - - - - ... - ----- diff --git a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http-handler.adoc b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http-handler.adoc index f001341d575..77acd975706 100644 --- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http-handler.adoc +++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http-handler.adoc @@ -24,7 +24,7 @@ An `org.eclipse.jetty.server.Handler` is the component that processes incoming H * nested, where one `Handler` invokes the next, nested, `Handler` ** `HandlerWrapper` implements this behavior -The `HandlerCollection` behavior (invoking _all_ handlers) is useful when for example the last `Handler` is a logging `Handler` that logs the request(that may have been modified by previous handlers). +The `HandlerCollection` behavior (invoking _all_ handlers) is useful when for example the last `Handler` is a logging `Handler` that logs the request (that may have been modified by previous handlers). The `HandlerList` behavior (invoking handlers up to the first that calls `Request.setHandled(true)`) is useful when each handler processes a different URIs or a different virtual hosts: ``Handler``s are invoked one after the other until one matches the URI or virtual host. diff --git a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http.adoc b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http.adoc index 310566bbc56..e6f293ebc2c 100644 --- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http.adoc +++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/server/http/server-http.adoc @@ -71,7 +71,7 @@ Read xref:pg-server-http-handler[this section] for further details about ``Handl If you are interested in writing your server application based on the Servlet APIs, jump to xref:pg-server-http-handler-use-servlet[this section]. [[pg-server-http-request-processing]] -==== Server Request Processing +==== Request Processing The Jetty HTTP request processing is outlined below in the diagram below. You may want to refer to the xref:pg-arch-io[Jetty I/O architecture] for additional information about the classes mentioned below. @@ -153,6 +153,49 @@ Server applications can register `HttpChannel.Listener` by adding them as xref:p include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java[tags=httpChannelListener] ---- +[[pg-server-http-request-logging]] +==== Request Logging + +HTTP requests and responses can be logged to provide data that can be later analyzed with other tools. +These tools can provide information such as the most frequently accessed request URIs, the response status codes, the request/response content lengths, geographical information about the clients, etc. + +The default request/response log line format is the link:https://en.wikipedia.org/wiki/Common_Log_Format[NCSA Format] extended with referrer data and user-agent data. + +[NOTE] +==== +Typically, the extended NCSA format is the is enough and it's the standard used and understood by most log parsing tools and monitoring tools. + +To customize the request/response log line format see the link:{javadoc-url}/org/eclipse/jetty/server/CustomRequestLog.html[`CustomRequestLog` javadocs]. +==== + +Request logging can be enabled at the server level, or at the web application context level. + +The request logging output can be directed to an SLF4J logger named `"org.eclipse.jetty.server.RequestLog"` at `INFO` level, and therefore to any logging library implementation of your choice (see also xref:pg-troubleshooting-logging[this section] about logging). + +[source,java,indent=0] +---- +include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java[tags=serverRequestLogSLF4J] +---- + +Alternatively, the request logging output can be directed to a daily rolling file of your choice, and the file name must contain `yyyy_MM_dd` so that rolled over files retain their date: + +[source,java,indent=0] +---- +include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java[tags=serverRequestLogFile] +---- + +For maximum flexibility, you can log to multiple ``RequestLog``s using class `RequestLog.Collection`, for example by logging with different formats or to different outputs. + +You can use `CustomRequestLog` with a custom `RequestLog.Writer` to direct the request logging output to your custom targets (for example, an RDBMS). +You can implement your own `RequestLog` if you want to have functionalities that are not implemented by `CustomRequestLog`. + +Request logging can also be enabled at the web application context level, using `RequestLogHandler` (see xref:pg-server-http-handler[this section] about how to organize Jetty ``Handler``s) to wrap a web application `Handler`: + +[source,java,indent=0] +---- +include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java[tags=contextRequestLog] +---- + include::server-http-connector.adoc[] include::server-http-handler.adoc[] include::server-http-security.adoc[] diff --git a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java index 4f56d21c2a5..6a59797ffc1 100644 --- a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java +++ b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java @@ -16,6 +16,7 @@ package org.eclipse.jetty.docs.programming.server.http; import java.io.IOException; import java.nio.file.Path; import java.util.EnumSet; +import java.util.TimeZone; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import javax.servlet.DispatcherType; @@ -40,14 +41,17 @@ import org.eclipse.jetty.rewrite.handler.RedirectRegexRule; import org.eclipse.jetty.rewrite.handler.RewriteHandler; import org.eclipse.jetty.rewrite.handler.RewriteRegexRule; import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.CustomRequestLog; import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.ProxyConnectionFactory; import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.RequestLogWriter; import org.eclipse.jetty.server.SecureRequestCustomizer; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.Slf4jRequestLogWriter; import org.eclipse.jetty.server.SslConnectionFactory; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.ContextHandler; @@ -56,6 +60,7 @@ import org.eclipse.jetty.server.handler.DefaultHandler; import org.eclipse.jetty.server.handler.HandlerCollection; import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.server.handler.HandlerWrapper; +import org.eclipse.jetty.server.handler.RequestLogHandler; import org.eclipse.jetty.server.handler.ResourceHandler; import org.eclipse.jetty.server.handler.SecuredRedirectHandler; import org.eclipse.jetty.server.handler.StatisticsHandler; @@ -155,6 +160,57 @@ public class HTTPServerDocs // end::httpChannelListener[] } + public void serverRequestLogSLF4J() + { + // tag::serverRequestLogSLF4J[] + Server server = new Server(); + + // Sets the RequestLog to log to an SLF4J logger named "org.eclipse.jetty.server.RequestLog" at INFO level. + server.setRequestLog(new CustomRequestLog(new Slf4jRequestLogWriter(), CustomRequestLog.EXTENDED_NCSA_FORMAT)); + // end::serverRequestLogSLF4J[] + } + + public void serverRequestLogFile() + { + // tag::serverRequestLogFile[] + Server server = new Server(); + + // Use a file name with the pattern 'yyyy_MM_dd' so rolled over files retain their date. + RequestLogWriter logWriter = new RequestLogWriter("/var/log/yyyy_MM_dd.jetty.request.log"); + // Retain rolled over files for 2 weeks. + logWriter.setRetainDays(14); + // Log times are in the current time zone. + logWriter.setTimeZone(TimeZone.getDefault().getID()); + + // Set the RequestLog to log to the given file, rolling over at midnight. + server.setRequestLog(new CustomRequestLog(logWriter, CustomRequestLog.EXTENDED_NCSA_FORMAT)); + // end::serverRequestLogFile[] + } + + public void contextRequestLog() + { + // tag::contextRequestLog[] + Server server = new Server(); + + // Create a first ServletContextHandler for your main application. + ServletContextHandler mainContext = new ServletContextHandler(); + mainContext.setContextPath("/main"); + + // Create a RequestLogHandler to log requests for your main application. + RequestLogHandler requestLogHandler = new RequestLogHandler(); + requestLogHandler.setRequestLog(new CustomRequestLog()); + // Wrap the main application with the request log handler. + requestLogHandler.setHandler(mainContext); + + // Create a second ServletContextHandler for your other application. + // No request logging for this application. + ServletContextHandler otherContext = new ServletContextHandler(); + mainContext.setContextPath("/other"); + + server.setHandler(new HandlerList(requestLogHandler, otherContext)); + // end::contextRequestLog[] + } + public void configureConnector() throws Exception { // tag::configureConnector[]