/* * Copyright (C) 2015 Commerce Technologies, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.commercehub.dropwizard.logging; 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.Layout; import ch.qos.logback.core.spi.FilterAttachable; import com.commercehub.dropwizard.redis.JedisPoolConfigFactory; import com.commercehub.logging.logback.AsyncAppender; import com.commercehub.logging.logback.redis.RedisAppender; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeName; import io.dropwizard.logging.AppenderFactory; import io.dropwizard.util.Duration; import org.hibernate.validator.constraints.NotBlank; import javax.validation.Valid; import javax.validation.constraints.Max; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; @JsonTypeName("logstash") public class LogstashAppenderFactory implements AppenderFactory { private static final String LOGSTASH_APPENDER_NAME = "logstash-appender"; private static final String REDIS_APPENDER_NAME = "redis-appender"; @NotBlank private String host = RedisAppender.DEFAULT_HOST; @Min(0L) @Max(65535L) private int port = RedisAppender.DEFAULT_PORT; @NotNull private Duration timeout = Duration.milliseconds(RedisAppender.DEFAULT_TIMEOUT); private String password; @Min(0L) @Max(65535L) private int database = RedisAppender.DEFAULT_DATABASE; @NotBlank private String key; @NotNull private Level threshold = Level.INFO; @Min(1L) @Max(65535L) private int queueSize = AsyncAppender.DEFAULT_QUEUE_SIZE; @Min(-1L) @Max(65535L) private int discardingThreshold = AsyncAppender.DISCARDING_THRESHOLD_UNDEFINED; @Valid @NotNull private JedisPoolConfigFactory pool = new JedisPoolConfigFactory(); @Valid @NotNull private LogstashEventLayoutFactory layout = new LogstashEventLayoutFactory(); @Override public Appender<ILoggingEvent> build(LoggerContext context, String applicationName, Layout<ILoggingEvent> layout) { RedisAppender appender = new RedisAppender(); appender.setContext(context); appender.setName(REDIS_APPENDER_NAME); appender.setPoolConfig(pool.build()); appender.setHost(host); appender.setPort(port); appender.setTimeout((int) timeout.toMilliseconds()); appender.setPassword(password); appender.setDatabase(database); appender.setKey(key); appender.setLayout(layout != null ? layout : this.layout.build()); addThresholdFilter(appender); appender.start(); return wrapAsync(context, appender); } private void addThresholdFilter(FilterAttachable<ILoggingEvent> appender) { ThresholdFilter filter = new ThresholdFilter(); filter.setLevel(threshold.toString()); filter.start(); appender.addFilter(filter); } private Appender<ILoggingEvent> wrapAsync(LoggerContext context, Appender<ILoggingEvent> appender) { AsyncAppender asyncAppender = new AsyncAppender(); asyncAppender.setContext(context); asyncAppender.setName(LOGSTASH_APPENDER_NAME); asyncAppender.setQueueSize(queueSize); asyncAppender.setDiscardingThreshold(discardingThreshold); asyncAppender.addAppender(appender); asyncAppender.start(); return asyncAppender; } @JsonProperty public String getHost() { return host; } @JsonProperty public void setHost(String host) { this.host = host; } @JsonProperty public int getPort() { return port; } @JsonProperty public void setPort(int port) { this.port = port; } @JsonProperty public Duration getTimeout() { return timeout; } @JsonProperty public void setTimeout(Duration timeout) { this.timeout = timeout; } @JsonProperty public String getPassword() { return password; } @JsonProperty public void setPassword(String password) { this.password = password; } @JsonProperty public int getDatabase() { return database; } @JsonProperty public void setDatabase(int database) { this.database = database; } @JsonProperty public String getKey() { return key; } @JsonProperty public void setKey(String key) { this.key = key; } @JsonProperty public Level getThreshold() { return threshold; } @JsonProperty public void setThreshold(Level threshold) { this.threshold = threshold; } @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; } @JsonProperty public JedisPoolConfigFactory getPool() { return pool; } @JsonProperty public void setPool(JedisPoolConfigFactory pool) { this.pool = pool; } @JsonProperty public LogstashEventLayoutFactory getLayout() { return layout; } @JsonProperty public void setLayout(LogstashEventLayoutFactory layout) { this.layout = layout; } }