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

org.pmw.tinylog.Configuration Maven / Gradle / Ivy

Go to download

A Tinylog console writer extension to restrict writers to single log levels (e.g. for level-specific colored logs).

The newest version!
/*
 * Copyright 2012 Martin Winandy
 * 
 * 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 org.pmw.tinylog;

import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.pmw.tinylog.writers.LogEntryValue;
import org.pmw.tinylog.writers.Writer;

/**
 * Configuration for {@link org.pmw.tinylog.Logger Logger}. Use {@link org.pmw.tinylog.Configurator Configurator} to
 * create a configuration.
 * 

* COMMENT: This class has been taken from the Tinylog (v1.3.1) and modified to support access * to the writer specific levels for singlelevel-cw. All modifications are tagged with "--- manually added ---". */ public final class Configuration { private static final Level DEFAULT_LEVEL = Level.INFO; private static final String DEFAULT_FORMAT_PATTERN = "{date} [{thread}] {class}.{method}()\n{level}: {message}"; private static final int DEFAULT_MAX_STACK_TRACE_ELEMENTS = 40; private final Configurator configurator; private final Level level; private final Level lowestLevel; private final Map customLevels; private final String formatPattern; private final Locale locale; private final List writers; private final WritingThread writingThread; private final int maxStackTraceElements; private final Map effectiveWriters; private final Map[]> effectiveFormatTokens; private final Map> requiredLogEntryValues; private final Map requiredStackTraceInformation; // --- manually added --- private final Map writerLevels; /** * @param configurator * Copy of based configurator * @param level * Severity level * @param customLevels * Custom severity levels for specific packages and classes * @param formatPattern * Format pattern for log entries * @param locale * Locale for format pattern * @param writerDefinitions * Writer definitions (can be empty to disable any output) * @param writingThread * Writing thread (can be null to write log entries synchronously) * @param maxStackTraceElements * Limit of stack traces for exceptions */ Configuration(final Configurator configurator, final Level level, final Map customLevels, final String formatPattern, final Locale locale, final List writerDefinitions, final WritingThread writingThread, final Integer maxStackTraceElements) { this.configurator = configurator; this.level = level == null ? getLevel(writerDefinitions) : level; this.lowestLevel = getLowestLevel(this.level, customLevels, writerDefinitions); this.customLevels = customLevels; this.formatPattern = formatPattern == null ? DEFAULT_FORMAT_PATTERN : formatPattern; this.locale = locale == null ? Locale.getDefault() : locale; this.writers = getWriters(writerDefinitions); this.writingThread = writingThread; this.maxStackTraceElements = maxStackTraceElements == null ? DEFAULT_MAX_STACK_TRACE_ELEMENTS : maxStackTraceElements; this.effectiveWriters = getEffectiveWriters(writerDefinitions); this.effectiveFormatTokens = getEffectiveFormatTokens(writerDefinitions, this.formatPattern, this.locale, this.maxStackTraceElements); this.requiredLogEntryValues = getRequiredLogEntryValues(effectiveWriters, effectiveFormatTokens); this.requiredStackTraceInformation = getRequiredStackTraceInformation(requiredLogEntryValues, customLevels); // --- manually added --- this.writerLevels = getWriterLevels(writerDefinitions); } /** * Get the global severity level. * * @return Global severity level */ public Level getLevel() { return level; } /** * Check if there are custom severity levels. * * @return true if custom severity levels exist, false if not */ public boolean hasCustomLevels() { return !customLevels.isEmpty(); } /** * Get the severity level for a package or class. * * @param packageOrClass * Name of the package respectively class * * @return Severity level for the package respectively class */ public Level getLevel(final String packageOrClass) { String key = packageOrClass; while (true) { Level customLevel = customLevels.get(key); if (customLevel != null) { return customLevel; } int index = key.lastIndexOf('.'); if (index > 0) { key = key.substring(0, index); } else { return level; } } } /** * Get the format pattern for log entries. * * @return Format pattern for log entries */ public String getFormatPattern() { return formatPattern; } /** * Get the locale that is used to render format patterns for log entries. * * @return Locale for format pattern */ public Locale getLocale() { return locale; } /** * Get the writers to output created log entries. * * @return Writers to output log entries */ public List getWriters() { return writers; } /** * Get the writing thread (writes log entries asynchronously). * * @return Writing thread */ public WritingThread getWritingThread() { return writingThread; } /** * Get the limit of stack traces for exceptions. * * @return Limit of stack traces */ public int getMaxStackTraceElements() { return maxStackTraceElements; } /** * Get a new configurator, based on this configuration. * @return New configurator */ Configurator getConfigurator() { return configurator.copy(); } /** * Fast check if output is possible. * * @param level * Severity level to check * @return true if log entries with the defined severity level can be output, false if not */ boolean isOutputPossible(final Level level) { return lowestLevel.ordinal() <= level.ordinal(); } /** * Get the effective writers to be used by the logger. * * @param level * Severity level of log entry * @return Effective writers */ Writer[] getEffectiveWriters(final Level level) { return effectiveWriters.get(level); } /** * Get the effective format tokens for all effective writers to be used by the logger. * * @param level * Severity level of log entry * @return Effective format tokens */ List[] getEffectiveFormatTokens(final Level level) { return effectiveFormatTokens.get(level); } /** * Get all log entry values that are required by the writers. * * @param level * Severity level of log entry * @return Required values for log entry */ Set getRequiredLogEntryValues(final Level level) { return requiredLogEntryValues.get(level); } /** * Get the required stack trace information. * * @param level * Severity level of log entry * @return Required stack trace information */ StackTraceInformation getRequiredStackTraceInformation(final Level level) { return requiredStackTraceInformation.get(level); } private static Level getLevel(final List definitions) { Level level = null; for (WriterDefinition definition : definitions) { if (definition.getLevel() != null) { if (level == null || definition.getLevel().ordinal() < level.ordinal()) { level = definition.getLevel(); } } } return level == null ? DEFAULT_LEVEL : level; } private static Level getLowestLevel(final Level level, final Map customLevels, final List definitions) { Level lowestLevel = level; for (Level customLevel : customLevels.values()) { if (lowestLevel.ordinal() > customLevel.ordinal()) { lowestLevel = customLevel; } } Level writerOutput = Level.OFF; for (WriterDefinition definition : definitions) { Level definitionLevel = definition.getLevel(); if (definitionLevel == null) { definitionLevel = lowestLevel; } if (definitionLevel.ordinal() <= writerOutput.ordinal()) { writerOutput = definitionLevel; } } return writerOutput.ordinal() > lowestLevel.ordinal() ? writerOutput : lowestLevel; } private static List getWriters(final List definitions) { List writers = new ArrayList(); for (WriterDefinition definition : definitions) { writers.add(definition.getWriter()); } return writers.isEmpty() ? Collections. emptyList() : writers; } // --- manually added --- private static Map getWriterLevels(final List definitions){ Map writerLevelMap = new HashMap(); for( WriterDefinition wd : definitions ) { writerLevelMap.put(wd.getWriter(), wd.getLevel()); } return writerLevelMap; } // --- manually added --- public Level getWriterLevel(final Writer writer) { return writerLevels.get(writer); } private static Map getEffectiveWriters(final List definitions) { Map map = new EnumMap(Level.class); for (Level level : Level.values()) { List writers = new ArrayList(); for (WriterDefinition definition : definitions) { Level definitionLevel = definition.getLevel(); if (definitionLevel == null) { definitionLevel = Level.TRACE; } if (level.ordinal() >= definitionLevel.ordinal()) { writers.add(definition.getWriter()); } } map.put(level, writers.toArray(new Writer[writers.size()])); } return map; } @SuppressWarnings("unchecked") private static Map[]> getEffectiveFormatTokens(final List definitions, final String globalFormatPattern, final Locale locale, final int maxStackTraceElements) { Map> cache = new HashMap>(); Tokenizer tokenizer = new Tokenizer(locale, maxStackTraceElements); Map[]> map = new EnumMap[]>(Level.class); for (Level level : Level.values()) { List> formatTokensOfLevel = new ArrayList>(); for (WriterDefinition definition : definitions) { Level definitionLevel = definition.getLevel(); if (definitionLevel == null) { definitionLevel = Level.TRACE; } if (level.ordinal() >= definitionLevel.ordinal()) { Writer writer = definition.getWriter(); if (cache.containsKey(writer)) { formatTokensOfLevel.add(cache.get(writer)); } else { Set requiredLogEntryValuesOfWriter = writer.getRequiredLogEntryValues(); if (requiredLogEntryValuesOfWriter == null || !requiredLogEntryValuesOfWriter.contains(LogEntryValue.RENDERED_LOG_ENTRY)) { formatTokensOfLevel.add(null); cache.put(writer, null); } else { String formatPattern = definition.getFormatPattern(); if (formatPattern == null) { formatPattern = globalFormatPattern; } List formatTokens = tokenizer.parse(formatPattern); formatTokensOfLevel.add(formatTokens); cache.put(writer, formatTokens); } } } } map.put(level, formatTokensOfLevel.toArray(new List[formatTokensOfLevel.size()])); } return map; } private static Map> getRequiredLogEntryValues(final Map writersMap, final Map[]> formatTokensMap) { Map> map = new EnumMap>(Level.class); for (Entry entry : writersMap.entrySet()) { Level level = entry.getKey(); Writer[] writers = entry.getValue(); if (writers.length == 0) { map.put(level, Collections. emptySet()); } else { List[] formatTokens = formatTokensMap.get(level); Set requiredLogEntryValues = EnumSet.noneOf(LogEntryValue.class); for (int i = 0; i < writers.length; ++i) { Set requiredLogEntryValuesOfWriter = writers[i].getRequiredLogEntryValues(); if (requiredLogEntryValuesOfWriter != null) { if (requiredLogEntryValuesOfWriter.contains(LogEntryValue.RENDERED_LOG_ENTRY)) { for (Token token : formatTokens[i]) { for (LogEntryValue logEntryValue : token.getRequiredLogEntryValues()) { requiredLogEntryValuesOfWriter.add(logEntryValue); } } } requiredLogEntryValues.addAll(requiredLogEntryValuesOfWriter); } } if (requiredLogEntryValues.isEmpty()) { map.put(level, Collections. emptySet()); } else { map.put(level, requiredLogEntryValues); } } } return map; } private static Map getRequiredStackTraceInformation(final Map> requiredLogEntryValues, final Map customLevels) { Map map = new EnumMap(Level.class); for (Entry> entry : requiredLogEntryValues.entrySet()) { Level level = entry.getKey(); Set logEntryValues = entry.getValue(); if (logEntryValues.contains(LogEntryValue.METHOD) || logEntryValues.contains(LogEntryValue.FILE) || logEntryValues.contains(LogEntryValue.LINE)) { map.put(level, StackTraceInformation.FULL); } else if (logEntryValues.contains(LogEntryValue.CLASS) || !customLevels.isEmpty()) { map.put(level, StackTraceInformation.CLASS_NAME); } else { map.put(level, StackTraceInformation.NONE); } } return map; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy