I am running some JUnit tests in Eclipse, and my code is generating an XML log file using the java logging APIs. (java.util.logging). Is there an easy way to view this XML log output in Eclipse, other than reading the raw XML? Specifically I want to be able to easily see what threads different log messages have come from.
I've been using the SLF4J logging API coupled with the Logback logging implementation. SLF4J can be configured to map log messages in the java.util.logging, log4j, jakarta commons logging, and SLF4j APIs into a common intermediate form. On the other side, the messages can be generated via java.util.logging, log4j, or Logback. It's a flexible approach that works well, especially when you have components that use different logging APIs.
One nice thing about Logback is that you can configure it to send a copy of the log messages to a an Eclipse plug-in. The plug-in and lets you view and filter the log file in a variety of ways. Messages contain the thread that generated them, so it sounds like something you should check out.
I think you were looking for the same thing I was looking for. I found UtilLogger4E, but I started my own project (EDevTools LogViewer), because it has some missing features and is not opensource.
It has the abilities to read Java Util Logging XML logs from a file or a configurable socket, display them colored by level in a table and it can show more than one log at a time (through multiple view instances).
Java Util Logging has a built-in feature to send logs to a socket (SocketHandler), it must only be set by the configuration file.
You can take a look at LogViewer at: http://sourceforge.net/projects/edevtools/
If you want to use log viewer which is not based on eclipse, I recommend you OtrosLogViewer. I can import java.util.logging XML format and SimpleFormat.
Disclaimer: I am the author of OtrosLogViewer
I was always hoping to find something like Apache Chainsaw for the java.util.logging/Eclipse combination, i.e. a log viewer in Eclipse that listens to a port and a java.util.logging.Handler implementation writing directly to that. But I haven't found such thing yet and didn't get around writing one either. So far I just use a suitable plain-text format to log to the console. Not elegant and no handy filtering options, but it does the job. Writing your own custom formatter is not hard at all.
There is some support for analyzing log files in Eclipse's Test and Performance Tools Platform Project (the name being even worse than the acronym). I never tried that, but it might be useful for you.
Just on the side, an excellent tool for viewing log files in real-time is baretail (essentially a tail -f on Windows), but can be set up to highlight certain patterns in colour which can really help. You can find a free version here.
Depending on exactly what you're trying to do you might just need a good logging setup for your logging sub sys?
A framework I've been using recently uses slf4j to log, by providing the following log4j config I get to see which threads output what:
log4j.rootLogger = trace, default
log4j.appender.default = org.apache.log4j.ConsoleAppender
log4j.appender.default.layout = org.apache.log4j.PatternLayout
log4j.appender.default.layout.ConversionPattern = %-4r [%t] %-5p %c %x - %m%n
In my case I get output similar to the following in the Console tab in eclipse when I run my junit tests.
0 [pool-1-thread-1] INFO com.example.BaseTest - Server listening on port 9090
35 [NioProcessor-6] INFO org.apache.mina.filter.logging.LoggingFilter - CREATED
35 [NioProcessor-1] INFO org.apache.mina.filter.logging.LoggingFilter - CREATED
I don't see how Eclipse can know about your threads. If it's XML, you need to write a parser that can find your thread messages using XPath and print them out. But that's up to you - Eclipse can't read your mind.
You'll have to find an XSL-T stylesheet that can take the XML stream produced by log4j and pull out the threads that you want.
Related
I have a 3rd-party developed big complex application full of java.util.logging.Logger#finer() calls.
Normally I use log4j and sl4j for logging, and I don't know very much of java.util.logging, even less about all the configuration details and possibilities.
Every single google about "java.util.logging" points to a full explanation about streams handlers, formatters, levels. Everyone assumes I really care about all this stuff (it is a reasonable assumption actually). But I couldn't care less.
I'm not really interested in separating logs per file, or file rotation, zipping, email, remote log etc. I'm also not concerned about log level and message formatting thrills.
All I want to do is to run this application with all available log messages spitting to stdout.
Is there an easy simple direct way to do this?
Something like jvmargs -Djava.util.logging.level=FINEST -Djava.util.logging.to=stdout.
Or maybe some simple file dropped into some location in the classpath?
All I want to do is to run this application with all available log messages spitting to stdout
Don't do this in production but it is the fast, easy, hacky way:
Edit the logging.properties file located in java/conf. E.G. /usr/lib/jvm/default-java/conf/logging.properties
That file is setup to attach a ConsoleHandler to the root logger which is what you want to do this. You just need to adjust the levels to see the output. This is a global change so be aware.
Edit that file and:
Change .level= INFO -> .level=ALL
Change java.util.logging.ConsoleHandler.level = INFO to java.util.logging.ConsoleHandler.level = ALL
Save the changes and restart your app.
The recommended way:
Most JVMs are not in your control (production/dev server) so you can instead copy that file to a location you own and use the java.util.logging.config.file system property.
E.G. -Djava.util.logging.config.file=/home/myuser/myapp/logging.properties
That way you are free to make changes that are local to your program and not global to the machine.
I have built a console program in Java that uses external jars. I would like to observe my own System.out.println logs in the console, but they are being for the most part overwhelmed by messages on the console generated by some Logger (from the package org.slf4j;) which outputs massive amounts of text.
My issue is I cannot change the code that uses the Logger, because it is wrapped up in a jar and do not have its source. Is there a way to only show MY System.out.println calls? Or to otherwise quiet the messaged produced by this code I don't have source for?
Thanks!
There are a couple of approaches.
Change the log level or location. Unless it is set programatically, there is a configuration file for the SLF4j system. Modify the level so it displays only warn or only error. Alternatively, change the logger so that it goes to a file instead of stdout.
If you on a *nix system, and depending upon how you invoke the program, it is possible to do something akin to java PROGRAM | grep -v "org.slf4j" (or whatever the package is). This approach will remove any lines that match from the display.
It sounds like you're using a library that uses SLF4J for its logging, which is a fairly standard library. As helpful as it can be that there are all those libraries out there that do useful things, one of the challenges of using them is that one needs to integrate their logging into the one used by your application. SLF4J provides a standard logging interface that many libraries use, and allows them to bind to a standard logging implementation like Logback or log4j.
I would expect that most SLF4J-using libraries would depend on the slf4j-api only, and not have a specific logging implementation binding in their dependencies. By default, SLF4J uses the "no-op" logger, meaning that no logging is output (other than an initial warning that that's what it's doing). You could add the slf4j-nop library if that's what you want for your testing, to remove all logging.
But since you're actually seeing output, it seems that the library you're using is also for some reason including a binding to an actual logging framework. At that point, your options are:
Figure out how that binding and actual logging framework is getting into your classpath and remove it. (If you're using Maven to manage your dependencies, for example, you might add an <exclude> element for them.), or
Figure out what logging framework is being used (If you're using Maven, I find the dependency:tree output useful), essentially adopt using it for your application as well, and configure it to log the way you want, hiding the messages that you find irrelevant.
If we had more details on how you were getting this library's dependencies in your application (I've given information for Maven as it's what I'm most familiar with and it's rather standard), or what logging framework you thereby unwittingly added to your application, somebody may be able to direct you further.
I have made a java application and wants to generate log files so whenever my client would encounter some problem, he can deliver me those log files so that I can correct my code accordingly.
Kindly provide me a small sample program that writes a statement to a log file. Kindly mention the .class files you are using with their full import statements.
The application is multi-threaded so Is it better to generate separate log files for each thread or not?
Is it better to clear all previous log files before starting the program?
macleojw is correct: You should try writing the code yourself.
Here is an overview of the Java logging framework that ships with the JDK. You may wish to check out Commons Logging and Log4J.
Regarding the second part of your question (which was editted out for some reason) I would recommend having all threads log to the same file but logging the thread name along with the log message allowing you to grep the file for a specific thread if required. Also, with most logging frameworks you can configure them to maintain a rolling window of the last N log files rather than explicitly deleting old files when an application starts.
Apache Log4j does everything you require. I hope that you can figure out how to use it on your own.
Take a look at Log4j, and specifically this set of step-by-step examples. It's pretty trivial.
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.