Sorry, yet another long post.
I'll explain the proposed logging implementation.
There are four main classes.
This looks like the Logger in JBoss except instead of delegating
to org.apache.log4j.Category it has a "hot-swap" delegate.
This is responsible for doing the logging.
It can perform the logging (like the Simple or the Null Logger)
or it can delegate to a "real" logger (like Log4j or java.util.Logging)
Perhaps a better name for this class is LoggerAdapter?
This is responsible for creating LoggerDelegate instances.
This controls which Delegate is used by the Loggers.
The user can register a DelegateFactory to select the Logger they
require, any existing Loggers are automatically updated to the
This class is used to create new Loggers with the correct Delegate.
Currently the whole thing; the framework, simple logger, null logger
and log4j adapter is 26k unpacked (11k packed) although
feature set is incomplete (e.g. changing the logging level for a Logger)
These are the design principles:
1) JBossMX needs a logger, it should be able to report errors/warnings
etc without any configuration. It should also be possible to turn
on a debugging mode.
2) The logging should provide methods similar to existing loggers (e.g. log4j, JLog, java.util.logging).
I chose org.jboss.logging from the server module as a basis. The fact that it automatically configures the
simple logger means the bootstrap logger is redundant.
3) JBossMX is a library, the logging needs to adapt to the application
or user preferences.
I anticipate there will be something similar to Log4jService in JBoss
and similar configuration services for other loggers.
These configuration services would have the option to specify that
this is the type of logging required for JBossMX internal logging.
This is a tricky one. Log4j 1.2 allows multiple repositories to exist
so different applications can configure there own logging in the same
VM. But something has to select the relevant repository based on
the context. e.g. In JBoss the repository could be configured at
deployment time using the classloader as the context.
I'm not aware of other loggers with this technology.
We could provide something similar within our logging, but then it
ceases to be a light framework. We would probably have to go beyond
selecting the correct log4j hierarchy and actually switch the whole
logging framework (e.g. log4j -> java.util.logging)
This can be done providing there is a way for LoggerControl to
know what the Context is when asked for a Logger.
Something has to associate Contexts with logging frameworks/repositories.
The extra level of indirection is
I haven't done any real measurements on this.
The only measurement I've done so far is comparing the Simple Logger
and the log4j delegate when logging is not done (100,000 attempts)
When I profiled it, the JIT seems to think my framework isn't a
hotspot so mostly it leaves it interrupted and just compiles the
Simple Logger :-)
Should the logger be org.jboss.mx.logging or org.jboss.logging,
it isn't really a management thing unless we are going
to get into context switches of logging.
Also, the log4j and other delegates could be packaged in different
jars for when size matters.
I haven't spent enough time thinking about logging to justify a comment on your code or architecture.
However, you mention about being able to turn on debugging JBossMX. IMHO we should have *no* debugging messages or "diagnostic mode" behaviour in JBossMX whatsoever.
1. IMHO verbose or debug mode adds nothing over a stack trace when trying to diagnose a problem.
2. too often I've seen debug code that introduces bug opportunities (using ref.getName() in the message when it was the nullness of ref that triggered the debug code).
3. JMX is just a big hashtable of objects that dispatch method calls. It'd be like putting debugging messages into the reflection api - no thanks, that's slow enough as it is.
The only place where I believe we need logging is when we're repackaging pathological exceptions and errors in the core as RuntimeOperationsException or RuntimeErrorException.
I guess having an option to make the MBeanServerImpl catch, log and rethrow exceptions might have some utility as well.
Well that's my 2pence.
If you want logging during invoke(), get/setAttribute()
just add a LogInterceptor.
But, I can see a use other areas to dump to debug what
is happening. e.g. Dumping the derived Management
interface for a Standard MBean at registration,
logging that a relation has been removed because it
no longer matches its roleinfo and of course during
This is useful for tracking problems, especially to a
okay I see you've got a valid point. I've been burned in the past by spec requirements for pervasive "verbose diagnostic messages". As in a message for nearly each LOC. The pain has left me a little sensitised.
I can see the climbdown from my high horse now... "There is only ONE rule - no verbose debugging! ... except of unexpected exceptions. Damn. There are only TWO rules - no verbose debugging except of unexpected exceptions! ... and in certain parts of the relation service. Damn. There are only THREE rules - ..." :D
No one expects an unexpected exception,
I'll start again :-)
I've refactored the logging implementation.
It is less of a prototype now :-)
I'll just list the what it does.
1) Hot-swappable logging implementation
2) Context sensitive logging implementation
3) System.err, File, Null and Log4j logging
4) Unified logging interface org.jboss.mx.logging.Logger
A "quick" explanation about contexts.
This allows different parts of the system to use
different logging implementations.
e.g. JBossMX internally can use the System.err logger,
ModelMBeans can create a context for using File
Loggers (as defined in the descriptor),
applications can use log4j,
applications downloaded from an MLet a different logger.
They all live happily together, and the logging
implementation can be swapped per context.
All the overhead for this is during the
Logger.getLogger(). Normal logging operations aren't affected.
Fix the File Logger to use a pool of FileOutputStreams
(this is for ModelMBeans sharing the same file, it should
reduce resources at a small performance cost)
Write some MBeans to create/configure contexts,
including the JBossMX internal context.
Get some performance measurements.
I'll commit it as it stands this weekend, I'm
writing the Relation Service testsuite at the moment,
already discovered a few problems ;-)
Trevor, MBeanCapability.of(Class) works great for