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

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

package io.dropwizard.logging;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.FileAppender;
import ch.qos.logback.core.encoder.LayoutWrappingEncoder;
import ch.qos.logback.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy;
import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP;
import ch.qos.logback.core.rolling.TimeBasedFileNamingAndTriggeringPolicy;
import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
import ch.qos.logback.core.rolling.FixedWindowRollingPolicy;
import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy;
import ch.qos.logback.core.spi.DeferredProcessingAware;
import com.fasterxml.jackson.annotation.JsonIgnore;
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 io.dropwizard.util.Size;
import io.dropwizard.validation.ValidationMethod;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;

/**
 * An {@link AppenderFactory} implementation which provides an appender that writes events to a file, archiving older
 * files as it goes.
 * 

* Configuration Parameters: *

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
NameDefaultDescription
{@code type}REQUIREDThe appender type. Must be {@code file}.
{@code threshold}{@code ALL}The lowest level of events to write to the file.
{@code currentLogFilename}REQUIREDThe filename where current events are logged.
{@code archive}{@code true}Whether or not to archive old events in separate files.
{@code archivedLogFilenamePattern}REQUIRED if {@code archive} is {@code true}. * The filename pattern for archived files. {@code %d} is replaced with the date in {@code yyyy-MM-dd} form, * and the fact that it ends with {@code .gz} indicates the file will be gzipped as it's archived. Likewise, * filename patterns which end in {@code .zip} will be filled as they are archived. *
{@code archivedFileCount}{@code 5} * The number of archived files to keep. Must be greater than {@code 0}. *
{@code maxFileSize}(unlimited) * The maximum size of the currently active file before a rollover is triggered. The value can be expressed * in bytes, kilobytes, megabytes, gigabytes, and terabytes by appending B, K, MB, GB, or TB to the * numeric value. Examples include 100MB, 1GB, 1TB. Sizes can also be spelled out, such as 100 megabytes, * 1 gigabyte, 1 terabyte. *
{@code timeZone}{@code UTC}The time zone to which event timestamps will be converted.
{@code logFormat}the default format * The Logback pattern with which events will be formatted. See * the Logback documentation * for details. *
* * @see AbstractAppenderFactory */ @JsonTypeName("file") public class FileAppenderFactory extends AbstractAppenderFactory { @NotNull private String currentLogFilename; private boolean archive = true; private String archivedLogFilenamePattern; @Min(1) private int archivedFileCount = 5; private Size maxFileSize; @JsonProperty public String getCurrentLogFilename() { return currentLogFilename; } @JsonProperty public void setCurrentLogFilename(String currentLogFilename) { this.currentLogFilename = currentLogFilename; } @JsonProperty public boolean isArchive() { return archive; } @JsonProperty public void setArchive(boolean archive) { this.archive = archive; } @JsonProperty public String getArchivedLogFilenamePattern() { return archivedLogFilenamePattern; } @JsonProperty public void setArchivedLogFilenamePattern(String archivedLogFilenamePattern) { this.archivedLogFilenamePattern = archivedLogFilenamePattern; } @JsonProperty public int getArchivedFileCount() { return archivedFileCount; } @JsonProperty public void setArchivedFileCount(int archivedFileCount) { this.archivedFileCount = archivedFileCount; } @JsonProperty public Size getMaxFileSize() { return maxFileSize; } @JsonProperty public void setMaxFileSize(Size maxFileSize) { this.maxFileSize = maxFileSize; } @JsonIgnore @ValidationMethod(message = "must have archivedLogFilenamePattern if archive is true") public boolean isValidArchiveConfiguration() { return !archive || (archivedLogFilenamePattern != null); } @JsonIgnore @ValidationMethod(message = "when specifying maxFileSize, archivedLogFilenamePattern must contain %i") public boolean isValidForMaxFileSizeSetting() { return !archive || maxFileSize == null || (archivedLogFilenamePattern != null && archivedLogFilenamePattern.contains("%i")); } @JsonIgnore @ValidationMethod(message = "when archivedLogFilenamePattern contains %i, maxFileSize must be specified") public boolean isMaxFileSizeSettingSpecified() { return !archive || !(archivedLogFilenamePattern != null && archivedLogFilenamePattern.contains("%i")) || maxFileSize != null; } @Override public Appender build(LoggerContext context, String applicationName, LayoutFactory layoutFactory, LevelFilterFactory levelFilterFactory, AsyncAppenderFactory asyncAppenderFactory) { final FileAppender appender = buildAppender(context); appender.setName("file-appender"); appender.setAppend(true); appender.setContext(context); final LayoutWrappingEncoder layoutEncoder = new LayoutWrappingEncoder<>(); layoutEncoder.setLayout(buildLayout(context, layoutFactory)); appender.setEncoder(layoutEncoder); appender.setPrudent(false); appender.addFilter(levelFilterFactory.build(threshold)); getFilterFactories().stream().forEach(f -> appender.addFilter(f.build())); appender.stop(); appender.start(); return wrapAsync(appender, asyncAppenderFactory); } protected FileAppender buildAppender(LoggerContext context) { if (archive) { final RollingFileAppender appender = new RollingFileAppender<>(); appender.setFile(currentLogFilename); if (maxFileSize != null && !archivedLogFilenamePattern.contains("%d")) { final FixedWindowRollingPolicy rollingPolicy = new FixedWindowRollingPolicy(); final SizeBasedTriggeringPolicy triggeringPolicy = new SizeBasedTriggeringPolicy<>(); triggeringPolicy.setMaxFileSize(String.valueOf(maxFileSize.toBytes())); triggeringPolicy.setContext(context); rollingPolicy.setContext(context); rollingPolicy.setMaxIndex(getArchivedFileCount()); rollingPolicy.setFileNamePattern(getArchivedLogFilenamePattern()); appender.setRollingPolicy(rollingPolicy); appender.setTriggeringPolicy(triggeringPolicy); rollingPolicy.setParent(appender); rollingPolicy.start(); return appender; } else { final TimeBasedFileNamingAndTriggeringPolicy triggeringPolicy; if (maxFileSize == null) { triggeringPolicy = new DefaultTimeBasedFileNamingAndTriggeringPolicy<>(); } else { final SizeAndTimeBasedFNATP maxFileSizeTriggeringPolicy = new SizeAndTimeBasedFNATP<>(); maxFileSizeTriggeringPolicy.setMaxFileSize(String.valueOf(maxFileSize.toBytes())); triggeringPolicy = maxFileSizeTriggeringPolicy; } triggeringPolicy.setContext(context); final TimeBasedRollingPolicy rollingPolicy = new TimeBasedRollingPolicy<>(); rollingPolicy.setContext(context); rollingPolicy.setFileNamePattern(archivedLogFilenamePattern); rollingPolicy.setTimeBasedFileNamingAndTriggeringPolicy( triggeringPolicy); triggeringPolicy.setTimeBasedRollingPolicy(rollingPolicy); rollingPolicy.setMaxHistory(archivedFileCount); appender.setRollingPolicy(rollingPolicy); appender.setTriggeringPolicy(triggeringPolicy); rollingPolicy.setParent(appender); rollingPolicy.start(); return appender; } } final FileAppender appender = new FileAppender<>(); appender.setFile(currentLogFilename); return appender; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy