Skip to content

Commit

Permalink
Merge pull request #1415 from ghenkes/logback-access
Browse files Browse the repository at this point in the history
Add a Logback Access RequestLog implementation
  • Loading branch information
arteam committed Jan 29, 2016
2 parents 79cb3d6 + 6dbfb7d commit 9dc046a
Show file tree
Hide file tree
Showing 41 changed files with 715 additions and 146 deletions.
10 changes: 10 additions & 0 deletions dropwizard-bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,11 @@
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
Expand Down Expand Up @@ -771,6 +776,11 @@
<artifactId>dropwizard-migrations</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-request-logging</artifactId>
<version>${dropwizard.version}</version>
</dependency>
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-servlets</artifactId>
Expand Down
4 changes: 4 additions & 0 deletions dropwizard-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-healthchecks</artifactId>
</dependency>
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-request-logging</artifactId>
</dependency>
<dependency>
<groupId>net.sourceforge.argparse4j</groupId>
<artifactId>argparse4j</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
import io.dropwizard.jetty.GzipHandlerFactory;
import io.dropwizard.jetty.MutableServletContextHandler;
import io.dropwizard.jetty.NonblockingServletHolder;
import io.dropwizard.jetty.RequestLogFactory;
import io.dropwizard.jetty.Slf4jRequestLogFactory;
import io.dropwizard.jetty.ServerPushFilterFactory;
import io.dropwizard.lifecycle.setup.LifecycleEnvironment;
import io.dropwizard.request.logging.LogbackAccessRequestLogFactory;
import io.dropwizard.request.logging.RequestLogFactory;
import io.dropwizard.servlets.ThreadNameFilter;
import io.dropwizard.util.Duration;
import io.dropwizard.validation.MinDuration;
Expand Down Expand Up @@ -209,7 +209,7 @@ public abstract class AbstractServerFactory implements ServerFactory {

@Valid
@NotNull
private RequestLogFactory requestLog = new Slf4jRequestLogFactory();
private RequestLogFactory requestLog = new LogbackAccessRequestLogFactory();

@Valid
@NotNull
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
import ch.qos.logback.classic.AsyncAppender;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.filter.ThresholdFilter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.AsyncAppenderBase;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.spi.FilterAttachable;
import ch.qos.logback.core.pattern.PatternLayoutBase;
import ch.qos.logback.core.spi.DeferredProcessingAware;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Strings;
import io.dropwizard.logging.async.AsyncAppenderFactory;
import io.dropwizard.logging.layout.LayoutFactory;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
Expand Down Expand Up @@ -38,6 +39,14 @@
* <td>An appender-specific log format.</td>
* </tr>
* <tr>
* <td>{@code timeZone}</td>
* <td>{@code UTC}</td>
* <td>
* The time zone to which event timestamps will be converted.
* Ignored if logFormat is supplied.
* </td>
* </tr>
* <tr>
* <td>{@code queueSize}</td>
* <td>{@link AsyncAppenderBase}</td>
* <td>The maximum capacity of the blocking queue.</td>
Expand All @@ -61,12 +70,16 @@
* </tr>
* </table>
*/
public abstract class AbstractAppenderFactory implements AppenderFactory {
public abstract class AbstractAppenderFactory<E extends DeferredProcessingAware> implements AppenderFactory<E> {

@NotNull
protected Level threshold = Level.ALL;

protected String logFormat;

@NotNull
protected TimeZone timeZone = TimeZone.getTimeZone("UTC");

@Min(1)
@Max(Integer.MAX_VALUE)
private int queueSize = AsyncAppenderBase.DEFAULT_QUEUE_SIZE;
Expand Down Expand Up @@ -115,6 +128,16 @@ public void setLogFormat(String logFormat) {
this.logFormat = logFormat;
}

@JsonProperty
public TimeZone getTimeZone() {
return timeZone;
}

@JsonProperty
public void setTimeZone(TimeZone timeZone) {
this.timeZone = timeZone;
}

@JsonProperty
public boolean isIncludeCallerData() {
return includeCallerData;
Expand All @@ -125,13 +148,15 @@ public void setIncludeCallerData(boolean includeCallerData) {
this.includeCallerData = includeCallerData;
}

protected Appender<ILoggingEvent> wrapAsync(Appender<ILoggingEvent> appender) {
return wrapAsync(appender, appender.getContext());
protected Appender<E> wrapAsync(Appender<E> appender, AsyncAppenderFactory<E> asyncAppenderFactory) {
return wrapAsync(appender, asyncAppenderFactory, appender.getContext());
}

protected Appender<ILoggingEvent> wrapAsync(Appender<ILoggingEvent> appender, Context context) {
final AsyncAppender asyncAppender = new AsyncAppender();
asyncAppender.setIncludeCallerData(includeCallerData);
protected Appender<E> wrapAsync(Appender<E> appender, AsyncAppenderFactory<E> asyncAppenderFactory, Context context) {
final AsyncAppenderBase<E> asyncAppender = asyncAppenderFactory.build();
if (asyncAppender instanceof AsyncAppender) {
((AsyncAppender) asyncAppender).setIncludeCallerData(includeCallerData);
}
asyncAppender.setQueueSize(queueSize);
asyncAppender.setDiscardingThreshold(discardingThreshold);
asyncAppender.setContext(context);
Expand All @@ -141,15 +166,8 @@ protected Appender<ILoggingEvent> wrapAsync(Appender<ILoggingEvent> appender, Co
return asyncAppender;
}

protected void addThresholdFilter(FilterAttachable<ILoggingEvent> appender, Level threshold) {
final ThresholdFilter filter = new ThresholdFilter();
filter.setLevel(threshold.toString());
filter.start();
appender.addFilter(filter);
}

protected DropwizardLayout buildLayout(LoggerContext context, TimeZone timeZone) {
final DropwizardLayout formatter = new DropwizardLayout(context, timeZone);
protected PatternLayoutBase<E> buildLayout(LoggerContext context, LayoutFactory<E> layoutFactory) {
final PatternLayoutBase<E> formatter = layoutFactory.build(context, timeZone);
if (!Strings.isNullOrEmpty(logFormat)) {
formatter.setPattern(logFormat);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package io.dropwizard.logging;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.Layout;
import ch.qos.logback.core.spi.DeferredProcessingAware;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.dropwizard.jackson.Discoverable;
import io.dropwizard.logging.async.AsyncAppenderFactory;
import io.dropwizard.logging.filter.LevelFilterFactory;
import io.dropwizard.logging.layout.LayoutFactory;

/**
* A service provider interface for creating Logback {@link Appender} instances.
Expand All @@ -23,16 +25,21 @@
* @see SyslogAppenderFactory
*/
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
public interface AppenderFactory extends Discoverable {
public interface AppenderFactory<E extends DeferredProcessingAware> extends Discoverable {
/**
* Given a Logback context, an application name, and a layout, build a new appender.
* Given a Logback context, an application name, a layout,
* a levelFilterFactory, and an asyncAppenderFactory build a new appender.
*
* @param context the Logback context
* @param applicationName the application name
* @param layout the layout for logging
* @param layoutFactory the factory for the layout for logging
* @param levelFilterFactory the factory for the level filter
* @param asyncAppenderFactory the factory for the async appender
* @return a new, started {@link Appender}
*/
Appender<ILoggingEvent> build(LoggerContext context,
Appender<E> build(LoggerContext context,
String applicationName,
Layout<ILoggingEvent> layout);
LayoutFactory<E> layoutFactory,
LevelFilterFactory<E> levelFilterFactory,
AsyncAppenderFactory<E> asyncAppenderFactory);
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package io.dropwizard.logging;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.ConsoleAppender;
import ch.qos.logback.core.Layout;
import ch.qos.logback.core.encoder.LayoutWrappingEncoder;
import ch.qos.logback.core.spi.DeferredProcessingAware;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import io.dropwizard.logging.async.AsyncAppenderFactory;
import io.dropwizard.logging.filter.LevelFilterFactory;
import io.dropwizard.logging.layout.LayoutFactory;

import javax.validation.constraints.NotNull;
import java.util.TimeZone;

/**
* An {@link AppenderFactory} implementation which provides an appender that writes events to the console.
Expand Down Expand Up @@ -59,7 +60,7 @@
* @see AbstractAppenderFactory
*/
@JsonTypeName("console")
public class ConsoleAppenderFactory extends AbstractAppenderFactory {
public class ConsoleAppenderFactory<E extends DeferredProcessingAware> extends AbstractAppenderFactory<E> {
@SuppressWarnings("UnusedDeclaration")
public enum ConsoleStream {
STDOUT("System.out"),
Expand All @@ -76,22 +77,9 @@ public String get() {
}
}

@NotNull
private TimeZone timeZone = TimeZone.getTimeZone("UTC");

@NotNull
private ConsoleStream target = ConsoleStream.STDOUT;

@JsonProperty
public TimeZone getTimeZone() {
return timeZone;
}

@JsonProperty
public void setTimeZone(TimeZone timeZone) {
this.timeZone = timeZone;
}

@JsonProperty
public ConsoleStream getTarget() {
return target;
Expand All @@ -103,19 +91,20 @@ public void setTarget(ConsoleStream target) {
}

@Override
public Appender<ILoggingEvent> build(LoggerContext context, String applicationName, Layout<ILoggingEvent> layout) {
final ConsoleAppender<ILoggingEvent> appender = new ConsoleAppender<>();
public Appender<E> build(LoggerContext context, String applicationName, LayoutFactory<E> layoutFactory,
LevelFilterFactory<E> levelFilterFactory, AsyncAppenderFactory<E> asyncAppenderFactory) {
final ConsoleAppender<E> appender = new ConsoleAppender<>();
appender.setName("console-appender");
appender.setContext(context);
appender.setTarget(target.get());

final LayoutWrappingEncoder<ILoggingEvent> layoutEncoder = new LayoutWrappingEncoder<>();
layoutEncoder.setLayout(layout == null ? buildLayout(context, timeZone) : layout);
final LayoutWrappingEncoder<E> layoutEncoder = new LayoutWrappingEncoder<>();
layoutEncoder.setLayout(buildLayout(context, layoutFactory));
appender.setEncoder(layoutEncoder);

addThresholdFilter(appender, threshold);
appender.addFilter(levelFilterFactory.build(threshold));
appender.start();

return wrapAsync(appender);
return wrapAsync(appender, asyncAppenderFactory);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.jmx.JMXConfigurator;
import ch.qos.logback.classic.jul.LevelChangePropagator;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.util.StatusPrinter;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.logback.InstrumentedAppender;
Expand All @@ -18,6 +19,12 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import io.dropwizard.jackson.Jackson;
import io.dropwizard.logging.async.AsyncAppenderFactory;
import io.dropwizard.logging.async.AsyncLoggingEventAppenderFactory;
import io.dropwizard.logging.filter.LevelFilterFactory;
import io.dropwizard.logging.filter.ThresholdLevelFilterFactory;
import io.dropwizard.logging.layout.DropwizardLayoutFactory;
import io.dropwizard.logging.layout.LayoutFactory;

import javax.management.InstanceAlreadyExistsException;
import javax.management.MalformedObjectNameException;
Expand Down Expand Up @@ -48,8 +55,8 @@ public class DefaultLoggingFactory implements LoggingFactory {

@Valid
@NotNull
private ImmutableList<AppenderFactory> appenders = ImmutableList.<AppenderFactory>of(
new ConsoleAppenderFactory()
private ImmutableList<AppenderFactory<ILoggingEvent>> appenders = ImmutableList.<AppenderFactory<ILoggingEvent>>of(
new ConsoleAppenderFactory<>()
);

@JsonIgnore
Expand Down Expand Up @@ -99,12 +106,12 @@ public void setLoggers(Map<String, JsonNode> loggers) {
}

@JsonProperty
public ImmutableList<AppenderFactory> getAppenders() {
public ImmutableList<AppenderFactory<ILoggingEvent>> getAppenders() {
return appenders;
}

@JsonProperty
public void setAppenders(List<AppenderFactory> appenders) {
public void setAppenders(List<AppenderFactory<ILoggingEvent>> appenders) {
this.appenders = ImmutableList.copyOf(appenders);
}

Expand All @@ -119,8 +126,12 @@ public void configure(MetricRegistry metricRegistry, String name) {
CHANGE_LOGGER_CONTEXT_LOCK.unlock();
}

for (AppenderFactory output : appenders) {
root.addAppender(output.build(loggerContext, name, null));
final LevelFilterFactory<ILoggingEvent> levelFilterFactory = new ThresholdLevelFilterFactory();
final AsyncAppenderFactory<ILoggingEvent> asyncAppenderFactory = new AsyncLoggingEventAppenderFactory();
final LayoutFactory<ILoggingEvent> layoutFactory = new DropwizardLayoutFactory();

for (AppenderFactory<ILoggingEvent> output : appenders) {
root.addAppender(output.build(loggerContext, name, layoutFactory, levelFilterFactory, asyncAppenderFactory));
}

StatusPrinter.setPrintStream(configurationErrorsStream);
Expand Down Expand Up @@ -179,6 +190,10 @@ private Logger configureLoggers(String name) {

root.setLevel(level);

final LevelFilterFactory<ILoggingEvent> levelFilterFactory = new ThresholdLevelFilterFactory();
final AsyncAppenderFactory<ILoggingEvent> asyncAppenderFactory = new AsyncLoggingEventAppenderFactory();
final LayoutFactory<ILoggingEvent> layoutFactory = new DropwizardLayoutFactory();

for (Map.Entry<String, JsonNode> entry : loggers.entrySet()) {
final Logger logger = loggerContext.getLogger(entry.getKey());
final JsonNode jsonNode = entry.getValue();
Expand All @@ -195,8 +210,9 @@ private Logger configureLoggers(String name) {
}
logger.setLevel(configuration.getLevel());
logger.setAdditive(configuration.isAdditive());
for (AppenderFactory appender : configuration.getAppenders()) {
logger.addAppender(appender.build(loggerContext, name, null));

for (AppenderFactory<ILoggingEvent> appender : configuration.getAppenders()) {
logger.addAppender(appender.build(loggerContext, name, layoutFactory, levelFilterFactory, asyncAppenderFactory));
}
} else {
throw new IllegalArgumentException("Unsupported format of logger '" + entry.getKey() + "'");
Expand Down
Loading

0 comments on commit 9dc046a

Please sign in to comment.