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
This commit is contained in:
committed by
Andy Wilkinson
parent
3eb5c348fb
commit
90e43737bb
@@ -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
|
||||
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
server.undertow.access-log-enabled=true
|
||||
server.undertow.access-log-pattern=combined
|
||||
@@ -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
|
||||
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()) {
|
||||
|
||||
@@ -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
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
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;
|
||||
*
|
||||
* @author Ivan Sopov
|
||||
* @author Andy Wilkinson
|
||||
* @author Marcos Barbero
|
||||
* @since 1.2.0
|
||||
* @see UndertowEmbeddedServletContainer
|
||||
*/
|
||||
@@ -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
|
||||
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
|
||||
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
|
||||
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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user