Browse Source

Add support for configuring Undertow's access log via the environment

This commit adds support for configuring Undertow's access log via the
environment using the following properties:

server.undertow.access-log-enabled
server.undertow.access-log-pattern
server.undertow.access-log-dir

See gh-3014
pull/3019/head
Marcos Barbero 11 years ago committed by Andy Wilkinson
parent
commit
90e43737bb
  1. 43
      spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java
  2. 2
      spring-boot-samples/spring-boot-sample-undertow/src/test/resources/application.properties
  3. 20
      spring-boot/src/main/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactory.java
  4. 15
      spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java
  5. 78
      spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java

43
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java

@ -56,6 +56,7 @@ import org.springframework.util.StringUtils; @@ -56,6 +56,7 @@ import org.springframework.util.StringUtils;
* @author Stephane Nicoll
* @author Andy Wilkinson
* @author Ivan Sopov
* @author Marcos Barbero
*/
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = false)
public class ServerProperties implements EmbeddedServletContainerCustomizer, Ordered {
@ -578,6 +579,21 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer, Ord @@ -578,6 +579,21 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer, Ord
private Boolean directBuffers;
/**
* Format pattern for access logs.
*/
private String accessLogPattern;
/**
* Enable access log.
*/
private boolean accessLogEnabled = false;
/**
* Undertow access log directory. If not specified a temporary directory will be used.
*/
private File accessLogDir;
public Integer getBufferSize() {
return this.bufferSize;
}
@ -618,12 +634,39 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer, Ord @@ -618,12 +634,39 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer, Ord
this.directBuffers = directBuffers;
}
public String getAccessLogPattern() {
return accessLogPattern;
}
public void setAccessLogPattern(String accessLogPattern) {
this.accessLogPattern = accessLogPattern;
}
public boolean isAccessLogEnabled() {
return accessLogEnabled;
}
public void setAccessLogEnabled(boolean accessLogEnabled) {
this.accessLogEnabled = accessLogEnabled;
}
public File getAccessLogDir() {
return accessLogDir;
}
public void setAccessLogDir(File accessLogDir) {
this.accessLogDir = accessLogDir;
}
void customizeUndertow(UndertowEmbeddedServletContainerFactory factory) {
factory.setBufferSize(this.bufferSize);
factory.setBuffersPerRegion(this.buffersPerRegion);
factory.setIoThreads(this.ioThreads);
factory.setWorkerThreads(this.workerThreads);
factory.setDirectBuffers(this.directBuffers);
factory.setAccessLogDirectory(this.accessLogDir);
factory.setAccessLogPattern(this.accessLogPattern);
factory.setAccessLogEnabled(this.accessLogEnabled);
}
}

2
spring-boot-samples/spring-boot-sample-undertow/src/test/resources/application.properties

@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
server.undertow.access-log-enabled=true
server.undertow.access-log-pattern=combined

20
spring-boot/src/main/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactory.java

@ -32,6 +32,7 @@ import org.apache.commons.logging.LogFactory; @@ -32,6 +32,7 @@ import org.apache.commons.logging.LogFactory;
*
* @author Phillip Webb
* @author Dave Syer
* @author Marcos Barbero
*/
public abstract class AbstractEmbeddedServletContainerFactory extends
AbstractConfigurableEmbeddedServletContainer implements
@ -78,6 +79,25 @@ public abstract class AbstractEmbeddedServletContainerFactory extends @@ -78,6 +79,25 @@ public abstract class AbstractEmbeddedServletContainerFactory extends
return file;
}
/**
* Returns the absolute temp dir for given web server.
* @param prefix webserver name
* @return The temp dir for given web server.
*/
protected File createTempDir(String prefix) {
try {
File tempFolder = File.createTempFile(prefix + ".", "." + getPort());
tempFolder.delete();
tempFolder.mkdir();
tempFolder.deleteOnExit();
return tempFolder;
}
catch (IOException ex) {
throw new EmbeddedServletContainerException(
String.format("Unable to create %s tempdir", prefix), ex);
}
}
private File getExplodedWarFileDocumentRoot() {
File file = getCodeSourceArchive();
if (this.logger.isDebugEnabled()) {

15
spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java

@ -79,6 +79,7 @@ import org.springframework.util.StringUtils; @@ -79,6 +79,7 @@ import org.springframework.util.StringUtils;
* @author Brock Mills
* @author Stephane Nicoll
* @author Andy Wilkinson
* @author Marcos Barbero
* @see #setPort(int)
* @see #setContextLifecycleListeners(Collection)
* @see TomcatEmbeddedServletContainer
@ -382,20 +383,6 @@ public class TomcatEmbeddedServletContainerFactory extends @@ -382,20 +383,6 @@ public class TomcatEmbeddedServletContainerFactory extends
return new TomcatEmbeddedServletContainer(tomcat, getPort() >= 0);
}
private File createTempDir(String prefix) {
try {
File tempFolder = File.createTempFile(prefix + ".", "." + getPort());
tempFolder.delete();
tempFolder.mkdir();
tempFolder.deleteOnExit();
return tempFolder;
}
catch (IOException ex) {
throw new EmbeddedServletContainerException(
"Unable to create Tomcat tempdir", ex);
}
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;

78
spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java

@ -19,6 +19,10 @@ package org.springframework.boot.context.embedded.undertow; @@ -19,6 +19,10 @@ package org.springframework.boot.context.embedded.undertow;
import io.undertow.Undertow;
import io.undertow.Undertow.Builder;
import io.undertow.UndertowMessages;
import io.undertow.server.HandlerWrapper;
import io.undertow.server.HttpHandler;
import io.undertow.server.handlers.accesslog.AccessLogHandler;
import io.undertow.server.handlers.accesslog.DefaultAccessLogReceiver;
import io.undertow.server.handlers.resource.ClassPathResourceManager;
import io.undertow.server.handlers.resource.FileResourceManager;
import io.undertow.server.handlers.resource.Resource;
@ -69,8 +73,11 @@ import org.springframework.context.ResourceLoaderAware; @@ -69,8 +73,11 @@ import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;
import org.springframework.util.ResourceUtils;
import org.xnio.OptionMap;
import org.xnio.Options;
import org.xnio.SslClientAuthMode;
import org.xnio.XnioWorker;
import org.xnio.Xnio;
/**
* {@link EmbeddedServletContainerFactory} that can be used to create
@ -81,6 +88,7 @@ import org.xnio.SslClientAuthMode; @@ -81,6 +88,7 @@ import org.xnio.SslClientAuthMode;
*
* @author Ivan Sopov
* @author Andy Wilkinson
* @author Marcos Barbero
* @since 1.2.0
* @see UndertowEmbeddedServletContainer
*/
@ -105,6 +113,12 @@ public class UndertowEmbeddedServletContainerFactory extends @@ -105,6 +113,12 @@ public class UndertowEmbeddedServletContainerFactory extends
private Boolean directBuffers;
private File accessLogDirectory;
private String accessLogPattern;
private boolean accessLogEnabled = false;
/**
* Create a new {@link UndertowEmbeddedServletContainerFactory} instance.
*/
@ -337,6 +351,9 @@ public class UndertowEmbeddedServletContainerFactory extends @@ -337,6 +351,9 @@ public class UndertowEmbeddedServletContainerFactory extends
for (UndertowDeploymentInfoCustomizer customizer : this.deploymentInfoCustomizers) {
customizer.customize(deployment);
}
if (isAccessLogEnabled()) {
configureAccessLog(deployment);
}
DeploymentManager manager = Servlets.defaultContainer().addDeployment(deployment);
manager.deploy();
SessionManager sessionManager = manager.getDeployment().getSessionManager();
@ -345,6 +362,51 @@ public class UndertowEmbeddedServletContainerFactory extends @@ -345,6 +362,51 @@ public class UndertowEmbeddedServletContainerFactory extends
return manager;
}
private void configureAccessLog(DeploymentInfo deploymentInfo) {
deploymentInfo.addInitialHandlerChainWrapper(new HandlerWrapper() {
@Override
public HttpHandler wrap(HttpHandler handler) {
try {
String formatString = (accessLogPattern != null) ? accessLogPattern
: "common";
DefaultAccessLogReceiver accessLogReceiver = new DefaultAccessLogReceiver(
createWorker(), getLogsDir(), "access_log");
return new AccessLogHandler(handler, accessLogReceiver, formatString,
Undertow.class.getClassLoader());
}
catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
});
}
private XnioWorker createWorker() throws IOException {
Xnio xnio = Xnio.getInstance(Undertow.class.getClassLoader());
OptionMap.Builder builder = OptionMap.builder();
if(this.ioThreads != null && this.ioThreads > 0) {
builder.set(Options.WORKER_IO_THREADS, ioThreads);
}
if(this.workerThreads != null && this.workerThreads > 0) {
builder.set(Options.WORKER_TASK_CORE_THREADS, workerThreads);
builder.set(Options.WORKER_TASK_MAX_THREADS, workerThreads);
}
return xnio.createWorker(builder.getMap());
}
private File getLogsDir() {
File logsDir;
if (accessLogDirectory != null) {
logsDir = accessLogDirectory;
if (!logsDir.isDirectory() && !logsDir.mkdirs()) {
throw new IllegalStateException("Failed to create logs dir '" + logsDir + "'");
}
} else {
logsDir = createTempDir("undertow");
}
return logsDir;
}
private void registerServletContainerInitializerToDriveServletContextInitializers(
DeploymentInfo deployment, ServletContextInitializer... initializers) {
ServletContextInitializer[] mergedInitializers = mergeInitializers(initializers);
@ -442,6 +504,22 @@ public class UndertowEmbeddedServletContainerFactory extends @@ -442,6 +504,22 @@ public class UndertowEmbeddedServletContainerFactory extends
this.directBuffers = directBuffers;
}
public void setAccessLogDirectory(File accessLogDirectory) {
this.accessLogDirectory = accessLogDirectory;
}
public void setAccessLogPattern(String accessLogPattern) {
this.accessLogPattern = accessLogPattern;
}
public void setAccessLogEnabled(boolean accessLogEnabled) {
this.accessLogEnabled = accessLogEnabled;
}
public boolean isAccessLogEnabled() {
return accessLogEnabled;
}
/**
* Undertow {@link ResourceManager} for JAR resources.
*/

Loading…
Cancel
Save