6

I have a SimpleFormatter for logging in my application with the string
"%1$tF %1$tT %4$-7s %2$s %5$s%6$s%n"

I would like to use the simple class name rather than the canonical name. Is there a format option I can use with the 2$ field? Or does this require writing a new Handler?

For example, rather than
2019-02-06 07:09:09 INFO simplex.tools.SIMPLEXScheduler main Start

I'd like to see
2019-02-06 07:09:09 INFO SIMPLEXScheduler main Start

3
  • HOw do you initialize your Logger with the full class name I suppose. Just put in the simple class name there. Commented Feb 6, 2019 at 17:59
  • I use Logger.getGlobal(). I call it from many different classes and it returns the right class name; I just don't want the full path to the class. Commented Feb 6, 2019 at 18:16
  • you could use the logp(Level level, String sourceClass, String sourceMethod, String msg) method to do your logging calls, passing in the simple class name and a perhaps empty method name, as this builds the LogRecords source entry But I'd rather recommend that you take your time to have a look at the different logging frameworks (skf4j, logback, log4j2 etc.), because they are way more flexible especially when it comes to formatting and controlling the output. Commented Feb 7, 2019 at 7:11

2 Answers 2

1

Is there a format option I can use with the 2$ field?

The SimpleFormatter only supports the functionality in the java.util.Formatter. Currently there is no way to format class name as simple class name.

Or does this require writing a new Handler?

One option is to write a new java.util.logging.Formatter. There are some hacks that you can do by just installing a java.util.logging.Filter to change the class name but you should avoid doing that. Use logp instead as suggested by P.J.Meisch

Disclaimer: I'm a content developer for com.sun.mail.util.logging package included with the JavaMail project.

If you have access to JavaMail you can use the com.sun.mail.util.logging.CompactFormatter which will only print the simple class name. The trade off is that it will print compact stack traces for exceptions. Arguments 1 through 6 are the same order as the SimpleFormatter so the same pattern can be used.

If you don't want to include JavaMail then you can use the com.sun.mail:logging-mailhandler artifact instead.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I think writing a new Formatter would be the easiest solution.
1

I wrote a custom Formatter as suggested by jmehrens. If I need something more complicated I may try moving to another framework like log4j but this does what I want for now. Thanks for the advice!

                Formatter formatter = new Formatter() {
                    @Override
                    public String format(LogRecord record) {
                        String source = "";
                        if (record.getSourceClassName() != null) {
                            try {
                                source = Class.forName(record.getSourceClassName()).getSimpleName();
                            } catch (ClassNotFoundException e) {
                                e.printStackTrace();
                            }
                            if (record.getSourceMethodName() != null) {
                                source += " " + record.getSourceMethodName();
                            }
                        } else {
                            source = record.getLoggerName();
                        }
                        String message = formatMessage(record);
                        String throwable = "";
                        if (record.getThrown() != null) {
                            StringWriter sw = new StringWriter();
                            PrintWriter pw = new PrintWriter(sw);
                            pw.println();
                            record.getThrown().printStackTrace(pw);
                            pw.close();
                            throwable = sw.toString();
                        }
                        return String.format(getLogFormat(), new Date(record.getMillis()), source,
                                record.getLoggerName(), record.getLevel(), message, throwable);
                    }

                };

1 Comment

You should catch LinkageError and RuntimeException thrown from Class.forName. Instead of logging the stacktrace you could just substitute the (record.getSourceClassName(). Otherwise if you run in to an issue with class loading in your current code you'll have the a blank class name.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.