/** * Installs Apache SIS monoline formatter for easier identification of Apache SIS log messages among Maven outputs. * We perform this installation only for {@code *TestSuite}, not for individual {@code *Test}. Consequently this is * typically enabled when building a whole module with Maven but not when debugging an individual class. * * @since 1.0 */ @BeforeClass public static void configureLogging() { MonolineFormatter f = MonolineFormatter.install(); f.setHeader(null); f.setTimeFormat(null); f.setSourceFormat("class.method"); }
/** * Resets the colors to the default values. This method does not check if <cite>ANSI escape codes</cite> * are supported or not - this check must be done by the caller. */ private void resetLevelColors() { final SortedMap<Level,X364> colors = colors(); colors.clear(); colors.put(Level.ALL, X364.BACKGROUND_GRAY); colors.put(Level.CONFIG, X364.BACKGROUND_BLUE); colors.put(Level.INFO, X364.BACKGROUND_GREEN); colors.put(Level.WARNING, X364.BACKGROUND_YELLOW); colors.put(Level.SEVERE, X364.BACKGROUND_RED); colors.put(PerformanceLevel.PERFORMANCE, X364.BACKGROUND_CYAN); }
/** * Installs a {@code MonolineFormatter} for the root logger, or returns the existing instance if any. * This method performs the following choices: * * <ul> * <li>If a {@link ConsoleHandler} is associated to the root logger, then: * <ul> * <li>If that handler already uses a {@code MonolineFormatter}, then the existing formatter is returned.</li> * <li>Otherwise the {@code ConsoleHandler} formatter is replaced by a new {@code MonolineFormatter} instance, * and that new instance is returned. We perform this replacement in order to avoid sending twice the same * records to the console.</li> * </ul></li> * <li>Otherwise a new {@code ConsoleHandler} using a new {@code MonolineFormatter} is created and added to the * root logger.</li> * </ul> * * <div class="note"><b>Implementation note:</b> * The current implementation does not check for duplicated {@code ConsoleHandler} instances, * and does not check if any child logger has a {@code ConsoleHandler}.</div> * * @return the new or existing {@code MonolineFormatter}. The formatter output can be configured * using the {@link #setTimeFormat(String)} and {@link #setSourceFormat(String)} methods. * @throws SecurityException if this method does not have the permission to install the formatter. */ @Configuration public static MonolineFormatter install() throws SecurityException { return install(Logging.getLogger(""), null); }
levelWidth = levelWidth((handler != null) ? handler.getLevel() : null); timeFormat(manager.getProperty(classname + ".time")); } catch (IllegalArgumentException exception) { Logging.configurationException(Logging.getLogger(Modules.UTILITIES), MonolineFormatter.class, "<init>", exception); sourceFormat(manager.getProperty(classname + ".source")); } catch (IllegalArgumentException exception) { Logging.configurationException(Logging.getLogger(Modules.UTILITIES), MonolineFormatter.class, "<init>", exception); resetLevelColors();
if (SHOW_LEVEL) { if (colors) { levelColor = colorAt(level); levelReset = X364.BACKGROUND_DEFAULT.sequence(); String message = formatMessage(record); int length = 0; if (message != null) { exception.printStackTrace(printer); } else { printAbridged(exception, writer, record.getLoggerName(), record.getSourceClassName(), record.getSourceMethodName());
/** * Formats the given expected string to a format matching the current locale setting. * The given string shall use tabulation before each line of the message. */ private static String localize(final Level level, final String expected) { final String levelToReplace = level.getName(); final String levelLocalized = level.getLocalizedName(); assertTrue(expected, expected.startsWith(levelToReplace)); final int margin = MonolineFormatter.levelWidth(null); final StringBuilder buffer = new StringBuilder(expected.length() + 40) .append(levelLocalized) .append(CharSequences.spaces(margin - levelLocalized.length())) .append(expected, levelToReplace.length() + 1, expected.length()); // +1 is for skipping '\t'. final String spaces = MonolineFormatter.CONTINUATION_MARK + CharSequences.spaces(margin - 1).toString(); int positionOfLast = -1; for (int i=margin; (i=buffer.indexOf("\n\t", i)) >= 0; i += margin) { buffer.replace(positionOfLast = ++i, i+1, spaces); // Replace only tabulation, leave new line. } if (positionOfLast >= 0) { buffer.setCharAt(positionOfLast, MonolineFormatter.CONTINUATION_END); } return buffer.toString(); }
/** * Tests formatting of a multi-line message. */ @Test @DependsOnMethod("testlevelWidth") public void testMultilines() { final LogRecord record = new LogRecord(Level.INFO, "First line\n Indented line\nLast line\n"); final String formatted = formatter.format(record); assertMultilinesEquals(localize(Level.INFO, "INFO\t First line\n" + "\t Indented line\n" + "\t Last line\n"), formatted); }
monoline = (MonolineFormatter) formatter; } else { monoline = new MonolineFormatter(handler); handler.setFormatter(monoline); monoline = new MonolineFormatter(handler); handler.setFormatter(monoline); logger.addHandler(handler);
/** * Installs a {@code MonolineFormatter} for the root logger, or returns the existing instance if any. * This method performs the following choices: * * <ul> * <li>If a {@link ConsoleHandler} is associated to the root logger, then: * <ul> * <li>If that handler already uses a {@code MonolineFormatter}, then the existing formatter is returned.</li> * <li>Otherwise the {@code ConsoleHandler} formatter is replaced by a new {@code MonolineFormatter} instance, * and that new instance is returned. We perform this replacement in order to avoid sending twice the same * records to the console.</li> * </ul></li> * <li>Otherwise a new {@code ConsoleHandler} using a new {@code MonolineFormatter} is created and added to the * root logger.</li> * </ul> * * <div class="note"><b>Implementation note:</b> * The current implementation does not check for duplicated {@code ConsoleHandler} instances, * and does not check if any child logger has a {@code ConsoleHandler}.</div> * * @return the new or existing {@code MonolineFormatter}. The formatter output can be configured * using the {@link #setTimeFormat(String)} and {@link #setSourceFormat(String)} methods. * @throws SecurityException if this method does not have the permission to install the formatter. */ @Configuration public static MonolineFormatter install() throws SecurityException { return install(Logging.getLogger(""), null); }
levelWidth = levelWidth((handler != null) ? handler.getLevel() : null); timeFormat(manager.getProperty(classname + ".time")); } catch (IllegalArgumentException exception) { Logging.configurationException(Logging.getLogger(Modules.UTILITIES), MonolineFormatter.class, "<init>", exception); sourceFormat(manager.getProperty(classname + ".source")); } catch (IllegalArgumentException exception) { Logging.configurationException(Logging.getLogger(Modules.UTILITIES), MonolineFormatter.class, "<init>", exception); resetLevelColors();
if (SHOW_LEVEL) { if (colors) { levelColor = colorAt(level); levelReset = X364.BACKGROUND_DEFAULT.sequence(); String message = formatMessage(record); int length = 0; if (message != null) { exception.printStackTrace(printer); } else { printAbridged(exception, writer, record.getLoggerName(), record.getSourceClassName(), record.getSourceMethodName());
/** * Tests {@link MonolineFormatter#levelWidth(Level)}. */ @Test public void testlevelWidth() { final String severe = Level.SEVERE.getLocalizedName(); assertEquals(severe, severe.length(), MonolineFormatter.levelWidth(Level.SEVERE)); final String warning = Level.WARNING.getLocalizedName(); assertEquals(warning, StrictMath.max(severe.length(), warning.length()), MonolineFormatter.levelWidth(Level.WARNING)); }
/** * Tests formatting a log record which contains an exception. */ @Test @DependsOnMethod("testlevelWidth") public void testException() { final LogRecord record = new LogRecord(Level.WARNING, "An exception occured."); final Exception exception = new Exception(); exception.setStackTrace(new StackTraceElement[] { new StackTraceElement("org.apache.sis.NonExistent", "foo", "NonExistent.java", 10), new StackTraceElement("org.junit.WhoKnows", "main", "WhoKnows.java", 20) }); record.setThrown(exception); String formatted = formatter.format(record); assertMultilinesEquals(localize(Level.WARNING, "WARNING\t An exception occured.\n" + "\t Caused by: java.lang.Exception\n" + "\t at org.apache.sis.NonExistent.foo(NonExistent.java:10)\n" + "\t at org.junit.WhoKnows.main(WhoKnows.java:20)\n"), formatted); /* * Remove the message and try again. */ record.setMessage(null); formatted = formatter.format(record); assertMultilinesEquals(localize(Level.WARNING, "WARNING\t java.lang.Exception\n" + "\t at org.apache.sis.NonExistent.foo(NonExistent.java:10)\n" + "\t at org.junit.WhoKnows.main(WhoKnows.java:20)\n"), formatted); } }
monoline = (MonolineFormatter) formatter; } else { monoline = new MonolineFormatter(handler); handler.setFormatter(monoline); monoline = new MonolineFormatter(handler); handler.setFormatter(monoline); logger.addHandler(handler);
MonolineFormatter.install();
/** * Resets the colors to the default values. This method does not check if <cite>ANSI escape codes</cite> * are supported or not - this check must be done by the caller. */ private void resetLevelColors() { final SortedMap<Level,X364> colors = colors(); colors.clear(); colors.put(Level.ALL, X364.BACKGROUND_GRAY); colors.put(Level.CONFIG, X364.BACKGROUND_BLUE); colors.put(Level.INFO, X364.BACKGROUND_GREEN); colors.put(Level.WARNING, X364.BACKGROUND_YELLOW); colors.put(Level.SEVERE, X364.BACKGROUND_RED); colors.put(PerformanceLevel.PERFORMANCE, X364.BACKGROUND_CYAN); }
if ("server".equalsIgnoreCase(get(properties, "platform", "desktop"))) { } else { MonolineFormatter.install();
if (color != null) { final X364 code = X364.forColorName(color).background(); changed = (colors().put(level, code) != code); } else if (colors != null) { changed = (colors.remove(level) != null);
if (color != null) { final X364 code = X364.forColorName(color).background(); changed = (colors().put(level, code) != code); } else if (colors != null) { changed = (colors.remove(level) != null);