Adding logging to an RCP application has always been painful. Developers have struggled with the best way to incorporate Log4J and other logging APIs, and in particular with how to make configuration files accessible. Some have chosen to use buddy classloading, others have utilized fragments containing the config files.
Pax Logging to the rescue
I’m happy to say that RCP developers now have another choice - Pax Logging. There are a few great things about this library:
- Installation is easy. I’ll describe this in a bit.
- Configuration files can be placed in regular folders, either inside of an application bundle or anywhere on a users machine.
- Many logging APIs are supported, including Log4J, Commons Logging, JDK Logging, SLF4J and more. This means that legacy and third-party code can run as-is no matter what logging API they use.
Logging configuration with Pax ConfMan
Because Pax Logging requires the OSGi Configuration Admin service to work, your first step is to install this service in the form of Pax ConfMan. In my last blog post I provided detailed instructions on how to do this.
Adding configuration settings
The good news is that once you install Pax ConfMan, you’re almost done! Pax ConfMan requires the Pax Logging bundles in order to work, so we only have a few minor steps left.
The first is to add a logging configuration file. When using the OSGi Configuration Admin service, services are identified using a persistent identifier, or PID. Developers can choose the PIDs for their own services, and an implementation of the Config Admin uses these PIDs to inject properties into services.
Pax ConfMan does this by requiring that a properties file be named based on the PID of the service it is going to configure. For example, the Pax Logging PID is org.ops4j.pax.logging and so the properties file for this service will be called org.ops4j.pax.logging.properties.
If you created the folder structure suggested in the Pax ConfMan setup, simply create a file called org.ops4j.pax.logging.properties in the confadmin/services directory. You can now place whatever logging configuration you like into this file. For instance, here’s what I have for my simple test project:
log4j.rootLogger=DEBUG, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
log4j.logger.com.rcpquickstart.logtest=DEBUG
Forcing Pax Logging to start
Just as we did with Pax ConfMan, its necessary to force Pax Logging to start up when our application is launched. To do this, we simply need add the org.ops4j.pax.logging.pax-logging-service bundle to the Configuration page of the Product Configuration Editor and set it’s Auto-Start property to true. If you’ve followed the instructions for installing Pax ConfMan, your complete list should look like this:

Fire it up
That’s all there is to it. Start up your RCP application and you should see log messages appear in your console.

Happy logging!


Good to know someone appreciates that new Configuration page on the product definition editor ;)
I am using pax-logging since over a year now. Currently together with the fileinstall bundle that also feeds configurations to an CM available. It also has the benefit, that you can change the config during runtime and it will be updated.
I am just starting Pax-Logging at ST 1 to be sure to capture every logging message.
It would be nice if Eclipse would not write its own log file anymore. All the log informations should go to one log destination. Using the pax-logging service you can also attach to the eclipse logger and feed the Eclipse log entries to your logfile. Question is, how does one disable the creation of the Eclipse logfile?
I am trying to use pax logging in my osgi application.
Since this is my first osgi application i do have some problems.
I want to use apache felix with pax logging. I tried to start the pax-logging-service with felix, but it fails to start. So in general: Waht do i have to do? Include pax-logging-api in my bundles where i want to log and start pax-logging-service (can i build the service for felix? Should it start up without problems? Can i wrap the service jar for felix`?)
Can someone please help me?
Greetings,
Niko
Hi Niko,
Do you get an error message indicating why the logging bundle doesn’t start? I’m assuming you’ve installed Pax ConfMan as well.
BTW, if you’re targeting Felix you may just want to start with the Apache Karaf server. It’s basically Felix plus some standard services, including Pax Logging.
— Patrick
I wonder if it is possible to configure Pax-Logging via fragment bundle and feed it a default config file?
Hi Phil,
I haven’t looked into this myself, but it appears that Pax Logging provides a default log4j.properties file internally. This is mentioned in the following article:
http://wiki.ops4j.org/display/paxlogging/How+to+use+Pax+Logging
One option would be to simply open the bundle and modify the file by hand, but of course this would be a maintenance headache as new Pax Logging versions were released.
Placing the same file in a fragment would not work, as the bundle class path is searched before any fragment class paths.
Having said all this, there may be a way to do this that I’m not aware of. You may want to ask on the Pax mailing lists, and please do let me know if you find a good solution.
— Patrick
Based on these really excellent posts I am using PAX in an RCP app – so far, so good!
However, now I’ve been asked if it is possible to log to a file AND to a console – in the application. Furthermore, I’ve been asked if it were possible to have each editor have it’s own console.
Is that possible from a configuration or would I need to write something specifically to do this? Meaning would I need to provide a log4j appender that is capable of writing to the console? Or am I off in the weeds?
Thanks,
Jon
Hi Jon,
I’m glad the posts helped! You can definitely route the log to both a file and the console by creating the appropriate appenders. Of course, you’ll need to add the console view to your application if you want to view it outside the IDE.
I’m not sure how to route each editor’s log to it’s own console. It’s possible to create multiple consoles, but how to connect the appender to a specific console would be the issue. My guess is that you’d have to write custom code to manage this and I’m guessing it wouldn’t be easy. But if you get it working, let me know. It sounds like it could be useful.
Regards,
— Patrick
Thanks Patrick!
In my app I’ve added the ConsoleView to the view by adding into my perspective in plugins.xml. However, no window shows up. I am assuming that this because I have to do something to get that window to show, probably something like what is posted here:
http://wiki.eclipse.org/FAQ_How_do_I_write_to_the_console_from_a_plug-in_%3F
So, I am guessing that what you meant when you wrote “You can definitely route the log to both a file and the console by creating the appropriate appenders” is that if my log4j.properties is already specifying a console logger, it’s just a matter of grabbing the right IConsole instance and forcing it to appear. Is that right?
I am not going to worry about the per editor console just now, I think that is beyond my abilities today and really more of a nice to have.
Hi Jon,
Yes, you’re right that if the log4j.properties file is configured to log to the console then the log output should appear in the Console View.
As for why the Console View is not appearing, you don’t need to follow the steps in that FAQ. The FAQ only applies if you want to control the console programmatically.
Here are a few things to check:
* Have you added the org.eclipse.ui.console bundle to your target platform? This is not part of the standard RCP SDK. Of course if you’re using the entire Eclipse SDK as your target then the bundle will be there.
* If you’re adding the view with the perspectiveExtensions extension point, you’ll need to clear your workspace metadata to force the view to appear.
— Patrick
Thanks for the pointers!
I created a custom target based on the Eclipse platform and then I added another directory containing the bundles you posted about. In that target it says it loading 800 plugins. The view loads ok in my app (and I get no errors in the .log file), but no logging shows. I know I am getting logging via Pax because in the IDE’s console I see it.
I don’t know if this matters much but I am launching the app via a product config launch (rather than just launching the application).
In the launch config, I am already clearing the workspace (and I’ve also occassionally checked the box for clearing the config as well).
–Jon
Hi Jon,
Are you running the RCP application with the -consoleLog argument?
— Patrick
Hi Jon,
Just did some research, as I’ve never done what you’re trying to do. You need to execute the following code as your application starts up.
MessageConsole console = new MessageConsole(“System Output”, null);
ConsolePlugin.getDefault().getConsoleManager()
.addConsoles(new IConsole[] { console });
ConsolePlugin.getDefault().getConsoleManager().showConsoleView(console);
MessageConsoleStream stream = console.newMessageStream();
System.setOut(new PrintStream(stream));
System.setErr(new PrintStream(stream));
Hope this helps,
— Patrick