ARTEMIS-1917 support logging HTTP access
Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/aa1f6a9d Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/aa1f6a9d Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/aa1f6a9d Branch: refs/heads/master Commit: aa1f6a9dd31f6d86fc5534a64e0899b4e165066d Parents: 77eb0b6 Author: Justin Bertram <jbert...@apache.org> Authored: Thu Jun 7 16:59:47 2018 -0500 Committer: Clebert Suconic <clebertsuco...@apache.org> Committed: Tue Jun 19 00:12:32 2018 -0400 ---------------------------------------------------------------------- .../activemq/artemis/dto/RequestLogDTO.java | 105 +++++++++++++++++++ .../activemq/artemis/dto/WebServerDTO.java | 3 + .../artemis/component/WebServerComponent.java | 71 +++++++++++++ docs/user-manual/en/SUMMARY.md | 1 + docs/user-manual/en/web-server.md | 82 +++++++++++++++ 5 files changed, 262 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/aa1f6a9d/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/RequestLogDTO.java ---------------------------------------------------------------------- diff --git a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/RequestLogDTO.java b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/RequestLogDTO.java new file mode 100644 index 0000000..b2522e6 --- /dev/null +++ b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/RequestLogDTO.java @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.artemis.dto; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "request-log") +@XmlAccessorType(XmlAccessType.FIELD) +public class RequestLogDTO { + + /** + * the output file name of the request log + */ + @XmlAttribute(required = true) + public String filename; + + /** + * append to log + */ + @XmlAttribute + public Boolean append; + + /** + * the extended request log format flag + */ + @XmlAttribute + public Boolean extended; + + /** + * logging of the request cookies + */ + @XmlAttribute + public Boolean logCookies; + + /** + * the output file name of the request log + */ + @XmlAttribute + public String logTimeZone; + + /** + * the log file name date format + */ + @XmlAttribute + public String filenameDateFormat; + + /** + * the number of days before rotated log files are deleted + */ + @XmlAttribute + public Integer retainDays; + + /** + * request paths that will not be logged + */ + @XmlAttribute + public String ignorePaths; + + /** + * the timestamp format string for request log entries + */ + @XmlAttribute + public String logDateFormat; + + /** + * the locale of the request log + */ + @XmlAttribute + public String logLocale; + + /** + * logging of request processing time + */ + @XmlAttribute + public Boolean logLatency; + + /** + * logging of the request hostname + */ + @XmlAttribute + public Boolean logServer; + + /** + * whether the actual IP address of the connection or the IP address from the X-Forwarded-For header will be logged + */ + @XmlAttribute + public Boolean preferProxiedForAddress; +} http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/aa1f6a9d/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/WebServerDTO.java ---------------------------------------------------------------------- diff --git a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/WebServerDTO.java b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/WebServerDTO.java index 3e15261..8987b42 100644 --- a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/WebServerDTO.java +++ b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/WebServerDTO.java @@ -50,6 +50,9 @@ public class WebServerDTO extends ComponentDTO { @XmlElementRef public List<AppDTO> apps; + @XmlElementRef(required = false) + public RequestLogDTO requestLog; + @XmlAttribute private String keyStorePassword; http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/aa1f6a9d/artemis-web/src/main/java/org/apache/activemq/artemis/component/WebServerComponent.java ---------------------------------------------------------------------- diff --git a/artemis-web/src/main/java/org/apache/activemq/artemis/component/WebServerComponent.java b/artemis-web/src/main/java/org/apache/activemq/artemis/component/WebServerComponent.java index 0a2b231..05a9202 100644 --- a/artemis-web/src/main/java/org/apache/activemq/artemis/component/WebServerComponent.java +++ b/artemis-web/src/main/java/org/apache/activemq/artemis/component/WebServerComponent.java @@ -23,6 +23,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import org.apache.activemq.artemis.ActiveMQWebLogger; import org.apache.activemq.artemis.components.ExternalComponent; @@ -35,6 +36,7 @@ import org.eclipse.jetty.server.ConnectionFactory; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.NCSARequestLog; import org.eclipse.jetty.server.SecureRequestCustomizer; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; @@ -42,6 +44,7 @@ import org.eclipse.jetty.server.SslConnectionFactory; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.DefaultHandler; import org.eclipse.jetty.server.handler.HandlerList; +import org.eclipse.jetty.server.handler.RequestLogHandler; import org.eclipse.jetty.server.handler.ResourceHandler; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.webapp.WebAppContext; @@ -143,12 +146,80 @@ public class WebServerComponent implements ExternalComponent { DefaultHandler defaultHandler = new DefaultHandler(); defaultHandler.setServeIcon(false); + if (webServerConfig.requestLog != null) { + handlers.addHandler(getLogHandler()); + } handlers.addHandler(homeContext); handlers.addHandler(instanceContext); handlers.addHandler(defaultHandler); server.setHandler(handlers); } + private RequestLogHandler getLogHandler() { + RequestLogHandler requestLogHandler = new RequestLogHandler(); + NCSARequestLog requestLog = new NCSARequestLog(); + + // required via config so no check necessary + requestLog.setFilename(webServerConfig.requestLog.filename); + + if (webServerConfig.requestLog.append != null) { + requestLog.setAppend(webServerConfig.requestLog.append); + } + + if (webServerConfig.requestLog.extended != null) { + requestLog.setExtended(webServerConfig.requestLog.extended); + } + + if (webServerConfig.requestLog.logCookies != null) { + requestLog.setLogCookies(webServerConfig.requestLog.logCookies); + } + + if (webServerConfig.requestLog.logTimeZone != null) { + requestLog.setLogTimeZone(webServerConfig.requestLog.logTimeZone); + } + + if (webServerConfig.requestLog.filenameDateFormat != null) { + requestLog.setFilenameDateFormat(webServerConfig.requestLog.filenameDateFormat); + } + + if (webServerConfig.requestLog.retainDays != null) { + requestLog.setRetainDays(webServerConfig.requestLog.retainDays); + } + + if (webServerConfig.requestLog.ignorePaths != null && webServerConfig.requestLog.ignorePaths.length() > 0) { + String[] split = webServerConfig.requestLog.ignorePaths.split(","); + String[] ignorePaths = new String[split.length]; + for (int i = 0; i < ignorePaths.length; i++) { + ignorePaths[i] = split[i].trim(); + } + requestLog.setIgnorePaths(ignorePaths); + } + + if (webServerConfig.requestLog.logDateFormat != null) { + requestLog.setLogDateFormat(webServerConfig.requestLog.logDateFormat); + } + + if (webServerConfig.requestLog.logLocale != null) { + requestLog.setLogLocale(Locale.forLanguageTag(webServerConfig.requestLog.logLocale)); + } + + if (webServerConfig.requestLog.logLatency != null) { + requestLog.setLogLatency(webServerConfig.requestLog.logLatency); + } + + if (webServerConfig.requestLog.logServer != null) { + requestLog.setLogServer(webServerConfig.requestLog.logServer); + } + + if (webServerConfig.requestLog.preferProxiedForAddress != null) { + requestLog.setPreferProxiedForAddress(webServerConfig.requestLog.preferProxiedForAddress); + } + + requestLogHandler.setRequestLog(requestLog); + + return requestLogHandler; + } + @Override public void start() throws Exception { if (isStarted()) { http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/aa1f6a9d/docs/user-manual/en/SUMMARY.md ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/SUMMARY.md b/docs/user-manual/en/SUMMARY.md index 86273cc..d86ed85 100644 --- a/docs/user-manual/en/SUMMARY.md +++ b/docs/user-manual/en/SUMMARY.md @@ -58,6 +58,7 @@ * [Graceful Server Shutdown](graceful-shutdown.md) * [Libaio Native Libraries](libaio.md) * [Thread management](thread-pooling.md) +* [Embedded Web Server](web-server.md) * [Logging](logging.md) * [REST Interface](rest.md) * [Embedding the Broker](embedding-activemq.md) http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/aa1f6a9d/docs/user-manual/en/web-server.md ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/web-server.md b/docs/user-manual/en/web-server.md new file mode 100644 index 0000000..2a403ad --- /dev/null +++ b/docs/user-manual/en/web-server.md @@ -0,0 +1,82 @@ +# Embedded Web Server + +Apache ActiveMQ Artemis embeds the [Jetty web +server](https://www.eclipse.org/jetty/). Its main purpose is to host the [Management +Console](management-console.md). However, it can also host other web +applications like the [REST interface](rest.md) or even Spring-based web +applications (e.g. using Camel). + +## Configuration + +The embedded Jetty instance is configured in `etc/bootstrap.xml` via the `web` +element, e.g.: + +```xml +<web bind="http://localhost:8161" path="web"> + <app url="activemq-branding" war="activemq-branding.war"/> + <app url="artemis-plugin" war="artemis-plugin.war"/> + <app url="console" war="console.war"/> +</web> +``` + +The `web` element has the following attributes: + +- `bind` The protocol to use (i.e. `http` or `https`) as well as the host and + port on which to listen. +- `path` The name of the subdirectory in which to find the web application + archives (i.e. WAR files). This is a subdirectory of the broker's home or + instance directory. +- `clientAuth` Whether or not clients should present an SSL certificate when + they connect. Only applicable when using `https`. +- `passwordCodec` The custom coded to use for unmasking the `keystorePassword` + and `truststorePassword`. +- `keystorePath` The location on disk of the keystore. Only applicable when + using `https`. +- `keystorePassword` The password to the keystore. Only applicable when using + `https`. Can be masked using `ENC()` syntax or by defining `passwordCodec`. + See more in the [password masking](masking-passwords.md) chapter. +- `truststorePath` The location on disk fo the truststore. Only applicable when + using `https`. +- `truststorePassword` The password to the truststore. Only applicable when + using `https`. Can be masked using `ENC()` syntax or by defining + `passwordCodec`. See more in the [password masking](masking-passwords.md) + chapter. + +Each web application should be defined in an `app` element. The `app` element +has the following attributes: + +- `url` The context to use for the web application. +- `war` The name of the web application archive on disk. + +It's also possible to configure HTTP/S request logging via the `request-log` +element which has the following attributes: + +- `filename` The full path of the request log. This attribute is required. +- `append` Whether or not to append to the existing log or truncate it. Boolean flag. +- `extended` Whether or not to use the extended request log format. Boolean flag. +- `logCookies` Logging of the request cookies. Boolean flag. +- `logTimeZone` The output file name of the request log. +- `filenameDateFormat` The log file name date format. +- `retainDays` The number of days before rotated log files are deleted. +- `ignorePaths` Request paths that will not be logged. Comma delimited list. +- `logDateFormat` The timestamp format string for request log entries. +- `logLocale` The locale of the request log. +- `logLatency` Logging of request processing time. Boolean flag. +- `logServer` Logging of the request hostname. Boolean flag. +- `preferProxiedForAddress` Whether the actual IP address of the connection or + the IP address from the `X-Forwarded-For` header will be logged. Boolean flag. + +These attributes are essentially passed straight through to the underlying +[`org.eclipse.jetty.server.NCSARequestLog`](https://www.eclipse.org/jetty/javadoc/current/org/eclipse/jetty/server/NCSARequestLog.html) +instance. Default values are based on this implementation. + +Here is an example configuration: + +```xml +<web bind="http://localhost:8161" path="web"> + <app url="activemq-branding" war="activemq-branding.war"/> + <app url="artemis-plugin" war="artemis-plugin.war"/> + <app url="console" war="console.war"/> + <request-log filename="${artemis.instance}/log/http-access-yyyy_MM_dd.log" append="true" extended="true"/> +</web> +``` \ No newline at end of file