1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/logging/ColorfulConsoleFormatter.java Mon Nov 17 18:12:27 2014 +0100
1.3 @@ -0,0 +1,100 @@
1.4 +/**
1.5 + * copy-image-resizer
1.6 + * Copyright © 2013 František Kučera (frantovo.cz)
1.7 + *
1.8 + * This program is free software: you can redistribute it and/or modify
1.9 + * it under the terms of the GNU General Public License as published by
1.10 + * the Free Software Foundation, either version 3 of the License, or
1.11 + * (at your option) any later version.
1.12 + *
1.13 + * This program is distributed in the hope that it will be useful,
1.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.16 + * GNU General Public License for more details.
1.17 + *
1.18 + * You should have received a copy of the GNU General Public License
1.19 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
1.20 + */
1.21 +package cz.frantovo.copyImageResizer.logging;
1.22 +
1.23 +import cz.frantovo.copyImageResizer.logging.ColorfulPrintWriter.TerminalColor;
1.24 +import cz.frantovo.copyImageResizer.logging.ColorfulPrintWriter.TerminalStyle;
1.25 +import java.io.StringWriter;
1.26 +import java.util.logging.Formatter;
1.27 +import java.util.logging.Level;
1.28 +import java.util.logging.LogRecord;
1.29 +
1.30 +/**
1.31 + * For console/terminal log output. Log messages are printed in brief and colorful form.
1.32 + *
1.33 + * @author Ing. František Kučera (frantovo.cz)
1.34 + */
1.35 +public class ColorfulConsoleFormatter extends Formatter {
1.36 +
1.37 + private boolean printStacktrace = false;
1.38 +
1.39 + @Override
1.40 + public String format(LogRecord r) {
1.41 + StringWriter sw = new StringWriter();
1.42 + try (ColorfulPrintWriter out = new ColorfulPrintWriter(sw)) {
1.43 + printLevel(out, r.getLevel());
1.44 + printMessage(out, r);
1.45 + printThrowable(out, r);
1.46 + out.println();
1.47 + }
1.48 + return sw.toString();
1.49 + }
1.50 +
1.51 + private void printLevel(ColorfulPrintWriter out, Level l) {
1.52 + TerminalColor color = TerminalColor.Magenta;
1.53 +
1.54 + if (l == Level.SEVERE) {
1.55 + color = TerminalColor.Red;
1.56 + } else if (l == Level.WARNING) {
1.57 + color = TerminalColor.Yellow;
1.58 + }
1.59 +
1.60 + out.print(color, rpad(l.getLocalizedName() + ": ", 10));
1.61 + }
1.62 +
1.63 + private void printMessage(ColorfulPrintWriter out, LogRecord r) {
1.64 + out.print(formatMessage(r));
1.65 + }
1.66 +
1.67 + private void printThrowable(ColorfulPrintWriter out, LogRecord r) {
1.68 + Throwable t = r.getThrown();
1.69 + if (t != null) {
1.70 + out.print(": ");
1.71 + out.print(TerminalColor.Red, t.getClass().getSimpleName());
1.72 + String message = t.getLocalizedMessage();
1.73 + if (message != null) {
1.74 + out.print(": ");
1.75 + out.print(message);
1.76 + }
1.77 + if (printStacktrace) {
1.78 + out.println();
1.79 + out.setForegroundColor(TerminalColor.Yellow);
1.80 + out.setStyle(TerminalStyle.Dim);
1.81 + t.printStackTrace(out);
1.82 + out.resetAll();
1.83 + }
1.84 + }
1.85 + }
1.86 +
1.87 + public boolean isPrintStacktrace() {
1.88 + return printStacktrace;
1.89 + }
1.90 +
1.91 + public void setPrintStacktrace(boolean printStacktrace) {
1.92 + this.printStacktrace = printStacktrace;
1.93 + }
1.94 +
1.95 + private static String rpad(String s, int n) {
1.96 + if (n > 0) {
1.97 + return String.format("%1$-" + n + "s", s);
1.98 + } else {
1.99 + return s;
1.100 + }
1.101 + }
1.102 +
1.103 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/logging/ColorfulPrintWriter.java Mon Nov 17 18:12:27 2014 +0100
2.3 @@ -0,0 +1,358 @@
2.4 +/**
2.5 + * copy-image-resizer
2.6 + * Copyright © 2013 František Kučera (frantovo.cz)
2.7 + *
2.8 + * This program is free software: you can redistribute it and/or modify
2.9 + * it under the terms of the GNU General Public License as published by
2.10 + * the Free Software Foundation, either version 3 of the License, or
2.11 + * (at your option) any later version.
2.12 + *
2.13 + * This program is distributed in the hope that it will be useful,
2.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.16 + * GNU General Public License for more details.
2.17 + *
2.18 + * You should have received a copy of the GNU General Public License
2.19 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
2.20 + */
2.21 +package cz.frantovo.copyImageResizer.logging;
2.22 +
2.23 +import java.io.File;
2.24 +import java.io.FileNotFoundException;
2.25 +import java.io.OutputStream;
2.26 +import java.io.PrintWriter;
2.27 +import java.io.UnsupportedEncodingException;
2.28 +import java.io.Writer;
2.29 +import java.util.EnumSet;
2.30 +
2.31 +/**
2.32 + * PrintWriter with convenience methods for printing color and formatted text.
2.33 + *
2.34 + * Uses ANSI Escape Sequences.
2.35 + * See: http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html
2.36 + *
2.37 + * @author Ing. František Kučera (frantovo.cz)
2.38 + */
2.39 +public class ColorfulPrintWriter extends PrintWriter {
2.40 +
2.41 + public enum TerminalColor {
2.42 +
2.43 + Black(30, 40),
2.44 + Red(31, 41),
2.45 + Green(32, 42),
2.46 + Yellow(33, 43),
2.47 + Blue(34, 44),
2.48 + Magenta(35, 45),
2.49 + Cyan(36, 46),
2.50 + White(37, 47);
2.51 + private final int foregroundCode;
2.52 + private final int backgroundCode;
2.53 +
2.54 + private TerminalColor(int foregroundCode, int backgroundCode) {
2.55 + this.foregroundCode = foregroundCode;
2.56 + this.backgroundCode = backgroundCode;
2.57 + }
2.58 +
2.59 + public int getForegroundCode() {
2.60 + return foregroundCode;
2.61 + }
2.62 +
2.63 + public int getBackgroundCode() {
2.64 + return backgroundCode;
2.65 + }
2.66 + }
2.67 +
2.68 + public enum TerminalStyle {
2.69 +
2.70 + Reset(0),
2.71 + Bright(1),
2.72 + Dim(2),
2.73 + Underscore(4),
2.74 + Blink(5),
2.75 + Reverse(7),
2.76 + Hidden(8);
2.77 + private int code;
2.78 +
2.79 + private TerminalStyle(int code) {
2.80 + this.code = code;
2.81 + }
2.82 +
2.83 + public int getCode() {
2.84 + return code;
2.85 + }
2.86 + }
2.87 + private final boolean COLOR_ENABLED;
2.88 + private boolean colorful = true;
2.89 +
2.90 + public void setStyle(TerminalStyle style) {
2.91 + setStyle(EnumSet.of(style));
2.92 + }
2.93 +
2.94 + public void setStyle(EnumSet<TerminalStyle> styles) {
2.95 + printCodes(getStyleCodes(styles));
2.96 + }
2.97 +
2.98 + private static int[] getStyleCodes(EnumSet<TerminalStyle> styles) {
2.99 + int[] array = new int[styles.size()];
2.100 + int i = 0;
2.101 + for (TerminalStyle s : styles) {
2.102 + array[i++] = s.getCode();
2.103 + }
2.104 + return array;
2.105 + }
2.106 +
2.107 + /**
2.108 + * Print (usually audible) bell code (\007, \a, ^G)
2.109 + */
2.110 + public void bell() {
2.111 + print("\007");
2.112 + }
2.113 +
2.114 + /**
2.115 + * Eat the last character
2.116 + */
2.117 + public void backspace() {
2.118 + print("\b");
2.119 + }
2.120 +
2.121 + /**
2.122 + * Eat n last characters
2.123 + *
2.124 + * @param count n
2.125 + */
2.126 + public void backspace(int count) {
2.127 + for (int i = 0; i < count; i++) {
2.128 + backspace();
2.129 + }
2.130 + }
2.131 +
2.132 + /**
2.133 + * With 100 ms delay and all colors.
2.134 + *
2.135 + * @see #printRainbow(java.lang.String, int,
2.136 + * info.globalcode.sql.dk.ColorfulPrintWriter.TerminalColor[])
2.137 + */
2.138 + public void printRainbow(String string) {
2.139 + printRainbow(string, 100);
2.140 + }
2.141 +
2.142 + /**
2.143 + * With all colors.
2.144 + *
2.145 + * @see #printRainbow(java.lang.String, int,
2.146 + * info.globalcode.sql.dk.ColorfulPrintWriter.TerminalColor[])
2.147 + */
2.148 + public void printRainbow(String string, int delay) {
2.149 + printRainbow(string, delay, TerminalColor.values());
2.150 + }
2.151 +
2.152 + /**
2.153 + * Prints rainbow text – (re)writes same text subsequently in given colors and then in default
2.154 + * color.
2.155 + *
2.156 + * @param string text to be printed, should not contain \n new line (then rainbow does not work
2.157 + * – use println() after printRainbow() instead)
2.158 + * @param delay delay between rewrites
2.159 + * @param colors list of colors to be used
2.160 + */
2.161 + public void printRainbow(String string, int delay, TerminalColor... colors) {
2.162 + for (TerminalColor c : colors) {
2.163 + print(c, string);
2.164 + try {
2.165 + Thread.sleep(delay);
2.166 + } catch (InterruptedException e) {
2.167 + // no time to sleep
2.168 + break;
2.169 + }
2.170 + backspace(string.length());
2.171 + flush();
2.172 + }
2.173 + print(string);
2.174 + }
2.175 +
2.176 + public void setForegroundColor(TerminalColor color) {
2.177 + printCodes(color.getForegroundCode());
2.178 + }
2.179 +
2.180 + public void setBackgroundColor(TerminalColor color) {
2.181 + printCodes(color.getBackgroundCode());
2.182 + }
2.183 +
2.184 + public void print(TerminalColor foregroundColor, String string) {
2.185 + setForegroundColor(foregroundColor);
2.186 + print(string);
2.187 + resetAll();
2.188 + }
2.189 +
2.190 + public void println(TerminalColor foregroundColor, String string) {
2.191 + print(foregroundColor, string);
2.192 + println();
2.193 + }
2.194 +
2.195 + public void print(TerminalColor foregroundColor, TerminalColor backgroundColor, String string) {
2.196 + setForegroundColor(foregroundColor);
2.197 + setBackgroundColor(backgroundColor);
2.198 + print(string);
2.199 + resetAll();
2.200 + }
2.201 +
2.202 + public void println(TerminalColor foregroundColor, TerminalColor backgroundColor, String string) {
2.203 + print(foregroundColor, backgroundColor, string);
2.204 + println();
2.205 + }
2.206 +
2.207 + public void print(TerminalColor foregroundColor, TerminalColor backgroundColor, EnumSet<TerminalStyle> styles, String string) {
2.208 + setForegroundColor(foregroundColor);
2.209 + setBackgroundColor(backgroundColor);
2.210 + setStyle(styles);
2.211 + print(string);
2.212 + resetAll();
2.213 + }
2.214 +
2.215 + public void println(TerminalColor foregroundColor, TerminalColor backgroundColor, EnumSet<TerminalStyle> styles, String string) {
2.216 + print(foregroundColor, backgroundColor, styles, string);
2.217 + println();
2.218 + }
2.219 +
2.220 + public void print(TerminalColor foregroundColor, TerminalColor backgroundColor, TerminalStyle style, String string) {
2.221 + print(foregroundColor, backgroundColor, EnumSet.of(style), string);
2.222 + }
2.223 +
2.224 + public void println(TerminalColor foregroundColor, TerminalColor backgroundColor, TerminalStyle style, String string) {
2.225 + print(foregroundColor, backgroundColor, style, string);
2.226 + println();
2.227 + }
2.228 +
2.229 + public void print(TerminalColor foregroundColor, EnumSet<TerminalStyle> styles, String string) {
2.230 + setForegroundColor(foregroundColor);
2.231 + setStyle(styles);
2.232 + print(string);
2.233 + resetAll();
2.234 + }
2.235 +
2.236 + public void println(TerminalColor foregroundColor, EnumSet<TerminalStyle> styles, String string) {
2.237 + print(foregroundColor, styles, string);
2.238 + println();
2.239 + }
2.240 +
2.241 + public void print(TerminalColor foregroundColor, TerminalStyle style, String string) {
2.242 + print(foregroundColor, EnumSet.of(style), string);
2.243 + }
2.244 +
2.245 + public void println(TerminalColor foregroundColor, TerminalStyle style, String string) {
2.246 + print(foregroundColor, style, string);
2.247 + println();
2.248 + }
2.249 +
2.250 + public void print(EnumSet<TerminalStyle> styles, String string) {
2.251 + setStyle(styles);
2.252 + print(string);
2.253 + resetAll();
2.254 + }
2.255 +
2.256 + public void println(EnumSet<TerminalStyle> styles, String string) {
2.257 + print(styles, string);
2.258 + println();
2.259 + }
2.260 +
2.261 + public void print(TerminalStyle style, String string) {
2.262 + print(EnumSet.of(style), string);
2.263 + }
2.264 +
2.265 + public void println(TerminalStyle style, String string) {
2.266 + print(style, string);
2.267 + println();
2.268 + }
2.269 +
2.270 + public void resetAll() {
2.271 + printCodes(TerminalStyle.Reset.code);
2.272 + }
2.273 +
2.274 + private void printCodes(int... codes) {
2.275 + if (COLOR_ENABLED && colorful) {
2.276 + print("\033[");
2.277 + for (int i = 0; i < codes.length; i++) {
2.278 + print(codes[i]);
2.279 + if (i < codes.length - 1 && codes.length > 1) {
2.280 + print(";");
2.281 + }
2.282 + }
2.283 + print("m");
2.284 + }
2.285 + }
2.286 +
2.287 + /**
2.288 + * Colors can be switched on/off during usage of this writer.
2.289 + *
2.290 + * @return whether colors are currently turned on
2.291 + * @see #isColorEnabled()
2.292 + */
2.293 + public boolean isColorful() {
2.294 + return colorful;
2.295 + }
2.296 +
2.297 + /**
2.298 + * Collors might be definitively disabled in constructor. If not, they can be turned on/off
2.299 + * during usage of this writer by {@linkplain #setColorful(boolean)}
2.300 + *
2.301 + * @return whether colors are allowed for this instance of this class
2.302 + * @see #isColorful()
2.303 + */
2.304 + public boolean isColorEnabled() {
2.305 + return COLOR_ENABLED;
2.306 + }
2.307 +
2.308 + /**
2.309 + * @see #isColorful()
2.310 + * @see #isColorEnabled()
2.311 + */
2.312 + public void setColorful(boolean colorful) {
2.313 + this.colorful = colorful;
2.314 + }
2.315 +
2.316 + public ColorfulPrintWriter(File file) throws FileNotFoundException {
2.317 + super(file);
2.318 + COLOR_ENABLED = true;
2.319 + }
2.320 +
2.321 + public ColorfulPrintWriter(OutputStream out) {
2.322 + super(out);
2.323 + COLOR_ENABLED = true;
2.324 + }
2.325 +
2.326 + public ColorfulPrintWriter(String fileName) throws FileNotFoundException {
2.327 + super(fileName);
2.328 + COLOR_ENABLED = true;
2.329 + }
2.330 +
2.331 + public ColorfulPrintWriter(Writer out) {
2.332 + super(out);
2.333 + COLOR_ENABLED = true;
2.334 + }
2.335 +
2.336 + public ColorfulPrintWriter(File file, String csn) throws FileNotFoundException, UnsupportedEncodingException {
2.337 + super(file, csn);
2.338 + COLOR_ENABLED = true;
2.339 + }
2.340 +
2.341 + /**
2.342 + * @param colorEnabled colors might be definitively disabled by this option – this might be more
2.343 + * optimalizable than dynamic turning off colors by {@linkplain #setColorful(boolean)} which is
2.344 + * not definitive (colors can be turned on during live of this instance). This might be useful
2.345 + * if you need an instance of this class but don't need colors at all.
2.346 + */
2.347 + public ColorfulPrintWriter(OutputStream out, boolean autoFlush, boolean colorEnabled) {
2.348 + super(out, autoFlush);
2.349 + COLOR_ENABLED = colorEnabled;
2.350 + }
2.351 +
2.352 + public ColorfulPrintWriter(String fileName, String csn) throws FileNotFoundException, UnsupportedEncodingException {
2.353 + super(fileName, csn);
2.354 + COLOR_ENABLED = true;
2.355 + }
2.356 +
2.357 + public ColorfulPrintWriter(Writer out, boolean autoFlush) {
2.358 + super(out, autoFlush);
2.359 + COLOR_ENABLED = true;
2.360 + }
2.361 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/logging/ConsoleLoggerInitializer.java Mon Nov 17 18:12:27 2014 +0100
3.3 @@ -0,0 +1,78 @@
3.4 +/**
3.5 + * copy-image-resizer
3.6 + * Copyright © 2013 František Kučera (frantovo.cz)
3.7 + *
3.8 + * This program is free software: you can redistribute it and/or modify
3.9 + * it under the terms of the GNU General Public License as published by
3.10 + * the Free Software Foundation, either version 3 of the License, or
3.11 + * (at your option) any later version.
3.12 + *
3.13 + * This program is distributed in the hope that it will be useful,
3.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3.16 + * GNU General Public License for more details.
3.17 + *
3.18 + * You should have received a copy of the GNU General Public License
3.19 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
3.20 + */
3.21 +package cz.frantovo.copyImageResizer.logging;
3.22 +
3.23 +import cz.frantovo.copyImageResizer.Constants;
3.24 +import java.util.logging.ConsoleHandler;
3.25 +import java.util.logging.Handler;
3.26 +import java.util.logging.Level;
3.27 +import java.util.logging.Logger;
3.28 +
3.29 +/**
3.30 + * Configures logging subsystem.
3.31 + * Usage: java -Djava.util.logging.config.class=info.globalcode.sql.dk.logging.ConsoleLoggerInitializer …
3.32 + *
3.33 + * @author Ing. František Kučera (frantovo.cz)
3.34 + */
3.35 +public class ConsoleLoggerInitializer {
3.36 +
3.37 + private static final Logger log = Logger.getLogger(ConsoleLoggerInitializer.class.getName());
3.38 + public static final String LEVEL_PROPERTY = ConsoleLoggerInitializer.class.getName() + ".level";
3.39 + private static final Level DEFAULT_LEVEL = Level.INFO;
3.40 +
3.41 + public ConsoleLoggerInitializer() {
3.42 + Logger logger = Logger.getLogger(Constants.JAVA_PACKAGE);
3.43 + ConsoleHandler handler = new ConsoleHandler();
3.44 + ColorfulConsoleFormatter formatter = new ColorfulConsoleFormatter();
3.45 +
3.46 + logger.addHandler(handler);
3.47 + handler.setFormatter(formatter);
3.48 +
3.49 + setLevel(logger, handler, formatter);
3.50 +
3.51 +
3.52 + /**
3.53 + * TODO: optional FileHandler – detailed logs in file in ~/sql-dk/log/…
3.54 + */
3.55 + }
3.56 +
3.57 + private void setLevel(Logger logger, Handler handler, ColorfulConsoleFormatter formatter) {
3.58 + boolean levelParseError = false;
3.59 + Level level;
3.60 + String cliLevel = System.getProperty(LEVEL_PROPERTY);
3.61 + if (cliLevel == null) {
3.62 + level = DEFAULT_LEVEL;
3.63 + } else {
3.64 + try {
3.65 + level = Level.parse(cliLevel);
3.66 + } catch (IllegalArgumentException e) {
3.67 + level = DEFAULT_LEVEL;
3.68 + levelParseError = true;
3.69 + }
3.70 + }
3.71 +
3.72 + handler.setLevel(level);
3.73 + logger.setLevel(level);
3.74 +
3.75 + if (levelParseError) {
3.76 + log.log(Level.WARNING, "Invalid logging level „{0}“ specified in „{1}“ → using default level „{2}“", new Object[]{cliLevel, LEVEL_PROPERTY, DEFAULT_LEVEL});
3.77 + }
3.78 +
3.79 + formatter.setPrintStacktrace(level.intValue() < Level.INFO.intValue());
3.80 + }
3.81 +}