Skip to content

Instantly share code, notes, and snippets.

@basinilya
Last active July 27, 2019 08:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save basinilya/2ba09438acf8ecd113b2b2224d21b3bb to your computer and use it in GitHub Desktop.
Save basinilya/2ba09438acf8ecd113b2b2224d21b3bb to your computer and use it in GitHub Desktop.
Custom MessageFormat for java.util.logging
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