Last active
July 27, 2019 08:27
-
-
Save basinilya/2ba09438acf8ecd113b2b2224d21b3bb to your computer and use it in GitHub Desktop.
Custom MessageFormat for java.util.logging
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.foo.myloggerformatter; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.text.DateFormat; | |
import java.text.FieldPosition; | |
import java.text.Format; | |
import java.text.MessageFormat; | |
import java.text.ParsePosition; | |
import java.util.Date; | |
import java.util.Locale; | |
import java.util.logging.Handler; | |
import java.util.logging.Level; | |
import java.util.logging.LogManager; | |
import java.util.logging.LogRecord; | |
import java.util.logging.Logger; | |
import java.util.logging.SimpleFormatter; | |
/** | |
* Formats parameterized logger messages using toString() instead of the Locale-specific formatter | |
*/ | |
public class MyLoggerFormatter extends SimpleFormatter { | |
public static void main(final String[] args) throws Exception { | |
final Logger logger = Logger.getLogger(MyLoggerFormatter.class.getName()); | |
final Object obj = 4242; | |
final Object[] objects = new Object[] { obj }; | |
for (final Handler han : logger.getParent().getHandlers()) { | |
han.setFormatter(new MyLoggerFormatter()); | |
} | |
logger.log(Level.SEVERE, "{0}", obj); | |
final StringBuffer sb = new StringBuffer(); | |
final FieldPosition fp = new FieldPosition(0); | |
} | |
private MessageFormat getMessageFormat(final String pattern) { | |
final MessageFormat mf = new MessageFormat(pattern); | |
mf.setLocale(Locale.US); | |
final Format[] fmts = mf.getFormatsByArgumentIndex(); | |
for (int i = 0; i < fmts.length; i++) { | |
if (fmts[i] == null) { | |
fmts[i] = new MyFormat(mf.getLocale()); | |
} | |
} | |
mf.setFormatsByArgumentIndex(fmts); | |
return mf; | |
} | |
@Override | |
public synchronized String formatMessage(final LogRecord record) { | |
String format = record.getMessage(); | |
final java.util.ResourceBundle catalog = record.getResourceBundle(); | |
if (catalog != null) { | |
try { | |
format = catalog.getString(record.getMessage()); | |
} catch (final java.util.MissingResourceException ex) { | |
// Drop through. Use record message as format | |
format = record.getMessage(); | |
} | |
} | |
// Do the formatting. | |
try { | |
final Object[] parameters = record.getParameters(); | |
if (parameters == null || parameters.length == 0) { | |
// No parameters. Just return format string. | |
return format; | |
} | |
// Is it a java.text style format? | |
// Ideally we could match with | |
// Pattern.compile("\\{\\d").matcher(format).find()) | |
// However the cost is 14% higher, so we cheaply check for | |
// 1 of the first 4 parameters | |
if (format.indexOf("{0") >= 0 || format.indexOf("{1") >= 0 || format.indexOf("{2") >= 0 | |
|| format.indexOf("{3") >= 0) { | |
return getMessageFormat(format).format(parameters); | |
} | |
return format; | |
} catch (final Exception /* NOSONAR */ ex) { | |
// Formatting failed: use localized format string. | |
return format; | |
} | |
} | |
} | |
class MyFormat extends Format { | |
private static final long serialVersionUID = 1L; | |
private final Locale locale; | |
MyFormat(final Locale locale) { | |
this.locale = locale; | |
} | |
@Override | |
public StringBuffer format( | |
final Object obj, | |
final StringBuffer toAppendTo, | |
final FieldPosition pos) { | |
toAppendTo.append('<'); | |
{ | |
String arg = null; | |
Format subFormatter = null; | |
if (obj == null) { | |
arg = "null"; | |
} else if (obj instanceof Number) { | |
// format number if can | |
arg = obj.toString(); | |
// subFormatter = NumberFormat.getInstance(locale); | |
} else if (obj instanceof Date) { | |
// format a Date if can | |
subFormatter = | |
DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale); | |
} else if (obj instanceof String) { | |
arg = (String) obj; | |
} else { | |
arg = obj.toString(); | |
if (arg == null) { | |
arg = "null"; | |
} | |
} | |
if (subFormatter == null) { | |
toAppendTo.append(arg); | |
} else { | |
subFormatter.format(obj, toAppendTo, pos); | |
} | |
} | |
toAppendTo.append('>'); | |
return toAppendTo; | |
} | |
@Override | |
public Object parseObject(final String source, final ParsePosition pos) { | |
throw new UnsupportedOperationException(); | |
} | |
private static boolean inited; | |
public static synchronized void init() { | |
if (!inited) { | |
inited = true; | |
try ( | |
InputStream is = MyLoggerFormatter.class.getResourceAsStream("logger.properties")) { | |
if (is != null) { | |
// LogManager.getLogManager().res | |
LogManager.getLogManager().readConfiguration(is); | |
} | |
} catch (final IOException e) { | |
// | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment