| Title: Logging |
| <a name="Logging-LoggingforUsers"></a> |
| ## Logging for Users |
| All logging in OpenEJB is done using the |
| openejb.base/conf/logging.properties file. When you download and extract |
| OpenEJB, you will not find this file under the openejb.base/conf directory. |
| However, when you start the server, this file magically appears. So what |
| does this give you as a user of OpenEJB? Here are some of the benefits: |
| 1. You do not have to author a logging.properties from scratch. You get one |
| with sensible defaults. |
| 1. If you did modify the default file, and you wanted to revert back to the |
| default file generated by OpenEJB, all you have to do is |
| 1. # Delete or rename the file e.g. rename it to logging.properties.BAK . |
| 1. # Restart the server |
| |
| |
| OpenEJB will find that the logging.properties file is missing from the |
| openejb.base/conf directory and it will automatically create a new one with |
| the default configuration. The good thing is that if you modify the |
| logging.properties file, OpenEJB will \*NOT\* over-write it. |
| |
| The default logging configuration created by OpenEJB uses |
| RollingFileAppender's. The log files are located under the |
| openejb.base/logs directory. By default it writes to just two files , |
| openejb.log and transaction.log |
| {info:title=Embedded Testing} |
| When running tests using embedded OpenEJB, the logging.properties will be |
| ignored. You need to use a file named embedded.logging.properties instead. |
| Place this file under src/test/resources |
| {info} |
| <a name="Logging-Loggingforcontributors/committers"></a> |
| ## Logging for contributors/committers |
| |
| The org.apache.openejb.util.Logger class is the one which is used for |
| logging. This class is a wrapper around log4. |
| |
| <a name="Logging-LogCategory"></a> |
| ### LogCategory |
| |
| Each Logger instance belongs to a category represented by a |
| org.apache.openejb.util.LogCategory instance. Here is what the LogCategory |
| class looks like |
| |
| public final class LogCategory { |
| private final String name; |
| public static final LogCategory OPENEJB = new LogCategory( "OpenEJB"); |
| public static final LogCategory OPENEJB_ADMIN = OPENEJB.createChild("admin"); |
| public static final LogCategory OPENEJB_STARTUP = OPENEJB.createChild("startup"); |
| public static final LogCategory OPENEJB_STARTUP_CONFIG = OPENEJB_STARTUP.createChild("config"); |
| public static final LogCategory OPENEJB_STARTUP_VALIDATION = OPENEJB_STARTUP.createChild("validation"); |
| // other categories removed for code brevity |
| private LogCategory(String name){ |
| this.name = name; |
| } |
| public String getName() { |
| return name; |
| } |
| /** |
| * Creates a child category of this category. <B>Use this method sparingly</B>. This method is to be used in only those circumstances where the name of the |
| * category is not known upfront and is a derived name. If you know the name of the category, it is highly recommended to add a static final field |
| * of type LogCategory in this class |
| * @param child |
| * @return - LogCategory |
| */ |
| public LogCategory createChild(String child){ |
| return new LogCategory(this.name+"."+child); |
| } |
| |
| } |
| |
| Notice carefully how each LogCategory instance is created. The |
| objective here is that each LogCategory should be a child of the OPENEJB |
| category. If you need to add a new category and you know the name of the |
| category upfront, simply open the LogCategory class and add another |
| category. For example, if you needed to add a category named SHUTDOWN, here |
| is the recommended way to add it |
| |
| public static final LogCategory OPENEJB_SHUTDOWN = LogCategory.OPENEJB.createChild("shutdown"); |
| |
| Sometimes you may want to create a category whose name is "generated" at |
| runtime. In that case you can use the "createChild" method of the |
| LogCategory class to create this new category. For example, if you |
| wanted to create a category of Logger for every deployed module, then |
| assuming you have the moduleId information you could do something as |
| follows to create a category: |
| |
| String moduleId = "mymodule"; |
| LogCategory generatedCategory = LogCategory.OPENEJB.createChild(moduleId); |
| |
| |
| <a name="Logging- Logger"></a> |
| ### Logger |
| |
| The preference is to externalize all logging messages in properties file. |
| Typically each package should have a file called Messages.properties. |
| This file should have all the keys and the corresponding messages. |
| Here are the steps you would follow to log a message: |
| * For each message you need to log, you would open the Messages.properties |
| file in the corresponding package and add a key-value pair for the |
| message. For example, if you were authoring a class called |
| org.apache.openejb.util.Connect, then you would add a key-value pair to the |
| Messages.properties file located in the org.apache.openejb.util package. |
| |
| * Obtain a Logger instance in one of the following ways: |
| |
| |
| *Using the package name* |
| |
| Logger logger = Logger.getInstance (LogCategory.OPENEJB, |
| "org.apache.openejb.util"); |
| |
| * |
| Using the Class* |
| |
| Logger logger = Logger.getInsance(LogCategory.OPENEJB, Connect.class); |
| |
| |
| *Get a child Logger for an existing Logger instance* |
| |
| Logger logger = Logger.getInsance(LogCategory.OPENEJB, Connect.class); |
| Logger child = logger.getChildLogger("shutdown"); |
| |
| |
| *Get a child Logger of an existing Logger using a LogCategory* |
| |
| LogCategory childCategory = LogCategory.OPENEJB.createChild("shutdown"); |
| Logger logger = Logger.getInstance(childCategory,Connect.class); |
| |
| * Call one of the following methods passing in the key as an argument |
| ** debug |
| ** error |
| ** fatal |
| ** info |
| ** warning |
| |
| |
| Logger logger = Logger.getInstance(LogCategory.OPENEJB,Connect.class); |
| logger.info("error.file"); |
| |
| The |
| Messages.properties file under org.apache.openejb.util must have the |
| "error.file" key in it with the corresponding message. |
| |
| <a name="Logging-LoggerInheritance "></a> |
| ### Logger Inheritance |
| |
| Another interesting feature of the Logging framework is inheritance. |
| Here is how it works: |
| |
| Say you have the following Messages.properties files in the classpath. |
| 1. org/apache/openejb/Messages.properties |
| 1. org/apache/openejb/core/Messages.properties |
| 1. org/apache/openejb/core/stateless/Messages.properties |
| |
| |
| |
| Then you have a class such as |
| org.apache.openejb.core.stateless.StatelessContainer (+note the package+) |
| If that class referenced a message key "classNotFound" for example, the |
| Logger would look for the message first in Messages.properties 3, then 2, |
| then 1 and so on until it found the required message. |
| This would allow better reuse of messages, more flexibility in where we put |
| the Message.properties files, as well as the added bonus in that we |
| no longer need to pass in the location of where our |
| Message.properties file is |
| |
| <a name="Logging-Loggingforintegrators"></a> |
| ### Logging for integrators |
| |
| If you want to embed OpenEJB in your application and need to control the |
| logging configuration of OpenEJB, simple set the openejb.logger.external |
| system property to true. Now, its your applications' responsibility to |
| configure logging, OpenEJB will simply use your configuration. |
| |
| <a name="Logging- OriginationoftheLoggingIdea"></a> |
| ### Origination of the Logging Idea |
| |
| There has been a long discussion for this logging idea. Its going to be |
| worth it to read the discussion at [i18n and logging](http://www.nabble.com/i18n-and-logging-tf3962134s2756.html) |
| |
| +Here is a extract from an email from David Blevins which talks about the |
| existing logging framework. The current framework is more or less the same |
| as this one, just some added features and a rewrite of the API+ |
| |
| Each module has a file called default.logging.conf. This file contains the |
| definition of all Loggers, their appenders and warning levels. However, we |
| do not use default.logging.conf first. The basic idea is that first we look |
| for say conf/logging.conf in the openejb.base directory. If we don't |
| find it there, we look for default.logging.conf in the classpath. If |
| we did find default.logging.conf (which we should) and there is an |
| openejb.base/conf/ directory then expand the default.logging.conf to |
| openejb.base/conf/logging.conf where we expected to find the file in the |
| first place. If there was no openejb.base/conf/ directory, then it's |
| safe to assume we're running embedded (in a test case perhaps) and just use |
| the default.logging.conf and do no extra work. |
| |
| We have default.logging.conf which we use this way as well as |
| default.openejb.conf and now more recently users.properties and |
| groups.properties. We search on disk for the resource in |
| openejb.base/conf/ if we don't find them we unpack the default one we |
| stuffed in openejb-core jar and extract it to disk in the openejb.base/conf |
| directory if there is one \-\- if there isn't one we just use the default |
| file. |
| |
| The basic ideas behind the pattern are that: |
| 1. If you've messed up your configuration, just delete or rename the |
| respective files in your conf/ directory and new (working) ones will |
| magically appear. |
| 2. When upgrading its nice that our zip file won't overwrite any |
| existing files in conf/ |
| 3. If you're running embedded you don't have to setup any |
| directories or have any config files, we can run on defaults. |
| |
| The *ConfUtils.getConfResource* utility to do that pattern generically , |
| but so far we're only using it for the users.properties and |
| groups.properties files. We should be using it everywhere. |
| Having the code in multiple places has lead to some inconsistencies |
| such as we expand the default.openejb.conf file to conf/openejb.xml (not |
| even the same file extension). We really don't need the "default" |
| part in our file names and the lingering usage of the "conf" file extension |
| is something that needs to go bye-bye \-\- we should use properties for |
| properties files and xml for xml files, etc. |