12

I am using Java Util logging and whenever I do statement like this

logger.log(Level.INFO, "print this number = {0}", number);

it formats my number from 278487683165614 to 278,487,683,165,614

this is extremely annoying while searching through logs.

Can i stop it from doing this ? Please help.

kmatyaszek
  • 19,016
  • 9
  • 60
  • 65
Robin Bajaj
  • 2,002
  • 4
  • 29
  • 47
  • 1
    log the number as a string, maybe? may be able to bypass the number formatting that way. – mre Nov 16 '12 at 22:27

4 Answers4

13

The default format isn't what you want, change it like this :

{0,number,#}

EDIT :

Here you have more information about MessageFormatPattern http://docs.oracle.com/javase/1.5.0/docs/api/java/text/MessageFormat.html

Alexandre Lavoie
  • 8,711
  • 3
  • 31
  • 72
  • u mean like this ?? logger.log(Level.INFO, "print this number = {0, number, #}", number); – Robin Bajaj Nov 16 '12 at 22:36
  • Exactly, same as when you are using i18n resources for text! – Alexandre Lavoie Nov 16 '12 at 22:36
  • that didn't work. it prints as "print this number = 0" in this case – Robin Bajaj Nov 16 '12 at 22:41
  • I think you need to use this way unfortunatly : String result = MessageFormat.format( "At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.", planet, new Date(), event); – Alexandre Lavoie Nov 16 '12 at 22:43
  • thx for your response. that will get clunky for my use, but I am sure it will work. Going with String.valueof(number) for now. – Robin Bajaj Nov 16 '12 at 23:05
  • Every situation has it solution :) – Alexandre Lavoie Nov 16 '12 at 23:14
  • 2
    This worked fine for me without the use of `MesageFormat`. This solution is also likely faster/more efficient than `String.valueOf` or `number.toString` since the logger won't bother formatting the number if the handler's log level isn't reached. If you use `String.valueOf`, it must be called every time regardless of the log level. – Alvin Thompson Jun 30 '16 at 18:01
2

Try one of the below (don't have the visibility of your number object type):

  1. Using String.valueOf()

    logger.log(Level.INFO, "print this number = {0}", String.valueOf(number));
    
  2. Using Number.toString

    logger.log(Level.INFO, "print this number = {0}", number.toString);
    
  3. Using NumberFormat.setGroupingUsed(false)

    NumberFormat formatter = new NumberFormat();     
    formatter.setGroupingUsed(false);
    logger.log(Level.INFO, "print this number = {0}", formatter.format(number));
    
Yogendra Singh
  • 33,927
  • 6
  • 63
  • 73
  • 1
    This does extra work that is the responsibility of the https://docs.oracle.com/javase/7/docs/api/java/util/logging/Formatter.html specifically. And it also does extra processing on the CPU even if the logging might not be enabled. Don't do this. – searchengine27 Oct 30 '18 at 22:17
  • Could you please elaborate on an alternative way of avoiding the thousands while logging numbers? (it is extremely annoying, I am so surprised they decided to do in that way) – M.E. Jun 03 '20 at 18:24
1

Have you tried number.toString()?

svbnet
  • 1,070
  • 3
  • 11
  • 29
-1

This is harder than it should be, but it's possible. The logging framework ends up passing log records to handlers, which use a formatter to format them, producing strings. By default, they use a SimpleFormatter, whose formatMessage method ends up using MessageFormat to do the work.

It's possible to modify a MessageFormat to not format numbers, and just convert them using toString. So we need to write our own formatter which uses MessageFormat, but does that. It's ugly but it works.

Here's what i wrote:

public class SimplerFormatter extends SimpleFormatter {

    private static final Format TRIVIAL_FORMAT = new Format() {
        @Override
        public StringBuffer format(Object obj, StringBuffer buf, FieldPosition pos) {
            pos.setBeginIndex(buf.length());
            buf.append(obj);
            pos.setEndIndex(buf.length());
            return buf;
        }

        @Override
        public Object parseObject(String source, ParsePosition pos) {
            throw new UnsupportedOperationException();
        }
    };

    @Override
    public String formatMessage(LogRecord record) {
        String format = record.getMessage();

        Object[] parameters = record.getParameters();
        if (parameters == null || parameters.length == 0) {
            return format;
        }

        try {
            return newMessageFormat(format).format(parameters);
        } catch (Exception e) {
            return format;
        }
    }

    private static MessageFormat newMessageFormat(String format) {
        MessageFormat messageFormat = new MessageFormat(format);

        Format[] argumentFormats = messageFormat.getFormats();
        for (int i = 0; i < argumentFormats.length; i++) {
            if (argumentFormats[i] == null) {
                messageFormat.setFormat(i, TRIVIAL_FORMAT);
            }
        }

        return messageFormat;
    }

}

Pass an instance of that to Handler::setFormat, and that handler will no longer format your numbers.

Tom Anderson
  • 46,189
  • 17
  • 92
  • 133
  • Woah....100 percent no. The most upvoted answer is literally how you use the stock formatter provided by default to format a number without commas. This is an insane amount of things to re-do, for something the stock formatter does for you by default. – searchengine27 Aug 01 '23 at 19:11
  • @searchengine27 The answer by Alexandre Lavoie requires changing the call sites, and so as far as i'm concerned, is not an answer to this question at all. This is indeed some crufty code, but that's because the poor architecture of java.util.logging and java.text require such code to do this! – Tom Anderson Aug 22 '23 at 12:16