TinylogLoggingConfiguration { @SuppressWarnings("unchecked") public Collection<Writer>[][] createWriters(final List<String> tags, final Level minimumLevel, final boolean writingThread) { if (RuntimeProvider.getProcessId() == Long.MIN_VALUE) { java.util.ServiceLoader.load(Writer.class); } Collection<Writer>[][] matrix = new Collection[tags.size() + 2][Level.values().length - 1]; ServiceLoader<Writer> loader = new ServiceLoader<Writer>(Writer.class, Map.class); Map<String, String> writerProperties = Configuration.getSiblings("writer"); if (writerProperties.isEmpty()) { writerProperties = Collections.singletonMap("writer", RuntimeProvider.getDefaultWriter()); } for (Entry<String, String> entry : writerProperties.entrySet()) { Map<String, String> configuration = Configuration.getChildren(entry.getKey()); String tag = configuration.get("tag"); Level level = ConfigurationParser.parse(configuration.get("level"), minimumLevel); if (level.ordinal() < minimumLevel.ordinal()) { level = minimumLevel; } String exception = Configuration.get("exception"); if (exception != null && !configuration.containsKey("exception")) { configuration.put("exception", exception); } configuration.put("ID", entry.getKey()); configuration.put("writingthread", Boolean.toString(writingThread)); Writer writer = loader.create(entry.getValue(), configuration); if (writer != null) { if (tag == null || tag.isEmpty()) { for (int tagIndex = 0; tagIndex < matrix.length; ++tagIndex) { addWriter(writer, matrix, tagIndex, level); } } else if (tag.equals("-")) { addWriter(writer, matrix, 0, level); } else { String[] tagArray = tag.split(","); for (String tagArrayItem : tagArray) { tagArrayItem = tagArrayItem.trim(); String[] tagLevelItem = tagArrayItem.split("@", 2); Level currentLevel; String currentTag; if (tagLevelItem.length == 1) { currentTag = tagArrayItem; currentLevel = level; } else { currentTag = tagLevelItem[0].trim(); currentLevel = ConfigurationParser.parse(tagLevelItem[1].trim(), level); } if (!tagArrayItem.isEmpty()) { addWriter(writer, matrix, tags.indexOf(currentTag) + 1, currentLevel); } } } } } for (int tagIndex = 0; tagIndex < matrix.length; ++tagIndex) { for (int levelIndex = 0; levelIndex < matrix[tagIndex].length; ++levelIndex) { if (matrix[tagIndex][levelIndex] == null) { matrix[tagIndex][levelIndex] = Collections.emptyList(); } } } return matrix; } TinylogLoggingConfiguration(); @SuppressWarnings("unchecked") Collection<Writer>[][] createWriters(final List<String> tags, final Level minimumLevel, final boolean writingThread); Level calculateMinimumLevel(final Level globalLevel, final Map<String, Level> customLevels); @SuppressWarnings("unchecked") Collection<LogEntryValue>[][] calculateRequiredLogEntryValues(final Collection<Writer>[][] writers); BitSet calculateFullStackTraceRequirements(final Collection<LogEntryValue>[][] logEntryValues); WritingThread createWritingThread(final Collection<Writer>[][] matrix); static Collection<Writer> getAllWriters(final Collection<Writer>[][] matrix); static LogEntry createLogEntry(final StackTraceElement stackTraceElement, final String tag, 
		final Level level, final Throwable exception, final MessageFormatter formatter, final Object obj,
		final Object[] arguments, final Collection<LogEntryValue>[] requiredLogEntryValues, 
		final TinylogContextProvider contextProvider);  }
@Test public void defaultWriter() { TinylogLoggingConfiguration config = new TinylogLoggingConfiguration(); Collection<Writer>[][] writers = config.createWriters(emptyList(), Level.TRACE, false); assertThat(writers).hasSize(2).allSatisfy(element -> assertThat(element).hasSize(5).allSatisfy(collection -> assertThat(collection).hasSize(1).allSatisfy(writer -> assertThat(writer).isNotNull()) ) ); }
@Test public void noWriters() { Configuration.set("writer", "console"); TinylogLoggingConfiguration config = new TinylogLoggingConfiguration(); Collection<Writer>[][] writers = config.createWriters(emptyList(), Level.OFF, false); assertThat(writers).hasSize(2).allSatisfy(element -> assertThat(element).hasSize(5).allSatisfy(collection -> assertThat(collection).isEmpty()) ); }
@Test public void singleTaggedWriter() { Configuration.set("writer", "console"); Configuration.set("writer.tag", "SYSTEM"); TinylogLoggingConfiguration config = new TinylogLoggingConfiguration(); Collection<Writer>[][] writers = config.createWriters(singletonList("SYSTEM"), Level.TRACE, false); assertThat(writers) .hasSize(3) .allSatisfy(element -> assertThat(element).hasSize(5)); assertThat(writers[0]).allSatisfy(collection -> assertThat(collection).isEmpty()); assertThat(writers[1]).allSatisfy(collection -> assertThat(collection).hasSize(1).allSatisfy(writer -> assertThat(writer).isInstanceOf(ConsoleWriter.class)) ); assertThat(writers[2]).allSatisfy(collection -> assertThat(collection).isEmpty()); }
@Test public void singleUntaggedWriter() { Configuration.set("writer", "console"); Configuration.set("writer.tag", "-"); TinylogLoggingConfiguration config = new TinylogLoggingConfiguration(); Collection<Writer>[][] writers = config.createWriters(emptyList(), Level.TRACE, false); assertThat(writers).hasSize(2); assertThat(writers[0]).allSatisfy(collection -> assertThat(collection).hasSize(1).allSatisfy(writer -> assertThat(writer).isInstanceOf(ConsoleWriter.class)) ); assertThat(writers[1]).allSatisfy(collection -> assertThat(collection).isEmpty()); }
@Test public void singleMultipleTaggedWriter() { Configuration.set("writer", "console"); Configuration.set("writer.tag", " system , , backup , test, , "); List<String> tags = ConfigurationParser.getTags(); TinylogLoggingConfiguration config = new TinylogLoggingConfiguration(); Collection<Writer>[][] writers = config.createWriters(tags, Level.TRACE, false); assertThat(writers) .hasSize(5) .allSatisfy(element -> assertThat(element).hasSize(5)); assertThat(writers[0]).allSatisfy(collection -> assertThat(collection).isEmpty()); assertThat(writers[1]).allSatisfy(collection -> { assertThat(collection).hasSize(1).allSatisfy(writer -> assertThat(writer).isInstanceOf(ConsoleWriter.class)); }); assertThat(writers[2]).allSatisfy(collection -> { assertThat(collection).hasSize(1).allSatisfy(writer -> assertThat(writer).isInstanceOf(ConsoleWriter.class)); }); assertThat(writers[3]).allSatisfy(collection -> { assertThat(collection).hasSize(1).allSatisfy(writer -> assertThat(writer).isInstanceOf(ConsoleWriter.class)); }); assertThat(writers[4]).allSatisfy(collection -> assertThat(collection).isEmpty()); }
@Test public void singleMultipleTaggedWriterWithLevels() { Configuration.set("writer", "console"); Configuration.set("writer.level", "ERROR"); Configuration.set("writer.tag", " system@WARN , , backup , test@INFO, , "); List<String> tags = ConfigurationParser.getTags(); TinylogLoggingConfiguration config = new TinylogLoggingConfiguration(); Collection<Writer>[][] writers = config.createWriters(tags, Level.TRACE, false); assertThat(writers) .hasSize(5) .allSatisfy(element -> assertThat(element).hasSize(5)); assertThat(writers[0]).allSatisfy(collection -> assertThat(collection).isEmpty()); assertThat(writers[1][Level.TRACE.ordinal()]).isEmpty(); assertThat(writers[1][Level.DEBUG.ordinal()]).isEmpty(); assertThat(writers[1][Level.INFO.ordinal()]).isEmpty(); assertThat(writers[1][Level.WARN.ordinal()]).hasSize(1).allSatisfy(w -> assertThat(w).isInstanceOf(ConsoleWriter.class)); assertThat(writers[1][Level.ERROR.ordinal()]).hasSize(1).allSatisfy(w -> assertThat(w).isInstanceOf(ConsoleWriter.class)); assertThat(writers[2][Level.TRACE.ordinal()]).isEmpty(); assertThat(writers[2][Level.DEBUG.ordinal()]).isEmpty(); assertThat(writers[2][Level.INFO.ordinal()]).isEmpty(); assertThat(writers[2][Level.WARN.ordinal()]).isEmpty(); assertThat(writers[2][Level.ERROR.ordinal()]).hasSize(1).allSatisfy(w -> assertThat(w).isInstanceOf(ConsoleWriter.class)); assertThat(writers[3][Level.TRACE.ordinal()]).isEmpty(); assertThat(writers[3][Level.DEBUG.ordinal()]).isEmpty(); assertThat(writers[3][Level.INFO.ordinal()]).hasSize(1).allSatisfy(w -> assertThat(w).isInstanceOf(ConsoleWriter.class)); assertThat(writers[3][Level.WARN.ordinal()]).hasSize(1).allSatisfy(w -> assertThat(w).isInstanceOf(ConsoleWriter.class)); assertThat(writers[3][Level.ERROR.ordinal()]).hasSize(1).allSatisfy(w -> assertThat(w).isInstanceOf(ConsoleWriter.class)); assertThat(writers[4]).allSatisfy(collection -> assertThat(collection).isEmpty()); }
@Test public void multipleTaggedWriter() throws IOException { Configuration.set("writer1", "console"); Configuration.set("writer1.tag", "SYSTEM"); Configuration.set("writer2", "file"); Configuration.set("writer2.tag", "SYSTEM"); Configuration.set("writer2.file", File.createTempFile("tinylog", ".log").getAbsolutePath()); TinylogLoggingConfiguration config = new TinylogLoggingConfiguration(); Collection<Writer>[][] writers = config.createWriters(singletonList("SYSTEM"), Level.TRACE, false); assertThat(writers) .hasSize(3) .allSatisfy(element -> assertThat(element).hasSize(5)); assertThat(writers[0]).allSatisfy(collection -> assertThat(collection).isEmpty()); assertThat(writers[1]).allSatisfy(collection -> assertThat(collection) .hasSize(2) .hasAtLeastOneElementOfType(ConsoleWriter.class) .hasAtLeastOneElementOfType(FileWriter.class) ); assertThat(writers[2]).allSatisfy(collection -> assertThat(collection).isEmpty()); }
@Test public void levelOfWriterAboveMinimumLevel() { Configuration.set("writer", "console"); Configuration.set("writer.level", "WARN"); TinylogLoggingConfiguration config = new TinylogLoggingConfiguration(); Collection<Writer>[][] writers = config.createWriters(emptyList(), Level.TRACE, false); assertThat(writers).hasSize(2).allSatisfy(element -> { assertThat(element).hasSize(5); assertThat(element[Level.TRACE.ordinal()]).isEmpty(); assertThat(element[Level.DEBUG.ordinal()]).isEmpty(); assertThat(element[Level.INFO.ordinal()]).isEmpty(); assertThat(element[Level.WARN.ordinal()]) .hasSize(1) .allSatisfy(writer -> assertThat(writer).isInstanceOf(ConsoleWriter.class)); assertThat(element[Level.ERROR.ordinal()]) .hasSize(1) .allSatisfy(writer -> assertThat(writer).isInstanceOf(ConsoleWriter.class)); }); }
@Test public void levelOfWriterBelowMinimumLevel() { Configuration.set("writer", "console"); Configuration.set("writer.level", "trace"); TinylogLoggingConfiguration config = new TinylogLoggingConfiguration(); Collection<Writer>[][] writers = config.createWriters(emptyList(), Level.INFO, false); assertThat(writers).hasSize(2).allSatisfy(element -> { assertThat(element).hasSize(5); assertThat(element[Level.TRACE.ordinal()]).isEmpty(); assertThat(element[Level.DEBUG.ordinal()]).isEmpty(); assertThat(element[Level.INFO.ordinal()]) .hasSize(1) .allSatisfy(writer -> assertThat(writer).isInstanceOf(ConsoleWriter.class)); assertThat(element[Level.WARN.ordinal()]) .hasSize(1) .allSatisfy(writer -> assertThat(writer).isInstanceOf(ConsoleWriter.class)); assertThat(element[Level.ERROR.ordinal()]) .hasSize(1) .allSatisfy(writer -> assertThat(writer).isInstanceOf(ConsoleWriter.class)); }); }
@Test public void levelOfWriterIsOff() { Configuration.set("writer", "console"); Configuration.set("writer.level", "off"); TinylogLoggingConfiguration config = new TinylogLoggingConfiguration(); Collection<Writer>[][] writers = config.createWriters(emptyList(), Level.INFO, false); assertThat(writers).hasSize(2).allSatisfy(element -> assertThat(element).hasSize(5).allSatisfy(collection -> assertThat(collection).isEmpty()) ); }
@Test public void globalException() { Configuration.set("exception", "drop cause"); Configuration.set("writer", "configuration store"); TinylogLoggingConfiguration config = new TinylogLoggingConfiguration(); Collection<Writer>[][] writers = config.createWriters(emptyList(), Level.INFO, false); ConfigurationStoreWriter writer = (ConfigurationStoreWriter) writers[0][Level.INFO.ordinal()].iterator().next(); assertThat(writer.getProperties()).contains(entry("exception", "drop cause")); }
@Test public void localException() { Configuration.set("writer", "configuration store"); Configuration.set("writer.exception", "unpack"); TinylogLoggingConfiguration config = new TinylogLoggingConfiguration(); Collection<Writer>[][] writers = config.createWriters(emptyList(), Level.INFO, false); ConfigurationStoreWriter writer = (ConfigurationStoreWriter) writers[0][Level.INFO.ordinal()].iterator().next(); assertThat(writer.getProperties()).contains(entry("exception", "unpack")); }
@Test public void overrideException() { Configuration.set("exception", "drop cause"); Configuration.set("writer", "configuration store"); Configuration.set("writer.exception", "unpack"); TinylogLoggingConfiguration config = new TinylogLoggingConfiguration(); Collection<Writer>[][] writers = config.createWriters(emptyList(), Level.INFO, false); ConfigurationStoreWriter writer = (ConfigurationStoreWriter) writers[0][Level.INFO.ordinal()].iterator().next(); assertThat(writer.getProperties()).contains(entry("exception", "unpack")); }