Add support for configuring Jetty's request log via the environment

See gh-8819
pull/8971/merge
olivier lamy 8 years ago committed by Stephane Nicoll
parent 45f76965f6
commit ce892a06e4

@ -26,6 +26,16 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.eclipse.jetty.server.AbstractConnector;
import org.eclipse.jetty.server.ConnectionFactory;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.NCSARequestLog;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty; import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
import org.springframework.boot.context.properties.NestedConfigurationProperty; import org.springframework.boot.context.properties.NestedConfigurationProperty;
@ -900,6 +910,8 @@ public class ServerProperties {
*/ */
private Integer selectors; private Integer selectors;
private final Accesslog accesslog = new Accesslog();
public int getMaxHttpPostSize() { public int getMaxHttpPostSize() {
return this.maxHttpPostSize; return this.maxHttpPostSize;
} }
@ -924,6 +936,157 @@ public class ServerProperties {
this.selectors = selectors; this.selectors = selectors;
} }
public Accesslog getAccesslog() {
return this.accesslog;
}
public static class Accesslog {
/**
* Enable access log.
*/
private boolean enabled;
/**
* accesslog filename. If no filename, logs will be redirected to System.err
*/
private String filename;
/**
* number of days before rotated log files are deleted. Default 31
*/
private int retainDays = 31;
/**
* append to log.
*/
private boolean append;
/**
* the log file name date format.
*/
private String filenameDateFormat;
/**
* extended NCSA format.
*/
private boolean extended;
/**
* Set the timezone of the request log.
*/
private String logTimeZone;
/**
* Controls logging of the request cookies.
*/
private boolean logCookies;
/**
* Controls logging of the request hostname.
*/
private boolean logServer;
/**
* Controls logging of request processing time.
*/
private boolean logLatency;
/**
* Set the timestamp format for request log entries in the file. If this is not set, the pre-formated request
* timestamp is used.
*/
private String logDateFormat;
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getFilename() {
return this.filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public int getRetainDays() {
return this.retainDays;
}
public void setRetainDays(int retainDays) {
this.retainDays = retainDays;
}
public boolean isAppend() {
return this.append;
}
public void setAppend(boolean append) {
this.append = append;
}
public String getFilenameDateFormat() {
return this.filenameDateFormat;
}
public void setFilenameDateFormat(String filenameDateFormat) {
this.filenameDateFormat = filenameDateFormat;
}
public boolean isExtended() {
return this.extended;
}
public void setExtended(boolean extended) {
this.extended = extended;
}
public String getLogTimeZone() {
return this.logTimeZone;
}
public void setLogTimeZone(String logTimeZone) {
this.logTimeZone = logTimeZone;
}
public boolean isLogCookies() {
return this.logCookies;
}
public void setLogCookies(boolean logCookies) {
this.logCookies = logCookies;
}
public boolean isLogServer() {
return logServer;
}
public void setLogServer( boolean logServer ) {
this.logServer = logServer;
}
public boolean isLogLatency() {
return logLatency;
}
public void setLogLatency( boolean logLatency ) {
this.logLatency = logLatency;
}
public String getLogDateFormat() {
return logDateFormat;
}
public void setLogDateFormat( String logDateFormat ) {
this.logDateFormat = logDateFormat;
}
}
} }
/** /**

@ -36,6 +36,7 @@ import org.eclipse.jetty.server.AbstractConnector;
import org.eclipse.jetty.server.ConnectionFactory; import org.eclipse.jetty.server.ConnectionFactory;
import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.NCSARequestLog;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.HandlerCollection; import org.eclipse.jetty.server.handler.HandlerCollection;
@ -541,6 +542,9 @@ public class DefaultServletWebServerFactoryCustomizer
customizeConnectionTimeout(factory, customizeConnectionTimeout(factory,
serverProperties.getConnectionTimeout()); serverProperties.getConnectionTimeout());
} }
if (jettyProperties.getAccesslog().isEnabled()) {
customizeAccesslog(factory, jettyProperties.getAccesslog());
}
} }
private static void customizeConnectionTimeout( private static void customizeConnectionTimeout(
@ -637,6 +641,32 @@ public class DefaultServletWebServerFactoryCustomizer
}); });
} }
private static void customizeAccesslog(JettyServletWebServerFactory factory,
final ServerProperties.Jetty.Accesslog accesslog) {
factory.addServerCustomizers( server -> {
NCSARequestLog requestLog = new NCSARequestLog();
if (accesslog.getFilename() != null) {
requestLog.setFilename(accesslog.getFilename());
}
if (accesslog.getFilenameDateFormat() != null) {
requestLog.setFilenameDateFormat(accesslog.getFilenameDateFormat());
}
if (accesslog.getRetainDays() > 0) {
requestLog.setRetainDays(accesslog.getRetainDays());
}
requestLog.setLogTimeZone(accesslog.getLogTimeZone());
requestLog.setExtended(accesslog.isExtended());
requestLog.setAppend(accesslog.isAppend());
requestLog.setLogCookies(accesslog.isLogCookies());
requestLog.setLogServer( accesslog.isLogServer() );
requestLog.setLogLatency( accesslog.isLogLatency() );
if (!StringUtils.isEmpty( accesslog.getLogDateFormat() )) {
requestLog.setLogDateFormat( accesslog.getLogDateFormat() );
}
server.setRequestLog(requestLog);
});
}
} }
} }

@ -184,6 +184,23 @@ public class ServerPropertiesTests {
assertThat(this.properties.getJetty().getSelectors()).isEqualTo(10); assertThat(this.properties.getJetty().getSelectors()).isEqualTo(10);
} }
@Test
public void testJettyBinding() throws Exception {
Map<String, String> map = new HashMap<String, String>();
map.put("server.jetty.accesslog.enabled", "true");
map.put("server.jetty.accesslog.filename", "foo.txt");
map.put("server.jetty.accesslog.retainDays", "4");
map.put("server.jetty.accesslog.append", "true");
map.put("server.jetty.accesslog.filenameDateFormat", "yyyymmdd");
bindProperties(map);
ServerProperties.Jetty jetty = this.properties.getJetty();
assertThat(jetty.getAccesslog().isEnabled()).isEqualTo(true);
assertThat(jetty.getAccesslog().getFilename()).isEqualTo("foo.txt");
assertThat(jetty.getAccesslog().getRetainDays()).isEqualTo(4);
assertThat(jetty.getAccesslog().isAppend()).isEqualTo(true);
assertThat(jetty.getAccesslog().getFilenameDateFormat()).isEqualTo("yyyymmdd");
}
private void bindProperties(Map<String, String> map) { private void bindProperties(Map<String, String> map) {
new RelaxedDataBinder(this.properties, "server") new RelaxedDataBinder(this.properties, "server")
.bind(new MutablePropertyValues(map)); .bind(new MutablePropertyValues(map));

@ -159,6 +159,20 @@ content into your application; rather pick only the properties that you need.
server.jetty.acceptors= # Number of acceptor threads to use. server.jetty.acceptors= # Number of acceptor threads to use.
server.jetty.max-http-post-size=0 # Maximum size in bytes of the HTTP post or put content. server.jetty.max-http-post-size=0 # Maximum size in bytes of the HTTP post or put content.
server.jetty.selectors= # Number of selector threads to use. server.jetty.selectors= # Number of selector threads to use.
server.jetty.accesslog.enabled=false # Enable access log.
server.jetty.accesslog.filename= # Filename of Jetty access logs.
server.jetty.accesslog.retainDays=31 # number of days before rotated log files are deleted.
server.jetty.accesslog.append=true # append to log flag.
server.jetty.accesslog.filenameDateFormat=yyyy_MM_dd # log file name date format.
server.jetty.accesslog.extended= true # extended request log format flag.
server.jetty.accesslog.logTimeZone= GMT # the timezone of the request log
server.jetty.accesslog.logCookies=false # Controls logging of the request cookies.
server.jetty.accesslog.logServer=false # Controls logging of the request hostname.
server.jetty.accesslog.logLatency=false # Controls logging of request processing time.
server.jetty.accesslog.logDateFormat= # Set the timestamp format for request log entries in the file. If this is not set, the pre-formated request timestamp is used.
server.jsp-servlet.class-name=org.apache.jasper.servlet.JspServlet # The class name of the JSP servlet.
server.jsp-servlet.init-parameters.*= # Init parameters used to configure the JSP servlet
server.jsp-servlet.registered=true # Whether or not the JSP servlet is registered
server.port=8080 # Server HTTP port. server.port=8080 # Server HTTP port.
server.server-header= # Value to use for the Server response header (no header is sent if empty) server.server-header= # Value to use for the Server response header (no header is sent if empty)
server.use-forward-headers= # If X-Forwarded-* headers should be applied to the HttpRequest. server.use-forward-headers= # If X-Forwarded-* headers should be applied to the HttpRequest.

@ -636,7 +636,7 @@ sample project for an example.
[[howto-configure-accesslogs]] [[howto-configure-accesslogs]]
=== Configure Access Logging === Configure Access Logging
Access logs can be configured for Tomcat and Undertow via their respective namespaces. Access logs can be configured for Tomcat, Undertow and Jetty via their respective namespaces.
For instance, the following logs access on Tomcat with a For instance, the following logs access on Tomcat with a
https://tomcat.apache.org/tomcat-8.0-doc/config/valve.html#Access_Logging[custom pattern]. https://tomcat.apache.org/tomcat-8.0-doc/config/valve.html#Access_Logging[custom pattern].
@ -664,6 +664,16 @@ Access logging for undertow can be configured in a similar fashion
Logs are stored in a `logs` directory relative to the working directory of the Logs are stored in a `logs` directory relative to the working directory of the
application. This can be customized via `server.undertow.accesslog.directory`. application. This can be customized via `server.undertow.accesslog.directory`.
Access logging for jetty can be configured in a similar fashion
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
----
server.jetty.accesslog.enabled=true
server.jetty.accesslog.filename=
----
If no filename logs will go to System.err.
For more details please refer to https://www.eclipse.org/jetty/documentation/9.3.x/configuring-jetty-request-logs.html.
[[howto-use-behind-a-proxy-server]] [[howto-use-behind-a-proxy-server]]

Loading…
Cancel
Save