You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by gg...@apache.org on 2012/11/01 16:49:38 UTC
svn commit: r1404650 - in /logging/log4j/log4j2/trunk/core/src:
main/java/org/apache/logging/log4j/core/pattern/
test/java/org/apache/logging/log4j/core/appender/ test/resources/
Author: ggregory
Date: Thu Nov 1 15:49:38 2012
New Revision: 1404650
URL: http://svn.apache.org/viewvc?rev=1404650&view=rev
Log:
Allow custom ANSI mappings for Levels.
Added:
logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderHighlightLayoutDefaultMain.java (with props)
logging/log4j/log4j2/trunk/core/src/test/resources/log4j2-console-highlight-default.xml (with props)
Modified:
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/AnsiEscape.java
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/HighlightConverter.java
logging/log4j/log4j2/trunk/core/src/test/resources/log4j2-console-highlight.xml
Modified: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/AnsiEscape.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/AnsiEscape.java?rev=1404650&r1=1404649&r2=1404650&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/AnsiEscape.java (original)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/AnsiEscape.java Thu Nov 1 15:49:38 2012
@@ -16,6 +16,9 @@
*/
package org.apache.logging.log4j.core.pattern;
+import java.util.HashMap;
+import java.util.Map;
+
/**
*
*/
@@ -84,6 +87,62 @@ public enum AnsiEscape {
return code;
}
+ /**
+ * Creates a Map from a source string. The format is:
+ *
+ * <pre>
+ * Key1=Value, Key2=Value, ...
+ * </pre>
+ *
+ * For example:
+ *
+ * <pre>
+ * ERROR=red bold, WARN=yellow bold, INFO=green, ...
+ * </pre>
+ *
+ * You can use whitespace around the comma and equal sign. The names in values MUST come from the {@linkplain AnsiEscape} enum, case is
+ * normalized to upper-case internally.
+ *
+ * @param values
+ * the source string to parse.
+ * @return a new map
+ */
+ public static Map<String, String> createMap(String values) {
+ return createMap(values.split("\\s*,\\s*"));
+ }
+
+ /**
+ * Creates a Map from a source array. Each array entry must be in the format:
+ *
+ * <pre>
+ * Key1 = Value
+ * </pre>
+ *
+ * For example:
+ *
+ * <pre>
+ * ERROR=red bold
+ * </pre>
+ *
+ * You can use whitespace around the equal sign and between the value elements. The names in values MUST come from the
+ * {@linkplain AnsiEscape} enum, case is normalized to upper-case internally.
+ *
+ * @param values
+ * the source array to parse.
+ * @return a new map
+ */
+ public static Map<String, String> createMap(String[] values) {
+ Map<String, String> map = new HashMap<String, String>();
+ for (String string : values) {
+ String[] keyValue = string.split("\\s*=\\s*");
+ if (keyValue.length > 1) {
+ final String style = keyValue[1];
+ map.put(keyValue[0], createSequence(style.split("\\s")));
+ }
+ }
+ return map;
+ }
+
public static String createSequence(String[] values) {
if (values == null) {
return getDefaultStyle();
Modified: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/HighlightConverter.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/HighlightConverter.java?rev=1404650&r1=1404649&r2=1404650&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/HighlightConverter.java (original)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/HighlightConverter.java Thu Nov 1 15:49:38 2012
@@ -16,58 +16,102 @@
*/
package org.apache.logging.log4j.core.pattern;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Map;
+
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.layout.PatternLayout;
-import java.util.EnumMap;
-import java.util.List;
-
/**
- * Highlight pattern converter. Formats the result of a pattern using a color appropriate
- * for the Level in the LogEvent.
+ * Highlight pattern converter. Formats the result of a pattern using a color appropriate for the Level in the LogEvent.
+ * <p>
+ * For example:
+ * </p>
+ *
+ * <pre>
+ * %highlight{%d{ ISO8601 } [%t] %-5level: %msg%n%throwable}
+ * </pre>
+ * <p>
+ * You can define custom colors for each Level:
+ * </p>
+ *
+ * <pre>
+ * %highlight{%d{ ISO8601 } [%t] %-5level: %msg%n%throwable}{FATAL=red, ERROR=red, WARN=yellow, INFO=green, DEBUG=cyan, TRACE=black}
+ * </pre>
+ * <p>
+ * You can use whitespace around the comma and equal sign. The names in values MUST come from the {@linkplain AnsiEscape} enum, case is
+ * normalized to upper-case internally.
+ * </p>
*/
@Plugin(name = "highlight", type = "Converter")
-@ConverterKeys({"highlight" })
+@ConverterKeys({ "highlight" })
public final class HighlightConverter extends LogEventPatternConverter {
- private static final EnumMap<Level, String> LEVEL_STYLES = new EnumMap<Level, String>(Level.class);
-
- private static final String[] FATAL = new String[]{"BLINK", "BRIGHT", "RED"};
- private static final String[] ERROR = new String[] {"BRIGHT", "RED"};
- private static final String[] WARN = new String[] {"RED"};
- private static final String[] INFO = new String[] {"BLUE"};
- private static final String[] DEBUG = null;
- private static final String[] TRACE = null;
-
- private final List<PatternFormatter> formatters;
+ private static final String[] DEFAULT_FATAL = new String[] { "BLINK", "BRIGHT", "RED" };
+ private static final String[] DEFAULT_ERROR = new String[] { "BRIGHT", "RED" };
+ private static final String[] DEFAULT_WARN = new String[] { "RED" };
+ private static final String[] DEFAULT_INFO = new String[] { "BLUE" };
+ private static final String[] DEFAULT_DEBUG = null;
+ private static final String[] DEFAULT_TRACE = null;
+
+ private static final EnumMap<Level, String> LEVEL_STYLES_DEFAULT = new EnumMap<Level, String>(Level.class);
static {
- LEVEL_STYLES.put(Level.FATAL, AnsiEscape.createSequence(FATAL));
- LEVEL_STYLES.put(Level.ERROR, AnsiEscape.createSequence(ERROR));
- LEVEL_STYLES.put(Level.WARN, AnsiEscape.createSequence(WARN));
- LEVEL_STYLES.put(Level.INFO, AnsiEscape.createSequence(INFO));
- LEVEL_STYLES.put(Level.DEBUG, AnsiEscape.createSequence(DEBUG));
- LEVEL_STYLES.put(Level.TRACE, AnsiEscape.createSequence(TRACE));
+ LEVEL_STYLES_DEFAULT.put(Level.FATAL, AnsiEscape.createSequence(DEFAULT_FATAL));
+ LEVEL_STYLES_DEFAULT.put(Level.ERROR, AnsiEscape.createSequence(DEFAULT_ERROR));
+ LEVEL_STYLES_DEFAULT.put(Level.WARN, AnsiEscape.createSequence(DEFAULT_WARN));
+ LEVEL_STYLES_DEFAULT.put(Level.INFO, AnsiEscape.createSequence(DEFAULT_INFO));
+ LEVEL_STYLES_DEFAULT.put(Level.DEBUG, AnsiEscape.createSequence(DEFAULT_DEBUG));
+ LEVEL_STYLES_DEFAULT.put(Level.TRACE, AnsiEscape.createSequence(DEFAULT_TRACE));
}
/**
- * Construct the converter.
- * @param formatters The PatternFormatters to generate the text to manipulate.
+ * Creates a level style map given configuration options in {@code option[1]}.
+ * <p/>
+ * The format of the option string in {@code option[1]} is:
+ *
+ * <pre>
+ * Level1=Value, Level2=Value, ...
+ * </pre>
+ *
+ * For example:
+ *
+ * <pre>
+ * ERROR=red bold, WARN=yellow bold, INFO=green, ...
+ * </pre>
+ *
+ * You can use whitespace around the comma and equal sign. The names in values MUST come from the {@linkplain AnsiEscape} enum, case is
+ * normalized to upper-case internally.
+ *
+ * @param options
+ * The second slot can optionally contain the style map.
+ * @return a new map
*/
- private HighlightConverter(List<PatternFormatter> formatters) {
- super("style", "style");
- this.formatters = formatters;
+ private static EnumMap<Level, String> createLevelStyleMap(final String[] options) {
+ Map<String, String> styles = options.length < 2 ? null : AnsiEscape.createMap(options[1]);
+ EnumMap<Level, String> levelStyles = new EnumMap<Level, String>(LEVEL_STYLES_DEFAULT);
+ for (Map.Entry<String, String> entry : styles.entrySet()) {
+ final Level key = Level.valueOf(entry.getKey());
+ if (key == null) {
+ LOGGER.error("Unkown level name: " + entry.getKey());
+ } else {
+ levelStyles.put(key, entry.getValue());
+ }
+ }
+ return levelStyles;
}
/**
* Gets an instance of the class.
- *
- * @param config The current Configuration.
- * @param options pattern options, may be null. If first element is "short",
- * only the first line of the throwable will be formatted.
+ *
+ * @param config
+ * The current Configuration.
+ * @param options
+ * pattern options, may be null. If first element is "short", only the first line of the throwable will be formatted.
* @return instance of class.
*/
public static HighlightConverter newInstance(Configuration config, final String[] options) {
@@ -79,12 +123,26 @@ public final class HighlightConverter ex
LOGGER.error("No pattern supplied on style");
return null;
}
-
PatternParser parser = PatternLayout.createPatternParser(config);
List<PatternFormatter> formatters = parser.parse(options[0]);
- return new HighlightConverter(formatters);
+ return new HighlightConverter(formatters, createLevelStyleMap(options));
}
+ private final List<PatternFormatter> formatters;
+
+ private final EnumMap<Level, String> levelStyles;
+
+ /**
+ * Construct the converter.
+ *
+ * @param formatters
+ * The PatternFormatters to generate the text to manipulate.
+ */
+ private HighlightConverter(List<PatternFormatter> formatters, EnumMap<Level, String> levelStyles) {
+ super("style", "style");
+ this.formatters = formatters;
+ this.levelStyles = levelStyles;
+ }
/**
* {@inheritDoc}
@@ -97,8 +155,7 @@ public final class HighlightConverter ex
}
if (buf.length() > 0) {
- toAppendTo.append(LEVEL_STYLES.get(event.getLevel())).append(buf.toString()).
- append(AnsiEscape.getDefaultStyle());
+ toAppendTo.append(levelStyles.get(event.getLevel())).append(buf.toString()).append(AnsiEscape.getDefaultStyle());
}
}
}
Added: logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderHighlightLayoutDefaultMain.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderHighlightLayoutDefaultMain.java?rev=1404650&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderHighlightLayoutDefaultMain.java (added)
+++ logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderHighlightLayoutDefaultMain.java Thu Nov 1 15:49:38 2012
@@ -0,0 +1,34 @@
+package org.apache.logging.log4j.core.appender;
+
+import java.io.IOException;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.Configurator;
+
+/**
+ * Shows how to use ANSI escape codes to color messages. Each message is printed to the console in color, but the rest of the log entry
+ * (time stamp for example) is in the default color for that console.
+ */
+public class ConsoleAppenderHighlightLayoutDefaultMain {
+
+ private static final Logger LOG = LogManager.getLogger(ConsoleAppenderHighlightLayoutDefaultMain.class);
+
+ public static void main(String[] args) {
+ LoggerContext ctx = Configurator.initialize(ConsoleAppenderAnsiMessagesMain.class.getName(), null,
+ "target/test-classes/log4j2-console-highlight-default.xml");
+ try {
+ LOG.fatal("Fatal message.");
+ LOG.error("Error message.");
+ LOG.warn("Warning message.");
+ LOG.info("Information message.");
+ LOG.debug("Debug message.");
+ LOG.trace("Trace message.");
+ LOG.error("Error message.", new IOException("test"));
+ } finally {
+ Configurator.shutdown(ctx);
+ }
+ }
+
+}
Propchange: logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderHighlightLayoutDefaultMain.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderHighlightLayoutDefaultMain.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: logging/log4j/log4j2/trunk/core/src/test/resources/log4j2-console-highlight-default.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/test/resources/log4j2-console-highlight-default.xml?rev=1404650&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/test/resources/log4j2-console-highlight-default.xml (added)
+++ logging/log4j/log4j2/trunk/core/src/test/resources/log4j2-console-highlight-default.xml Thu Nov 1 15:49:38 2012
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+
+-->
+<configuration status="OFF">
+ <appenders>
+ <Console name="Console" target="SYSTEM_OUT">
+ <PatternLayout pattern="%highlight{%d{ ISO8601 } [%t] %-5level: %msg%n%throwable}" />
+ </Console>
+ </appenders>
+ <loggers>
+ <logger name="org.foo" level="DEBUG" />
+ <root level="TRACE">
+ <appender-ref ref="Console" />
+ </root>
+ </loggers>
+</configuration>
\ No newline at end of file
Propchange: logging/log4j/log4j2/trunk/core/src/test/resources/log4j2-console-highlight-default.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: logging/log4j/log4j2/trunk/core/src/test/resources/log4j2-console-highlight-default.xml
------------------------------------------------------------------------------
svn:keywords = Id
Modified: logging/log4j/log4j2/trunk/core/src/test/resources/log4j2-console-highlight.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/test/resources/log4j2-console-highlight.xml?rev=1404650&r1=1404649&r2=1404650&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/test/resources/log4j2-console-highlight.xml (original)
+++ logging/log4j/log4j2/trunk/core/src/test/resources/log4j2-console-highlight.xml Thu Nov 1 15:49:38 2012
@@ -19,7 +19,7 @@
<configuration status="OFF">
<appenders>
<Console name="Console" target="SYSTEM_OUT">
- <PatternLayout pattern="%highlight{%d{ ISO8601 } [%t] %-5level: %msg%n%throwable}" />
+ <PatternLayout pattern="%highlight{%d{ ISO8601 } [%t] %-5level: %msg%n%throwable}{FATAL=white, ERROR=red, WARN=blue, INFO=black, DEBUG=green, TRACE=blue}" />
</Console>
</appenders>
<loggers>