/** * Copyright 2013 Michael K. Werle * * 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.coruscations.logback.redis.logstash; import org.junit.Test; import org.slf4j.LoggerFactory; import org.slf4j.MDC; import org.slf4j.MarkerFactory; import java.net.URL; import java.util.Iterator; import java.util.Random; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.filter.ThresholdFilter; import ch.qos.logback.classic.joran.JoranConfigurator; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.Appender; import ch.qos.logback.core.joran.spi.JoranException; import static org.junit.Assert.assertNotNull; public class RedisLogstashAppenderTest { @Test public void testRedisLogstashAppenderProgrammatically() throws InterruptedException { RedisLogstashAppender appender = new RedisLogstashAppender(); appender.setType("test-logback-redis-logstash"); appender.setFile("test"); appender.setRedisHostName("localhost"); appender.setRedisPort(6379); appender.setContext((LoggerContext) LoggerFactory.getILoggerFactory()); appender.start(); // Setup the test logger final Logger testLogger = (Logger) LoggerFactory.getLogger(getClass().getName() + "-test"); testLogger.setLevel(Level.TRACE); testLogger.addAppender(appender); // Add a threshold filter to any existing loggers to lower verbosity Logger rootLogger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); ThresholdFilter thresholdFilter = new ThresholdFilter(); thresholdFilter.setLevel("INFO"); thresholdFilter.start(); Iterator<Appender<ILoggingEvent>> appenderIterator = rootLogger.iteratorForAppenders(); while (appenderIterator.hasNext()) { appenderIterator.next().addFilter(thresholdFilter); } testLogger.info("This is a simple test."); testLogger.info("This is a multi-\nline\ntest."); testLogger.info("This is a \"quoted\" test."); int threadCount = 2 * Runtime.getRuntime().availableProcessors(); ExecutorService executor = Executors.newFixedThreadPool(threadCount); for (int i = 0; i < threadCount; i++) { final int threadNum = i; executor.submit(new Runnable() { private Random random = new Random(); @Override public void run() { testLogger.info("Starting test thread {}.", threadNum); for (int i = 0; i < 1000; i++) { testLogger.trace("This is programmatic test {}:{}.", threadNum, i); if (random.nextInt(10) < 1) { try { Thread.sleep((long) random.nextInt(100)); } catch (InterruptedException e) { // Ignore; it's just test code } } } testLogger.info("Finished test thread {}.", threadNum); } }); } executor.shutdown(); // Wait an absurdly long period of time executor.awaitTermination(30l, TimeUnit.SECONDS); testLogger.info("This is a programmatic test with an exception.", new Exception()); testLogger.info("This is a programmatic test with a multi-line exception message.", new Exception("Multi-\nline\nmessage")); testLogger.info("This is a programmatic test with a quoted exception message.", new Exception("\"Quoted\" message")); MDC.put("A key", "A value"); MDC.put("A multi-\nline\nkey", "A multi-\nline\nvalue"); MDC.put("A \"quoted\" key", "A \"quoted\" value"); testLogger.info("This is a programmatic test with an MDC."); MDC.clear(); testLogger.info(MarkerFactory.getMarker("A marker"), "This is a programmatic test for a marker."); testLogger.info(MarkerFactory.getMarker("A multi-\nline\nmarker"), "This is a programmatic test for a multi-line marker."); testLogger.info(MarkerFactory.getMarker("A \"quoted\" marker"), "This is a programmatic test for a quoted marker."); testLogger.info(MarkerFactory.getDetachedMarker("A detached marker"), "This is a programmatic test for a detached marker."); testLogger.info(MarkerFactory.getDetachedMarker("A detached multi-\nline\nmarker"), "This is a programmatic test for a detached multi-line marker."); testLogger.info(MarkerFactory.getDetachedMarker("A detached \"quoted\" marker"), "This is a programmatic test for a detached quoted marker."); MDC.clear(); MDC.put("tags", "one, two, thee, multi-\nline, \"quoted\" tag"); testLogger.info("This is a programmatic test for tags."); MDC.clear(); Thread.currentThread().setName("Multi-\nline\nThread\nName"); testLogger.info("This is a programmatic test for multi-line thread names."); Thread.currentThread().setName("\"Quoted\" Thread Name"); testLogger.info("This is a programmatic test for quoted thread names."); appender.stop(); } @Test public void testRedisLogstashAppenderFile() throws JoranException { LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); JoranConfigurator jc = new JoranConfigurator(); jc.setContext(context); context.reset(); // override default configuration URL resource = getClass().getClassLoader().getResource("test-logback.xml"); assertNotNull("Could not find test-logback.xml", resource); jc.doConfigure(resource.getFile()); Logger logger = (Logger) LoggerFactory.getLogger(RedisLogstashAppenderTest.class); logger.info("This is a test."); logger.info("This is a test with an exception.", new Exception()); } }