Polish Undertow access logs contribution
- Apply project’s code formatting and conventions - Don’t use the IO and worker thread configuration when creating the worker for the AccessLogReceiver. The IO and worker thread configuration is for HTTP request processing and a worker in its default configuration should be sufficient for the access log receiver. - Don’t use a temporary directory as the default for the access log directory. A temporary directory makes (some) sense for Tomcat as it requires a directory for its basedir. Undertow has no such requirement and using a temporary directory makes it hard to locate the logs. The default has been updated to a directory named logs, created in the current working directory. - Document the new properties in the application properties appendix Closes gh-3014
This commit is contained in:
parent
90e43737bb
commit
95f31b0d30
|
@ -582,7 +582,7 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer, Ord
|
||||||
/**
|
/**
|
||||||
* Format pattern for access logs.
|
* Format pattern for access logs.
|
||||||
*/
|
*/
|
||||||
private String accessLogPattern;
|
private String accessLogPattern = "common";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable access log.
|
* Enable access log.
|
||||||
|
@ -590,9 +590,9 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer, Ord
|
||||||
private boolean accessLogEnabled = false;
|
private boolean accessLogEnabled = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Undertow access log directory. If not specified a temporary directory will be used.
|
* Undertow access log directory.
|
||||||
*/
|
*/
|
||||||
private File accessLogDir;
|
private File accessLogDir = new File("logs");
|
||||||
|
|
||||||
public Integer getBufferSize() {
|
public Integer getBufferSize() {
|
||||||
return this.bufferSize;
|
return this.bufferSize;
|
||||||
|
@ -635,7 +635,7 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer, Ord
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAccessLogPattern() {
|
public String getAccessLogPattern() {
|
||||||
return accessLogPattern;
|
return this.accessLogPattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAccessLogPattern(String accessLogPattern) {
|
public void setAccessLogPattern(String accessLogPattern) {
|
||||||
|
@ -643,7 +643,7 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer, Ord
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAccessLogEnabled() {
|
public boolean isAccessLogEnabled() {
|
||||||
return accessLogEnabled;
|
return this.accessLogEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAccessLogEnabled(boolean accessLogEnabled) {
|
public void setAccessLogEnabled(boolean accessLogEnabled) {
|
||||||
|
@ -651,7 +651,7 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer, Ord
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getAccessLogDir() {
|
public File getAccessLogDir() {
|
||||||
return accessLogDir;
|
return this.accessLogDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAccessLogDir(File accessLogDir) {
|
public void setAccessLogDir(File accessLogDir) {
|
||||||
|
|
|
@ -95,6 +95,9 @@ content into your application; rather pick only the properties that you need.
|
||||||
server.tomcat.max-http-header-size= # maximum size in bytes of the HTTP message header
|
server.tomcat.max-http-header-size= # maximum size in bytes of the HTTP message header
|
||||||
server.tomcat.max-threads = 0 # number of threads in protocol handler
|
server.tomcat.max-threads = 0 # number of threads in protocol handler
|
||||||
server.tomcat.uri-encoding = UTF-8 # character encoding to use for URL decoding
|
server.tomcat.uri-encoding = UTF-8 # character encoding to use for URL decoding
|
||||||
|
server.undertow.access-log-enabled=false # if access logging is enabled
|
||||||
|
server.undertow.access-log-pattern=common # log pattern of the access log
|
||||||
|
server.undertow.access-log-dir=logs # access logs directory
|
||||||
|
|
||||||
# SPRING MVC ({sc-spring-boot-autoconfigure}/web/WebMvcProperties.{sc-ext}[WebMvcProperties])
|
# SPRING MVC ({sc-spring-boot-autoconfigure}/web/WebMvcProperties.{sc-ext}[WebMvcProperties])
|
||||||
spring.mvc.locale= # set fixed locale, e.g. en_UK
|
spring.mvc.locale= # set fixed locale, e.g. en_UK
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
server.undertow.access-log-enabled=true
|
||||||
|
server.undertow.access-log-dir=target/logs
|
||||||
|
server.undertow.access-log-pattern=combined
|
|
@ -1,2 +0,0 @@
|
||||||
server.undertow.access-log-enabled=true
|
|
||||||
server.undertow.access-log-pattern=combined
|
|
|
@ -32,7 +32,6 @@ import org.apache.commons.logging.LogFactory;
|
||||||
*
|
*
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
* @author Marcos Barbero
|
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractEmbeddedServletContainerFactory extends
|
public abstract class AbstractEmbeddedServletContainerFactory extends
|
||||||
AbstractConfigurableEmbeddedServletContainer implements
|
AbstractConfigurableEmbeddedServletContainer implements
|
||||||
|
@ -79,25 +78,6 @@ public abstract class AbstractEmbeddedServletContainerFactory extends
|
||||||
return file;
|
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() {
|
private File getExplodedWarFileDocumentRoot() {
|
||||||
File file = getCodeSourceArchive();
|
File file = getCodeSourceArchive();
|
||||||
if (this.logger.isDebugEnabled()) {
|
if (this.logger.isDebugEnabled()) {
|
||||||
|
|
|
@ -79,7 +79,6 @@ import org.springframework.util.StringUtils;
|
||||||
* @author Brock Mills
|
* @author Brock Mills
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @author Andy Wilkinson
|
* @author Andy Wilkinson
|
||||||
* @author Marcos Barbero
|
|
||||||
* @see #setPort(int)
|
* @see #setPort(int)
|
||||||
* @see #setContextLifecycleListeners(Collection)
|
* @see #setContextLifecycleListeners(Collection)
|
||||||
* @see TomcatEmbeddedServletContainer
|
* @see TomcatEmbeddedServletContainer
|
||||||
|
@ -388,6 +387,25 @@ public class TomcatEmbeddedServletContainerFactory extends
|
||||||
this.resourceLoader = resourceLoader;
|
this.resourceLoader = resourceLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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(
|
||||||
|
"Unable to create Tomcat tempdir", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the Tomcat base directory. If not specified a temporary directory will be used.
|
* Set the Tomcat base directory. If not specified a temporary directory will be used.
|
||||||
* @param baseDirectory the tomcat base directory
|
* @param baseDirectory the tomcat base directory
|
||||||
|
|
|
@ -22,6 +22,7 @@ import io.undertow.UndertowMessages;
|
||||||
import io.undertow.server.HandlerWrapper;
|
import io.undertow.server.HandlerWrapper;
|
||||||
import io.undertow.server.HttpHandler;
|
import io.undertow.server.HttpHandler;
|
||||||
import io.undertow.server.handlers.accesslog.AccessLogHandler;
|
import io.undertow.server.handlers.accesslog.AccessLogHandler;
|
||||||
|
import io.undertow.server.handlers.accesslog.AccessLogReceiver;
|
||||||
import io.undertow.server.handlers.accesslog.DefaultAccessLogReceiver;
|
import io.undertow.server.handlers.accesslog.DefaultAccessLogReceiver;
|
||||||
import io.undertow.server.handlers.resource.ClassPathResourceManager;
|
import io.undertow.server.handlers.resource.ClassPathResourceManager;
|
||||||
import io.undertow.server.handlers.resource.FileResourceManager;
|
import io.undertow.server.handlers.resource.FileResourceManager;
|
||||||
|
@ -76,8 +77,8 @@ import org.springframework.util.ResourceUtils;
|
||||||
import org.xnio.OptionMap;
|
import org.xnio.OptionMap;
|
||||||
import org.xnio.Options;
|
import org.xnio.Options;
|
||||||
import org.xnio.SslClientAuthMode;
|
import org.xnio.SslClientAuthMode;
|
||||||
import org.xnio.XnioWorker;
|
|
||||||
import org.xnio.Xnio;
|
import org.xnio.Xnio;
|
||||||
|
import org.xnio.XnioWorker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link EmbeddedServletContainerFactory} that can be used to create
|
* {@link EmbeddedServletContainerFactory} that can be used to create
|
||||||
|
@ -366,47 +367,40 @@ public class UndertowEmbeddedServletContainerFactory extends
|
||||||
deploymentInfo.addInitialHandlerChainWrapper(new HandlerWrapper() {
|
deploymentInfo.addInitialHandlerChainWrapper(new HandlerWrapper() {
|
||||||
@Override
|
@Override
|
||||||
public HttpHandler wrap(HttpHandler handler) {
|
public HttpHandler wrap(HttpHandler handler) {
|
||||||
try {
|
return createAccessLogHandler(handler);
|
||||||
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 AccessLogHandler createAccessLogHandler(HttpHandler handler) {
|
||||||
|
try {
|
||||||
|
createAccessLogDirectoryIfNecessary();
|
||||||
|
AccessLogReceiver accessLogReceiver = new DefaultAccessLogReceiver(
|
||||||
|
createWorker(), this.accessLogDirectory, "access_log");
|
||||||
|
String formatString = (this.accessLogPattern != null) ? this.accessLogPattern
|
||||||
|
: "common";
|
||||||
|
return new AccessLogHandler(handler, accessLogReceiver, formatString,
|
||||||
|
Undertow.class.getClassLoader());
|
||||||
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
|
throw new IllegalStateException("Failed to create AccessLogHandler", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createAccessLogDirectoryIfNecessary() {
|
||||||
|
Assert.notNull(this.accessLogDirectory, "accesslogDirectory must not be null");
|
||||||
|
if (!this.accessLogDirectory.isDirectory() && !this.accessLogDirectory.mkdirs()) {
|
||||||
|
throw new IllegalStateException("Failed to create access log directory '"
|
||||||
|
+ this.accessLogDirectory + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private XnioWorker createWorker() throws IOException {
|
private XnioWorker createWorker() throws IOException {
|
||||||
Xnio xnio = Xnio.getInstance(Undertow.class.getClassLoader());
|
Xnio xnio = Xnio.getInstance(Undertow.class.getClassLoader());
|
||||||
OptionMap.Builder builder = OptionMap.builder();
|
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());
|
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(
|
private void registerServletContainerInitializerToDriveServletContextInitializers(
|
||||||
DeploymentInfo deployment, ServletContextInitializer... initializers) {
|
DeploymentInfo deployment, ServletContextInitializer... initializers) {
|
||||||
ServletContextInitializer[] mergedInitializers = mergeInitializers(initializers);
|
ServletContextInitializer[] mergedInitializers = mergeInitializers(initializers);
|
||||||
|
@ -517,7 +511,7 @@ public class UndertowEmbeddedServletContainerFactory extends
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAccessLogEnabled() {
|
public boolean isAccessLogEnabled() {
|
||||||
return accessLogEnabled;
|
return this.accessLogEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue