Has anyone got SLF4J / logback to work with JBoss 7?
Previously, I was able to get my app to work in JBoss 5.1 by putting my "logback.groovy" in [server]/conf, and the logback core, classic (0.9.28), and Groovy (1.8.0) JARs in [server]/lib.
For JBoss 7.0.1, I've got the Groovy and logback modules set up OK (the .index files have been created), my EAR's MANIFEST.MF declares dependencies on both modules, and my "logback.groovy" is deployed in my WAR module's WEB-INF/classes, within my EAR. The EAR definitely deploys OK - lights are green...
Despite this, the only logging rules that actually get applied are the standard console/server.log ones set up in "standalone.xml". Yes, I can see my log statements (so SLF4J is working), but my logback rules, appenders, etc. are being ignored. There are no references to either logback or Groovy in any of that logging, so I'm assuming that I've not done enough to trigger logback's loading and finding my script.
There are other things I could try, but it would be good to know if other people have tried this. If they haven't, perhaps that's a sign that I should just throw in my lot with JBoss Logging?
Are you sure logback is active? If logback cannot find a configuration file, i.e. logback.groovy or logback.xml, it will print a warning message on the console. The output should be similar to:
12:49:22,078 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
12:49:22,093 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.xml]
12:49:22,093 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Setting up default configuration.
Do you see any such output on the console? If not, assuming that Jboss 7 is bundled with an slf4j-binding, you are probably already using Jboss logging. (Your calls to the slf4j api are being sent to jboss logging instead of logback.)
The Jboss folks should be contacted about using a logging backend other than jboss-logging.
Digging a little further, I noticed that JAS7 ships with a file called slf4j-jboss-logmanager-1.0.0.GA.jar located under the ./modules/org/slf4j/impl/main/ folder. The contents of this file show that it is definitely an slf4j binding. I do not know how Jboss "modules" work but removing/disabling slf4j-jboss-logmanager is the way to go if you wish logback-classic to be picked up by slf4j.
JBoss AS7 uses the jboss-logmanager. I assume that logback appenders would require a log manger that can handle them. I'm not really sure what would happen if you switched out the log manager.
There is support for custom java.util.logging.Handler's so you could write a wrapper for an appender in a handler. I know it's probably not ideal, but it should work.
I would encourage anyone to use JBoss Logging and not just because I work on it :-) It really does have some nice features, like var-arg log methods which is what drew me to it in the first place. There is also support for i18n logging and messages through interfaces.
Also JBoss Logging is more than just an API. It's a full logging framework. In the next release of JBoss Logging we will offer a way to specify which log manager you would like to use. That might make something like this a bit easier, but I must admit I have not tested in in AS7. If I get the time I will though.
Related
I read a lot but I couldn't figure out how I could specify for example the log level for specific classes.
Only way I could figure out was in the standalone.xml but why should I configure some application specific setting very general in the server? This complicates the deployment process unnecessary.
Isn't it somehow possible to define the specific log level and the output files somewhere inside the war without touching the server?
Btw. it doesn't matter if log4j or commons-logging or slf4j or whatever is used.
Using a logging.properties file or a log4j configuration file in your deployment will work in JBoss EAP 6.x and WildFly (formerly JBoss AS). Note though that a log4j configuration would only work if you use log4j for your logging facade.
That said I agree with Marko that this should probably be done in the server configuration. I would also encourage you to use the CLI or web interface rather than editing the raw XML as well. You can get some more information on the documentation.
I am sorry for not providing a direct answer, but consider this: the application being in charge of logging levels is a bad idea most of the time as this is something an AS admin should be able to change at any time. For example, the point of the DEBUG or TRACE log levels is to be able to place a lot of such statements in the code without hurting the production server's performance. However, once a bug is detected, you want to be able to lower the logging level without rebuilding the application. This should be a purely administrative task.
On the other hand, I do recognize the need to at least have a decent starting point for the logging configuration and I don't know of any architecture which would allow the application to provide defaults which are overridable by the server configuration.
We have a j2ee web environment. The server is configured to share session and possibly classloaders across multiple webapps. Basically, one classloader could server multiple web apps.
This seems to cause issues with log4j. Different webapps could have different log4j configurations but the logging will move to the same file.
Reading online, it looks like log4j uses singletons a lot, in terms of the appenders and other functionality.
Is there a way to completely separate the log4j configurations from one webapp from the other.
Server: websphere6+
Log4j: 1.4.2
Java: 1.5
Example log4j.properties (webapp1):
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=/usr/local/file1.log
log4j.additivity.com.app=false
Example log4j.properties (webapp2):
log4j.appender.Z=org.apache.log4j.RollingFileAppender
log4j.appender.Z.File=/usr/local/file2.log
log4j.additivity.com.app=false
Right now, logging from webapp2 may appear in the webapp1 logs and vice verse. We don't want that.
Possible Solution:
It might be possible to add a custom file appender? Would that fix the issue and what code would I add to the custom appender?
Is it possible to change the log4j initialization. E.g., could I use some startup servlet to load logj4 for each webapp.
You have two ways to solve your problem:
Configure your app. server so it doesn't share classloaders across multiple webapps. When it does do that, because of log4j's nature, only one log4j.properties file will be loaded.
If you leave the app. server so it shares classloaders, then use one "master" log4j.properties file. In it, define appenders for root of every one of your applications (example com.mycompany.webapp1, com.mycompany.webapp2)
No solution is perfect. Particularly, the second one will be problematic if your web apps share some classes that use log4j. In that case, logs from both apps will end up in the same file.
Your problem is a common one. To understand more about this topic, google for "log4j and j2ee".
Edit: since solutions 1 and 2 aren't feasible, you could try something else:
Use log4j.properties file per application. In every one of them, define an appender for their root (as explained in solution 2), and set additivity to false. This also won't be perfect if there is any class sharing between them.
Configure log4j programatically for every application. Since they're legacy applications, this could be tough. One way to do it is to use ServletContextListener for every application and configure log4j on application startup. I haven't personally tried this, so I'm not 100% sure if there will be clashes due to shared classloaders.
Log4j won't be really updated anymore. Ceki Gülcü, who created log4j, stated that he will focus his efforts on slf4j and logback, to correct some mistakes he did during development of log4j.
It seems a Log4j rolling appender stopped logging because it hit the MaxBackupIndex limit. I've moved the old log files out of the way but Log4j doesn't seem to start logging again.
Is there a way to restart Log4J logging via JMX?
I'd like to leverage this insteaed of restarting a Tomcat instance.
Thanks.
Logback, log4j's successor can be reloaded via JMX. It also supports (in thread) automatic reloading of the configuration file if it is modified.
I don't think that's what log4j does. The MaxBackupIndex parameter tlle it how many old files to keep around before it starts deleting them, it has no effect on the logging itself. I suspect your problem lies elsewhere.
I have some jar files that will be distributed to clients that are using log4j for logging. My question is should I include a log4j.xml configuration in the jar file or have the client provide one if they want logging?
My feeling is to leave the log4j.xml configuration file out of the client jars, since the apache jar files all come with log4j logging, but sans log4j.xml.
Yes, leave it out. It's an utter nuisance when your log4j configuration file is ignored because one of the 60 third-party libraries of your app contains its own.
The good thing about log4j in your case is that your jar really shouldn't have to worry about it. The basic use case of log4j is:
Obtain a logger object for the current class
Call one of the methods on that logger, such as debug("some message");
If the jars you are shipping are to be used by a larger application, then ideally your code will only do the two steps listed above. In this way, your code will simply obtain logger objects from the already-configured log4j instance in the client's application. Your production code is then decoupled from having to know how to configure log4j.
Any logging you need to see for your development of the jars can be accomplished by configuring a log4j instance in unit test setUp() methods or something similar that won't get bundled with the production code going to the client.
I would put a default log4j configuration that you expect will be useful to your clients in the documentation. This way interested people can see what logging options you have (usually certain classes have more interesting log messages, from the user's perspective). I find it annoying when I have a third-party lib using log4j and it has no documentation, and there are log messages filling my screen and I have to try to figure out how to enable or suppress certain log messages.
If you are using log4j in your application then you include it in your project. If you are not, then why would you put it in there? What if client A wants log4j version 1.2 and client B wants log4j version 1.3.
Let them decide what they need for their projects and worry about what you need for yours.
I would add the configuration xml and load it up with instruction for the user showing different configuration and options. This will make it easier for either them or support to enable addition logging.
Using a Jetty web server, started from maven, which includes iBatis, Spring, Jersey, a little of this and a little of that, I get logging output with a host of formats.
Some are from maven:
[INFO] [war:war]
[INFO] Exploding webapp...
Some are from Jetty:
2009-03-25 21:01:27.781::INFO: jetty-6.1.15
2009-03-25 21:01:28.218:/example:INFO: Initializing Spring root WebApplicationContext
Some are from Spring:
INFO ContextLoader - Root WebApplicationContext: initialization started (189)
INFO XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/applicationContext.xml] (323)
Some are from Jersey:
Mar 25, 2009 9:01:29 PM com.sun.jersey.spi.spring.container.SpringComponentProviderFactory register
still others are from my code:
INFO ExampleApp - [User#14ef239 ...stuff] (69)
I expect they're all using standard logging packages (log4j, commons-logging, java-logging...)
Is it possible, and what is the easiest way to configure all of them to use the same format?
Is there any benefit to leaving them in varying formats?
This is possible using the logback library and its bridges. It basically consists to remove any log4j commons or alike jars from the classpath, stick logback jar file and bridges jars for log4j and alike. Spring, jersey and maven will use the bridge factories to instantiate loggers which in turn will use logbak producing unified logging.
Check http://logback.qos.ch/ and http://www.slf4j.org/legacy.html
The key are the bridges which link other log utilities with a single global logger.
The issue you have is that the applications are using different logging libraries. Jersey will use JUL, Spring will use commons-logging (which will in turn pick log4j if that's in your classpath), and Jetty uses its own logger. You can fix this by getting all your components to log through JUL.
First you need to get log4j off your classpath. Use exclusions or other mechanisms to ensure that log4j is not included. This will prevent commons-logging from picking log4j over JUL and get Spring to log in the same format as Jersey.
Next you'll need to configure Jetty to use commons-logging. You can find information about that on the Maven Jetty Plugin documentation page.
If your application code is using log4j directly, you'll need to switch to either commons-logging or JUL.
Maven I'm not so sure about, but it probably has a similar solution.
I don't know of any way to manage what you're describing in a useful manner. If you're desperate, the best suggestion I can make is to write something to unify the disparate formats under one umbrella and manage it there using your preferred logging format.
I don't think you can unify all of these easily, because you don't know what is being used by each framework.
If you identify which ones you are interested in then you can get each to output to log files in a central location /var/log/app (under linux for example). From here you could write a simple utility that parses each log file and massages the data into a single log file in the format that you want. The Awk utility is very good at doing this sort of thing.
Alternatively, you could leave them as they are - and use something like Splunk to index the files for future searching and analysis. It really depends on what you require from the log files at a later date. Hope that helps.
If and when they are using standard logging package, of course you can unify common parts ("INFO" prefix, timestamp, category name (usually class/package)). Just configure log4j / J.U.L / logback to your liking.
I don't know why you would get different formats -- log formats are NOT configured by frameworks, but apps -- so maybe they are using different frameworks. But that may be accidental.
As to whether it matters; well, only if you process it automatically (trigger regex-based alarms).
SLF4J allows you to consolidate logging by routing it into a single logging framework. You can redirect legacy logging calls made with commons-logging, java.util.logging and log4j as if they were made to SLF4J. See www.slf4j.org/legacy.html for details.
All logging will then be delegated to an underlying framework of your choice, for example logback, log4j, java.util.logging among others. If you run into trouble do contact the slf4j-user mailing list.
I think we will eventually need a "logging api" logging api that ties together all unified logging apis such as slf4j and whatever other ones they are. Who knows, you might need to change your logging framework that handles all types of logging one day...
Simply use http://logback.qos.ch/translator/ to convert the log4j.properties into xml format and paste that in logback.xml. This works as charm directing your log to appender configured.