# HG changeset patch # User František Kučera # Date 1416257932 -3600 # Node ID 4634176c6602820cfe562a3fb15daff678f34bb5 # Parent 93fa6ce675e5350d62e84bedb4f20bd40ba88947 logging: two log formatters: ColorfulConsoleFormatter and SimpleFormatter diff -r 93fa6ce675e5 -r 4634176c6602 java/copy-image-resizer/src/cz/frantovo/copyImageResizer/logging/AbstractFormatter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/logging/AbstractFormatter.java Mon Nov 17 21:58:52 2014 +0100 @@ -0,0 +1,46 @@ +/** + * copy-image-resizer + * Copyright © 2013 František Kučera (frantovo.cz) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package cz.frantovo.copyImageResizer.logging; + +import java.util.logging.Formatter; + +/** + * + * @author Ing. František Kučera (frantovo.cz) + */ +public abstract class AbstractFormatter extends Formatter { + + protected static String rpad(String s, int n) { + if (n > 0) { + return String.format("%1$-" + n + "s", s); + } else { + return s; + } + } + + private boolean printStacktrace = false; + + public boolean isPrintStacktrace() { + return printStacktrace; + } + + public void setPrintStacktrace(boolean printStacktrace) { + this.printStacktrace = printStacktrace; + } + +} diff -r 93fa6ce675e5 -r 4634176c6602 java/copy-image-resizer/src/cz/frantovo/copyImageResizer/logging/AbstractInitializer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/logging/AbstractInitializer.java Mon Nov 17 21:58:52 2014 +0100 @@ -0,0 +1,76 @@ +/** + * copy-image-resizer + * Copyright © 2013 František Kučera (frantovo.cz) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package cz.frantovo.copyImageResizer.logging; + +import cz.frantovo.copyImageResizer.Constants; +import java.util.logging.ConsoleHandler; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author Ing. František Kučera (frantovo.cz) + */ +public abstract class AbstractInitializer { + + private static final Logger log = Logger.getLogger(AbstractInitializer.class.getName()); + + public static final String LEVEL_PROPERTY = AbstractInitializer.class.getName() + ".level"; + protected static final Level DEFAULT_LEVEL = Level.INFO; + + protected abstract AbstractFormatter createFormatter(); + + public AbstractInitializer() { + Logger logger = Logger.getLogger(Constants.JAVA_PACKAGE); + ConsoleHandler handler = new ConsoleHandler(); + AbstractFormatter formatter = createFormatter(); + + logger.addHandler(handler); + handler.setFormatter(formatter); + + setLevel(logger, handler, formatter); + + /** + * TODO: optional FileHandler – detailed logs in file in ~/sql-dk/log/… + */ + } + + protected void setLevel(Logger logger, Handler handler, AbstractFormatter formatter) { + boolean levelParseError = false; + Level level; + String cliLevel = System.getProperty(LEVEL_PROPERTY); + if (cliLevel == null) { + level = DEFAULT_LEVEL; + } else { + try { + level = Level.parse(cliLevel); + } catch (IllegalArgumentException e) { + level = DEFAULT_LEVEL; + levelParseError = true; + } + } + handler.setLevel(level); + logger.setLevel(level); + if (levelParseError) { + log.log(Level.WARNING, "Invalid logging level \u201e{0}\u201c specified in \u201e{1}\u201c \u2192 using default level \u201e{2}\u201c", new Object[]{cliLevel, LEVEL_PROPERTY, DEFAULT_LEVEL}); + } + formatter.setPrintStacktrace(level.intValue() < Level.INFO.intValue()); + } + +} diff -r 93fa6ce675e5 -r 4634176c6602 java/copy-image-resizer/src/cz/frantovo/copyImageResizer/logging/ColorfulConsoleFormatter.java --- a/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/logging/ColorfulConsoleFormatter.java Mon Nov 17 20:38:38 2014 +0100 +++ b/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/logging/ColorfulConsoleFormatter.java Mon Nov 17 21:58:52 2014 +0100 @@ -20,7 +20,6 @@ import cz.frantovo.copyImageResizer.logging.ColorfulPrintWriter.TerminalColor; import cz.frantovo.copyImageResizer.logging.ColorfulPrintWriter.TerminalStyle; import java.io.StringWriter; -import java.util.logging.Formatter; import java.util.logging.Level; import java.util.logging.LogRecord; @@ -29,9 +28,7 @@ * * @author Ing. František Kučera (frantovo.cz) */ -public class ColorfulConsoleFormatter extends Formatter { - - private boolean printStacktrace = false; +public class ColorfulConsoleFormatter extends AbstractFormatter { @Override public String format(LogRecord r) { @@ -71,7 +68,7 @@ out.print(": "); out.print(message); } - if (printStacktrace) { + if (isPrintStacktrace()) { out.println(); out.setForegroundColor(TerminalColor.Yellow); out.setStyle(TerminalStyle.Dim); @@ -80,21 +77,4 @@ } } } - - public boolean isPrintStacktrace() { - return printStacktrace; - } - - public void setPrintStacktrace(boolean printStacktrace) { - this.printStacktrace = printStacktrace; - } - - private static String rpad(String s, int n) { - if (n > 0) { - return String.format("%1$-" + n + "s", s); - } else { - return s; - } - } - } diff -r 93fa6ce675e5 -r 4634176c6602 java/copy-image-resizer/src/cz/frantovo/copyImageResizer/logging/ConsoleLoggerInitializer.java --- a/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/logging/ConsoleLoggerInitializer.java Mon Nov 17 20:38:38 2014 +0100 +++ b/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/logging/ConsoleLoggerInitializer.java Mon Nov 17 21:58:52 2014 +0100 @@ -17,62 +17,17 @@ */ package cz.frantovo.copyImageResizer.logging; -import cz.frantovo.copyImageResizer.Constants; -import java.util.logging.ConsoleHandler; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.Logger; - /** * Configures logging subsystem. - * Usage: java -Djava.util.logging.config.class=info.globalcode.sql.dk.logging.ConsoleLoggerInitializer … + * Usage: java + * -Djava.util.logging.config.class=cz.frantovo.copyImageResizer.logging.ConsoleLoggerInitializer … * * @author Ing. František Kučera (frantovo.cz) */ -public class ConsoleLoggerInitializer { +public class ConsoleLoggerInitializer extends AbstractInitializer { - private static final Logger log = Logger.getLogger(ConsoleLoggerInitializer.class.getName()); - public static final String LEVEL_PROPERTY = ConsoleLoggerInitializer.class.getName() + ".level"; - private static final Level DEFAULT_LEVEL = Level.INFO; - - public ConsoleLoggerInitializer() { - Logger logger = Logger.getLogger(Constants.JAVA_PACKAGE); - ConsoleHandler handler = new ConsoleHandler(); - ColorfulConsoleFormatter formatter = new ColorfulConsoleFormatter(); - - logger.addHandler(handler); - handler.setFormatter(formatter); - - setLevel(logger, handler, formatter); - - - /** - * TODO: optional FileHandler – detailed logs in file in ~/sql-dk/log/… - */ - } - - private void setLevel(Logger logger, Handler handler, ColorfulConsoleFormatter formatter) { - boolean levelParseError = false; - Level level; - String cliLevel = System.getProperty(LEVEL_PROPERTY); - if (cliLevel == null) { - level = DEFAULT_LEVEL; - } else { - try { - level = Level.parse(cliLevel); - } catch (IllegalArgumentException e) { - level = DEFAULT_LEVEL; - levelParseError = true; - } - } - - handler.setLevel(level); - logger.setLevel(level); - - if (levelParseError) { - log.log(Level.WARNING, "Invalid logging level „{0}“ specified in „{1}“ → using default level „{2}“", new Object[]{cliLevel, LEVEL_PROPERTY, DEFAULT_LEVEL}); - } - - formatter.setPrintStacktrace(level.intValue() < Level.INFO.intValue()); + @Override + protected AbstractFormatter createFormatter() { + return new ColorfulConsoleFormatter(); } } diff -r 93fa6ce675e5 -r 4634176c6602 java/copy-image-resizer/src/cz/frantovo/copyImageResizer/logging/SimpleFormatter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/logging/SimpleFormatter.java Mon Nov 17 21:58:52 2014 +0100 @@ -0,0 +1,103 @@ +/** + * copy-image-resizer + * Copyright © 2013 František Kučera (frantovo.cz) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package cz.frantovo.copyImageResizer.logging; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +/** + * For console/terminal log output. Log messages are printed in brief and colorful form. + * + * @author Ing. František Kučera (frantovo.cz) + */ +public class SimpleFormatter extends AbstractFormatter { + + private static final ThreadLocal dateFormatter = new ThreadLocal() { + + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + } + + }; + + @Override + public String format(LogRecord r) { + StringBuilder sb = new StringBuilder(); + + printTimestamp(sb, new Date(r.getMillis())); + printSeparator(sb); + printLevel(sb, r.getLevel()); + printSeparator(sb); + printMessage(sb, r); + printSeparator(sb); + printThrowable(sb, r); + sb.append("\n"); + + return sb.toString(); + } + + private void printSeparator(StringBuilder out) { + out.append(" | "); + } + + private void printTimestamp(StringBuilder out, Date date) { + out.append(dateFormatter.get().format(date)); + } + + private void printLevel(StringBuilder out, Level l) { + + if (l == Level.SEVERE) { + out.append(rpad("ERROR", 10)); + } else if (l == Level.INFO) { + out.append(rpad("OK", 10)); + } else { + out.append(rpad(l.getName(), 10)); + } + } + + private void printMessage(StringBuilder out, LogRecord r) { + String message = formatMessage(r); + // convert to single-line message + message = message.replaceAll("\\\\", "\\\\"); // escape backslashes + message = message.replaceAll("\\n", "\\n"); // escape line ends + out.append(message); + } + + private void printThrowable(StringBuilder out, LogRecord r) { + Throwable t = r.getThrown(); + if (t != null) { + out.append(t.getClass().getSimpleName()); + String message = t.getLocalizedMessage(); + if (message != null) { + out.append(": "); + out.append(message); + } + if (isPrintStacktrace()) { + out.append("\n"); + StringWriter sw = new StringWriter(); + t.printStackTrace(new PrintWriter(sw)); + out.append(sw.toString()); + } + } + } +} diff -r 93fa6ce675e5 -r 4634176c6602 java/copy-image-resizer/src/cz/frantovo/copyImageResizer/logging/SimpleLoggerInitializer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/logging/SimpleLoggerInitializer.java Mon Nov 17 21:58:52 2014 +0100 @@ -0,0 +1,36 @@ +/** + * copy-image-resizer + * Copyright © 2013 František Kučera (frantovo.cz) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package cz.frantovo.copyImageResizer.logging; + +/** + * Configures logging subsystem. + * Usage: java + * -Djava.util.logging.config.class=cz.frantovo.copyImageResizer.logging.SimpleLoggerInitializer … + * + * @author Ing. František Kučera (frantovo.cz) + */ +public class SimpleLoggerInitializer extends AbstractInitializer { + + public static final String LEVEL_PROPERTY = ConsoleLoggerInitializer.class.getName() + ".level"; + + @Override + protected AbstractFormatter createFormatter() { + return new SimpleFormatter(); + } + +} diff -r 93fa6ce675e5 -r 4634176c6602 scripts/copy-image-resizer.sh --- a/scripts/copy-image-resizer.sh Mon Nov 17 20:38:38 2014 +0100 +++ b/scripts/copy-image-resizer.sh Mon Nov 17 21:58:52 2014 +0100 @@ -19,6 +19,8 @@ DIR="`dirname $0`"; JAR="$DIR/../java/copy-image-resizer/dist/copy-image-resizer.jar"; +# TODO: tune the path to the .jar file + LOGGER="-Djava.util.logging.config.class=info.globalcode.sql.dk.logging.LoggerInitializer"; [ -n "$LOG_LEVEL" ] && LOGGER_LEVEL="-Dinfo.globalcode.sql.dk.logging.LoggerInitializer.level=$LOG_LEVEL"; @@ -26,10 +28,14 @@ MAIN_CLASS="cz.frantovo.copyImageResizer.cli.CLIStarter"; -LOGGER_INITIALIZER_CLASS="cz.frantovo.copyImageResizer.logging.ConsoleLoggerInitializer"; +# Customize logger output: +LOGGER_INITIALIZER_CLASS="cz.frantovo.copyImageResizer.logging.ConsoleLoggerInitializer"; # colorful log for interactive work (human readable) +LOGGER_INITIALIZER_CLASS="cz.frantovo.copyImageResizer.logging.SimpleLoggerInitializer"; # simple log for redirecting STDOUT to a file (machine readable) + LOGGER="-Djava.util.logging.config.class=$LOGGER_INITIALIZER_CLASS"; -[ -n "$LOG_LEVEL" ] && LOGGER_LEVEL="-D$LOGGER_INITIALIZER_CLASS.level=$LOG_LEVEL"; + +# by LOG_LEVEL variable you can set custom log level. Default is INFO. Possible values are: ALL, FINE, FINER, FINEST, CONFIG, INFO, OFF. SEVERE, WARNING (see java.util.logging.Level class) +[ -n "$LOG_LEVEL" ] && LOGGER_LEVEL="-Dcz.frantovo.copyImageResizer.logging.AbstractInitializer.level=$LOG_LEVEL"; java $LOGGER $LOGGER_LEVEL -cp "$CLASS_PATH" $MAIN_CLASS "$@" -