简体   繁体   中英

GlassFish 3: how do you change the (default) logging format?

The question originated from here: http://www.java.net/forum/topic/glassfish/glassfish/configuring-glassfish-logging-format - without an answer.

The default GlassFish 3 logging format is very annoying, much too long.

[#|2012-03-02T09:22:03.165+0100|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=113;_ThreadName=AWT-EventQueue-0;| MESSAGE... ]

This is just a horrible default IMO. The docs just explain all the fields, but not how to change the format: http://docs.oracle.com/cd/E18930_01/html/821-2416/abluk.html

Note, that I deploy SLF4J along with my webapp which should pick up the format as well.

How do you change the logging format?

FYI:

The links here are outdated: Install log formater in glassfish ...

The question here hasn't been answered: How to configure GlassFish logging to show milliseconds in timestamps? ...

The posting here resulted in nothing: http://www.java.net/forum/topic/glassfish/glassfish/cant-seem-configure- ...

It looks like GlassFish logging configuration is an issue of its own. Can anybody help?

The solution seems to be the first SO posting here: Install log formater in glassfish

I've hacked together a simple log formatter (adjust at will):

import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.LogRecord;
import java.util.logging.SimpleFormatter;

public class JBossAS7LikeFormatter extends SimpleFormatter
{
    private final String nl = System.getProperty("line.separator");
    private final DateFormat df = new SimpleDateFormat("HH:mm:ss,SSS");

    @Override
    public synchronized String format(LogRecord lr)
    {
        StringBuffer sb = new StringBuffer();

        // time only
        Date dt = new Date();
        dt.setTime(lr.getMillis());

        sb.append(df.format(dt));
        sb.append(" ");

        // level (longest is "WARNING" = 7 chars, space fill for level output)
        String level = lr.getLevel().getName();

        int numSpaces = 7 - level.length();

        sb.append(level);

        for ( int i = 0 ; i < numSpaces + 1 ; i++ )
        {
            sb.append(" ");
        }

        // package
        sb.append("[");
        sb.append(lr.getSourceClassName());
        sb.append("] ");

        // thread (name?)
        sb.append("(");
        sb.append(lr.getThreadID());
        sb.append(") ");

        // message
        sb.append(formatMessage(lr));
        sb.append(nl);

        // optional stack trace
        if ( lr.getThrown() != null )
        {
            try
            {
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                lr.getThrown().printStackTrace(pw);
                pw.close();
                sb.append(sw.toString());
            }
            catch ( Exception e )
            {
            }
        }

        return sb.toString();
    }

}

It even fixes the double newline problem on Windows machines.


I got this to work by putting the JAR into domain/lib/ext at first , but for newer tries, whatever the reason is, I only keep getting a ClassNotFoundException now:

Mrz 08, 2012 9:39:14 AM com.sun.enterprise.admin.launcher.GFLauncherLogger info
Information: Successfully launched in 5 msec.
Launching GlassFish on Felix platform
Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.sun.enterprise.glassfish.bootstrap.GlassFishMain.main(GlassFishMain.java:97)
    at com.sun.enterprise.glassfish.bootstrap.ASMain.main(ASMain.java:55)
Caused by: java.lang.NoClassDefFoundError: com/sun/enterprise/server/logging/UniformLogFormatter
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:410)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
    at java.util.logging.LogManager.getFormatterProperty(LogManager.java:1048)
    at java.util.logging.StreamHandler.configure(StreamHandler.java:76)
    at java.util.logging.StreamHandler.<init>(StreamHandler.java:94)
    at java.util.logging.ConsoleHandler.<init>(ConsoleHandler.java:88)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
    at java.lang.Class.newInstance0(Class.java:372)
    at java.lang.Class.newInstance(Class.java:325)
    at java.util.logging.LogManager$3.run(LogManager.java:419)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.util.logging.LogManager.loadLoggerHandlers(LogManager.java:405)
    at java.util.logging.LogManager.initializeGlobalHandlers(LogManager.java:1076)
    at java.util.logging.LogManager.access$1100(LogManager.java:148)
    at java.util.logging.LogManager$RootLogger.getHandlers(LogManager.java:1157)
    at java.util.logging.Logger.log(Logger.java:521)
    at com.sun.logging.LogDomains$1.log(LogDomains.java:372)
    at java.util.logging.Logger.doLog(Logger.java:543)
    at java.util.logging.Logger.log(Logger.java:587)
    at com.sun.enterprise.server.logging.LogManagerService.postConstruct(LogManagerService.java:354)
    at com.sun.hk2.component.AbstractCreatorImpl.inject(AbstractCreatorImpl.java:131)
    at com.sun.hk2.component.ConstructorCreator.initialize(ConstructorCreator.java:91)
    at com.sun.hk2.component.AbstractCreatorImpl.get(AbstractCreatorImpl.java:82)
    at com.sun.hk2.component.SingletonInhabitant.get(SingletonInhabitant.java:67)
    at com.sun.hk2.component.EventPublishingInhabitant.get(EventPublishingInhabitant.java:139)
    at com.sun.hk2.component.AbstractInhabitantImpl.get(AbstractInhabitantImpl.java:78)
    at com.sun.enterprise.v3.server.AppServerStartup.run(AppServerStartup.java:229)
    at com.sun.enterprise.v3.server.AppServerStartup.doStart(AppServerStartup.java:145)
    at com.sun.enterprise.v3.server.AppServerStartup.start(AppServerStartup.java:136)
    at com.sun.enterprise.glassfish.bootstrap.GlassFishImpl.start(GlassFishImpl.java:79)
    at com.sun.enterprise.glassfish.bootstrap.GlassFishDecorator.start(GlassFishDecorator.java:63)
    at com.sun.enterprise.glassfish.bootstrap.osgi.OSGiGlassFishImpl.start(OSGiGlassFishImpl.java:69)
    at com.sun.enterprise.glassfish.bootstrap.GlassFishMain$Launcher.launch(GlassFishMain.java:117)
    ... 6 more
Caused by: java.lang.ClassNotFoundException: com.sun.enterprise.server.logging.UniformLogFormatter
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
    ... 53 more
Completed shutdown of GlassFish runtime
Command start-domain failed.
The DAS was stopped.

I saw the new format for a few tries, but the it stopped to work - strange.

I've attached the JAR as is in my original GlassFish forum post. I've basically just used my ZIP tool and renamed it to JAR, but this shouldn't be a problem (?). If anybody gets it to work (again) please let me know.

Note: I'm using the GlassFish plugin to start/stop the server, don't know if this could be an issue.

Please continue any discussions in the GlassFish forum here: http://www.java.net/forum/topic/glassfish/glassfish/configuring-glassfish-logging-format

PS: sorry I needed to post the stack trace here as the GF forum is somewhat broken.

UPDATE :

Extending java.util.logging.SimpleFormatter did the trick. GlassFish now produces log entries like:

12:13:02,400 INFO    [com.sun.enterprise.web.WebContainer] (1) WEB0172: Virtual server [server] loaded default web module []
12:13:07,700 INFO    [org.hibernate.validator.util.Version] (1) Hibernate Validator 4.2.0.Final
12:13:08,919 WARNING [null] (1) Multiple [2] JMX MBeanServer instances exist, we will use the server at index [0] : [com.sun.enterprise.v3.admin.DynamicInterceptor@1a53cab6].
12:13:08,920 WARNING [null] (1) JMX MBeanServer in use: [com.sun.enterprise.v3.admin.DynamicInterceptor@1a53cab6] from index [0] 
12:13:08,920 WARNING [null] (1) JMX MBeanServer in use: [com.sun.jmx.mbeanserver.JmxMBeanServer@2f740f7e] from index [1] 

Again, on Windows: no double newlines.

The default logging format can be changed as per the post above. The NoClassDefFoundError reported above can be avoided by extending java.util.logging.Formatter rather than the com.sun.enterprise.server.logging.UniformLogFormatter.

To summarize:

  1. Implement a custom formatter which extends java.util.logging.Formatter
  2. Copy the jar containing custom formatter to domain/lib/ext
  3. Specify the log formatter in logging.properties , eg.

     com.sun.enterprise.server.logging.GFFileHandler.formatter=com.myformatter.CustomFormatter 

Following all the guides and failing, what finally got this to work for me in GF 3.1.2.2 was to update the correct property in logging.properties as explained above:

com.sun.enterprise.server.logging.GFFileHandler.formatter=com.myformatter.CustomFormatter

All guides I've seen have talked about updating the "handlers" property, but this was not neccessary. The property above is the only property I've changed.

Oh; and my custom formatter extends SimpleFormatter.

You need to supply your own logging implementation since there doesn't seem to be a way to change glassfish's. SLF4J is just a facade and doesn't actually do any logging, it forwards it to the logger that is present on your classpath.

What I've done in my app is replace the entire glassfish logging with logback following this post. http://hwellmann.blogspot.com/2010/12/glassfish-logging-with-slf4j-part-2.html

Since GlassFish 7.0.0-M8 you can switch the formatter as you wish for any handler used. In a simplest case you can use SimpleFormatter and set some custom format for it. Also the GlassFish documentation improved.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM