blob: 1b2fb4d4aeae839f5b195b0d82cb808c27d5de2f [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Logging</title>
<meta name="description" content="Apache TomEE">
<meta name="author" content="Apache TomEE">
<meta name="google-translate-customization" content="f36a520c08f4c9-0a04e86a9c075ce9-g265f3196f697cf8f-10">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate, max-age=0">
<!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<!-- Le styles -->
<link href="./../resources/css/bootstrap.css" rel="stylesheet">
<link href="./../resources/css/prettify.css" rel="stylesheet">
<!--link href="./../resources/css/bootstrap-mods.css" rel="stylesheet"-->
<link href="./../resources/css/main.css" rel="stylesheet">
<link href="./../resources/font-awesome-4.6.3/css/font-awesome.min.css" rel="stylesheet">
<script type="text/javascript">
var t = encodeURIComponent(document.title.replace(/^\s+|\s+$/g,""));
var u = encodeURIComponent(""+document.URL);
function fbshare () {
window.open(
"http://www.facebook.com/sharer/sharer.php?u="+u,
'Share on Facebook',
'width=640,height=426');
};
function gpshare () {
window.open(
"https://plus.google.com/share?url="+u,
'Share on Google+',
'width=584,height=385');
};
function twshare () {
window.open(
"https://twitter.com/intent/tweet?url="+u+"&text="+t,
'Share on Twitter',
'width=800,height=526');
};
function pinshare () {
window.open("//www.pinterest.com/pin/create/button/?url="+u+"&media=http%3A%2F%2Ftomee.apache.org%2Fresources%2Fimages%2Ffeather-logo.png&description="+t,
'Share on Pinterest',
'width=800,height=526');
};
</script>
<!-- Le fav and touch icons -->
<link rel="shortcut icon" href="./../favicon.ico">
<link rel="apple-touch-icon" href="./../resources/images/apple-touch-icon.png">
<link rel="apple-touch-icon" sizes="72x72" href="./../resources/images/apple-touch-icon-72x72.png">
<link rel="apple-touch-icon" sizes="114x114" href="./../resources/images/apple-touch-icon-114x114.png">
<script src="./../resources/js/prettify.js" type="text/javascript"></script>
<script src="./../resources/js/jquery-latest.js"></script>
<script src="http://platform.twitter.com/widgets.js" type="text/javascript"></script>
<script src="./../resources/js/common.js"></script>
<script src="./../resources/js/prettyprint.js"></script>
<!--script src="//assets.pinterest.com/js/pinit.js" type="text/javascript" async></script//-->
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-2717626-1']);
_gaq.push(['_setDomainName', 'apache.org']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body>
<div class="topbar" data-dropdown="dropdown">
<div class="fill">
<div class="container">
<a class="brand" href="./../index.html">Apache TomEE</a>
<ul class="nav">
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
Apache
<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<!-- <li><a href="./../misc/whoweare.html">Who we are?</a></li> -->
<!-- <li><a href="./../misc/heritage.html">Heritage</a></li> -->
<li><a href="http://www.apache.org">Apache Home</a></li>
<!-- <li><a href="./../misc/resources.html">Resources</a></li> -->
<li><a href="./../misc/contact.html">Contact</a></li>
<li><a href="./../misc/legal.html">Legal</a></li>
<li><a href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li>
<li><a href="http://www.apache.org/foundation/thanks.html">Thanks</a></li>
<li class="divider"/>
<li><a href="http://www.apache.org/security">Security</a></li>
</ul>
</li>
<li><a href="./../index.html">Home</a></li>
<li><a href="./../downloads.html">Downloads</a></li>
<li><a href="./../documentation.html">Documentation</a></li>
<li><a href="./../examples-trunk/index.html">Examples</a></li>
<li><a href="./../support.html">Support</a></li>
<li><a href="./../contribute.html">Contribute</a></li>
<li><a href="./../security/index.html">Security</a></li>
</ul>
<!-- Google CSE Search Box Begins -->
<FORM class="pull-right" id="searchbox_010475492895890475512:_t4iqjrgx90" action="http://www.google.com/cse">
<INPUT type="hidden" name="cx" value="010475492895890475512:_t4iqjrgx90">
<INPUT type="hidden" name="cof" value="FORID:0">
<INPUT size="18" width="130" style="width:130px" name="q" type="text" placeholder="Search">
</FORM>
<!--<SCRIPT type="text/javascript" src="http://www.google.com/coop/cse/brand?form=searchbox_010475492895890475512:_t4iqjrgx90"></SCRIPT>-->
<!-- Google CSE Search Box Ends -->
</div>
</div>
</div>
<div class="container">
<div class="page-header">
<small><a href="./../index.html">Home</a>&nbsp;&raquo&nbsp;<a href="./../dev/">Dev</a></small><br>
<h1>Logging
<div style="float: right; position: relative; bottom: -10px; ">
<a onclick="javascript:gpshare()" class="gp-share sprite" title="Share on Google+">share [gp]</a>
<a onclick="javascript:fbshare()" class="fb-share sprite" title="Share on Facebook">share [fb]</a>
<a onclick="javascript:twshare()" class="tw-share sprite" title="Share on Twitter">share [tw]</a>
<a onclick="javascript:pinshare()" class="pin-share sprite" title="Share on Pinterest">share [pin]</a>
<a data-toggle="modal" href="#edit" class="edit-page" title="Contribute to this Page">contribute</a>
</div>
</h1>
</div>
<p><a name="Logging-LoggingforUsers"></a></p>
<h2>Logging for Users</h2>
<p>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</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
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.</p>
<p>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&nbsp;<div class="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<div class="info">}
<a name="Logging-Loggingforcontributors/committers"></a></p>
<h2>Logging for contributors/committers</h2>
<p>The org.apache.openejb.util.Logger class is the one which is used for
logging. This class is a wrapper around log4.&nbsp;</p>
<p><a name="Logging-LogCategory"></a></p>
<h3>LogCategory</h3>
<p>Each Logger instance belongs to a category represented by a
org.apache.openejb.util.LogCategory instance. Here is what the LogCategory
class looks like</p>
<pre><code>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. &lt;B&gt;Use this method sparingly&lt;/B&gt;. 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);
}
}
</code></pre>
<p>Notice carefully how each LogCategory instance is created.&nbsp; 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</p>
<pre><code>public static final LogCategory OPENEJB_SHUTDOWN = LogCategory.OPENEJB.createChild("shutdown");
</code></pre>
<p>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.&nbsp; 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:</p>
<pre><code>String moduleId = "mymodule";
LogCategory generatedCategory = LogCategory.OPENEJB.createChild(moduleId);
</code></pre>
<p><a name="Logging-&nbsp;Logger"></a></p>
<h3>&nbsp;Logger</h3>
<p>The preference is to externalize all logging messages in properties file.
Typically each package should have a file called Messages.properties.&nbsp;
This file should have all the keys and the corresponding messages.&nbsp;
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.&nbsp; 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.</p>
<ul>
<li>Obtain a Logger instance in one of the following ways:</li>
</ul>
<p>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
<em>Using the package name</em></p>
<pre><code>Logger logger = Logger.getInstance (LogCategory.OPENEJB,
</code></pre>
<p>"org.apache.openejb.util");</p>
<p>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;<em>&nbsp;
Using the Class</em></p>
<pre><code>Logger logger = Logger.getInsance(LogCategory.OPENEJB, Connect.class);
</code></pre>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<em>Get a child Logger for an existing Logger instance</em></p>
<pre><code>Logger logger = Logger.getInsance(LogCategory.OPENEJB, Connect.class);
Logger child = logger.getChildLogger("shutdown");
</code></pre>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<em>Get a child Logger of an existing Logger using a LogCategory</em></p>
<pre><code>LogCategory childCategory = LogCategory.OPENEJB.createChild("shutdown");
Logger logger = Logger.getInstance(childCategory,Connect.class);
</code></pre>
<ul>
<li>&nbsp;Call one of the following methods passing in the key as an argument
<em>* debug
<em></em> error
<em></em> fatal
<em></em> info
*</em> warning</p>
<p>Logger logger = Logger.getInstance(LogCategory.OPENEJB,Connect.class);
logger.info("error.file");</li>
</ul>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The
Messages.properties file under org.apache.openejb.util must have the
"error.file" key in it with the corresponding message.</p>
<p><a name="Logging-LoggerInheritance&nbsp;"></a></p>
<h3>Logger Inheritance&nbsp;</h3>
<p>&nbsp;Another interesting feature of the Logging framework is inheritance.
Here is how it works:</p>
<p>Say you have the following Messages.properties files in the classpath.
1. &nbsp; org/apache/openejb/Messages.properties
1. &nbsp; org/apache/openejb/core/Messages.properties
1. &nbsp; org/apache/openejb/core/stateless/Messages.properties</p>
<p>&nbsp;
&nbsp;
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&nbsp; 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</p>
<p><a name="Logging-Loggingforintegrators"></a></p>
<h3>Logging for integrators</h3>
<p>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.</p>
<p><a name="Logging-&nbsp;OriginationoftheLoggingIdea"></a></p>
<h3>&nbsp;Origination of the Logging Idea</h3>
<p>There has been a long discussion for this logging idea. Its going to be
worth it to read the discussion at <a href="http://www.nabble.com/i18n-and-logging-tf3962134s2756.html">i18n and logging</a></p>
<p>+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+</p>
<p>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. &nbsp;If we don't
find it there, we look for default.logging.conf in the classpath. &nbsp;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. &nbsp;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.</p>
<p>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. &nbsp;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.</p>
<p>The basic ideas behind the pattern are that:
&nbsp;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.
&nbsp;2. When upgrading its nice that our zip file won't overwrite any
existing files in conf/
&nbsp;3. If you're running embedded you don't have to setup any
directories or have any config files, we can run on defaults.</p>
<p>The <em>ConfUtils.getConfResource</em> utility to do that pattern generically ,
but so far we're only using it for the users.properties and
groups.properties files. &nbsp;We should be using it everywhere.
&nbsp;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). &nbsp;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.</p>
<div id="edit" class="modal hide fade in" style="display: none; ">
<div class="modal-header">
<a class="close" data-dismiss="modal">x</a>
<h3>Thank you for contributing to the documentation!</h3>
</div>
<div class="modal-body">
<h4>Any help with the documentation is greatly appreciated.</h4>
<p>All edits are reviewed before going live, so feel free to do much more than fix typos or links. If you see a page that could benefit from an entire rewrite, we'd be thrilled to review it. Don't be surprised if we like it so much we ask you for help with other pages :)</p>
<small>NOTICE: unless indicated otherwise on the pages in question, all editable content available from apache.org is presumed to be licensed under the Apache License (AL) version 2.0 and hence all submissions to apache.org treated as formal Contributions under the license terms.</small>
<!--[if gt IE 6]>
<h4>Internet Explorer Users</h4>
<p>If you are not an Apache committer, click the Yes link and enter a <i>anonymous</i> for the username and leave the password empty</p>
<![endif]-->
</div>
<div class="modal-footer">
Do you have an Apache ID?
<a href="javascript:void(location.href='https://cms.apache.org/redirect?uri='+escape(location.href))" class="btn">Yes</a>
<a href="javascript:void(location.href='https://anonymous:@cms.apache.org/redirect?uri='+escape(location.href))" class="btn">No</a>
</div>
</div>
<script src="./../resources/js/bootstrap-modal.js"></script>
<footer>
<p>Copyright &copy; 1999-2016 The Apache Software Foundation, Licensed under the Apache License, Version 2.0.
Apache TomEE, TomEE, Apache, the Apache feather logo, and the Apache TomEE project logo are trademarks of The Apache Software Foundation.
All other marks mentioned may be trademarks or registered trademarks of their respective owners.</p>
</footer>
</div> <!-- /container -->
<!-- Javascript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="./../resources/js/bootstrap-dropdown.js"></script>
</body>
</html>