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:
- Implement a custom formatter which extends
java.util.logging.Formatter
- Copy the jar containing custom formatter to
domain/lib/ext
Specify the log formatter in logging.properties
, eg.
com.sun.enterprise.server.logging.GFFileHandler.formatter=com.myformatter.CustomFormatter
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
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.