All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.dropwizard.logging.AbstractAppenderFactory Maven / Gradle / Ivy

There is a newer version: 5.0.0-alpha.5
Show newest version
package io.dropwizard.logging;

import ch.qos.logback.classic.AsyncAppender;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.AsyncAppenderBase;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.LayoutBase;
import ch.qos.logback.core.pattern.PatternLayoutBase;
import ch.qos.logback.core.spi.DeferredProcessingAware;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.dropwizard.logback.ThrottlingAppenderWrapper;
import io.dropwizard.logging.async.AsyncAppenderFactory;
import io.dropwizard.logging.filter.FilterFactory;
import io.dropwizard.logging.layout.DiscoverableLayoutFactory;
import io.dropwizard.logging.layout.LayoutFactory;
import io.dropwizard.util.Strings;
import io.dropwizard.util.Duration;
import io.dropwizard.validation.MaxDuration;
import io.dropwizard.validation.MinDuration;

import javax.annotation.Nullable;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;

/**
 * A base implementation of {@link AppenderFactory}.
 * 

* Configuration Parameters: *

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
NameDefaultDescription
{@code threshold}ALLThe minimum event level the appender will handle.
{@code logFormat}(none)An appender-specific log format.
{@code timeZone}{@code UTC} * The time zone to which event timestamps will be converted. * Ignored if logFormat is supplied. *
{@code queueSize}{@link AsyncAppenderBase}The maximum capacity of the blocking queue.
{@code includeCallerData}{@link AsyncAppenderBase} * Whether to include caller data, required for line numbers. * Beware, is considered expensive. *
{@code discardingThreshold}{@link AsyncAppenderBase} * By default, when the blocking queue has 20% capacity remaining, * it will drop events of level TRACE, DEBUG and INFO, keeping only * events of level WARN and ERROR. To keep all events, set discardingThreshold to 0. *
{@code messageRate} * Maximum message rate: average duration between messages. Extra messages are discarded. * This setting avoids flooding a paid logging service by accident. * For example, a duration of 100ms allows for a maximum of 10 messages per second and 30s would mean * 1 message every 30 seconds. * The maximum acceptable duration is 1 minute. * By default, this duration is not set and this feature is disabled. *
{@code filterFactories}(none) * A list of {@link FilterFactory filters} to apply to the appender, in order, * after the {@code threshold}. *
*/ public abstract class AbstractAppenderFactory implements AppenderFactory { @NotNull protected Level threshold = Level.ALL; @Nullable protected String logFormat; @Nullable protected DiscoverableLayoutFactory layout; @NotNull protected TimeZone timeZone = TimeZone.getTimeZone("UTC"); @Min(1) @Max(Integer.MAX_VALUE) private int queueSize = AsyncAppenderBase.DEFAULT_QUEUE_SIZE; private int discardingThreshold = -1; @Nullable @MinDuration(value = 0, unit = TimeUnit.SECONDS, inclusive = false) @MaxDuration(value = 1, unit = TimeUnit.MINUTES) private Duration messageRate; private boolean includeCallerData = false; private List> filterFactories = Collections.emptyList(); private boolean neverBlock = false; @JsonProperty public int getQueueSize() { return queueSize; } @JsonProperty public void setQueueSize(int queueSize) { this.queueSize = queueSize; } @JsonProperty public int getDiscardingThreshold() { return discardingThreshold; } @JsonProperty public void setDiscardingThreshold(int discardingThreshold) { this.discardingThreshold = discardingThreshold; } /** * @since 2.0 */ @JsonProperty @Nullable public Duration getMessageRate() { return messageRate; } /** * @since 2.0 */ @JsonProperty public void setMessageRate(Duration messageRate) { this.messageRate = messageRate; } @JsonProperty public String getThreshold() { return threshold.toString(); } @JsonProperty public void setThreshold(String threshold) { this.threshold = DefaultLoggingFactory.toLevel(threshold); } @JsonProperty @Nullable public String getLogFormat() { return logFormat; } @JsonProperty public void setLogFormat(@Nullable String logFormat) { this.logFormat = logFormat; } @JsonProperty public TimeZone getTimeZone() { return timeZone; } @JsonProperty public void setTimeZone(String zoneId) { this.timeZone = Strings.nullToEmpty(zoneId).equalsIgnoreCase("system") ? TimeZone.getDefault() : TimeZone.getTimeZone(zoneId); } @JsonProperty public void setTimeZone(TimeZone timeZone) { this.timeZone = timeZone; } @JsonProperty public boolean isIncludeCallerData() { return includeCallerData; } @JsonProperty public void setIncludeCallerData(boolean includeCallerData) { this.includeCallerData = includeCallerData; } @JsonProperty public List> getFilterFactories() { return filterFactories; } @JsonProperty public void setFilterFactories(List> appenders) { this.filterFactories = new ArrayList<>(appenders); } @JsonProperty public void setNeverBlock(boolean neverBlock) { this.neverBlock = neverBlock; } @Nullable public DiscoverableLayoutFactory getLayout() { return layout; } public void setLayout(@Nullable DiscoverableLayoutFactory layout) { this.layout = layout; } protected Appender wrapAsync(Appender appender, AsyncAppenderFactory asyncAppenderFactory) { return wrapAsync(appender, asyncAppenderFactory, appender.getContext()); } protected Appender wrapAsync(Appender appender, AsyncAppenderFactory asyncAppenderFactory, Context context) { final AsyncAppenderBase asyncAppender = asyncAppenderFactory.build(); if (asyncAppender instanceof AsyncAppender) { ((AsyncAppender) asyncAppender).setIncludeCallerData(includeCallerData); } asyncAppender.setQueueSize(queueSize); asyncAppender.setDiscardingThreshold(discardingThreshold); asyncAppender.setContext(context); asyncAppender.setName("async-" + appender.getName()); asyncAppender.addAppender(appender); asyncAppender.setNeverBlock(neverBlock); asyncAppender.start(); if (messageRate == null) { return asyncAppender; } else { return new ThrottlingAppenderWrapper<>(asyncAppender, messageRate.getQuantity(), messageRate.getUnit()); } } protected LayoutBase buildLayout(LoggerContext context, LayoutFactory defaultLayoutFactory) { final LayoutBase layoutBase; if (layout == null) { final PatternLayoutBase patternLayoutBase = defaultLayoutFactory.build(context, timeZone); if (!Strings.isNullOrEmpty(logFormat)) { patternLayoutBase.setPattern(logFormat); } layoutBase = patternLayoutBase; } else { layoutBase = layout.build(context, timeZone); } layoutBase.start(); return layoutBase; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy