431 lines
18 KiB
XML
431 lines
18 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!--
|
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
|
contributor license agreements. See the NOTICE file distributed with
|
|
this work for additional information regarding copyright ownership.
|
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
|
(the "License"); you may not use this file except in compliance with
|
|
the License. You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
-->
|
|
<!DOCTYPE document [
|
|
<!ENTITY project SYSTEM "project.xml">
|
|
<!ENTITY le "≤" >
|
|
]>
|
|
<document url="logging.html">
|
|
|
|
&project;
|
|
|
|
<properties>
|
|
<title>Logging in Tomcat</title>
|
|
<author>Allistair Crossley</author>
|
|
<author email="yoavs@apache.org">Yoav Shapira</author>
|
|
</properties>
|
|
|
|
<body>
|
|
|
|
<section name="Table of Contents">
|
|
<toc/>
|
|
</section>
|
|
|
|
<section name="Introduction">
|
|
<p>
|
|
The internal logging for Apache Tomcat uses JULI, a packaged renamed fork
|
|
of <a href="https://commons.apache.org/logging">Apache Commons Logging</a>
|
|
that is hard-coded to use the <code>java.util.logging</code> framework.
|
|
This ensures that Tomcat's internal logging and any web application
|
|
logging will remain independent, even if a web application uses Apache
|
|
Commons Logging.
|
|
</p>
|
|
|
|
<p>
|
|
To configure Tomcat to use an alternative logging framework for its
|
|
internal logging, follow the instructions provided by the alternative
|
|
logging framework for redirecting logging for applications that use
|
|
<code>java.util.logging</code>. Keep in mind that the alternative logging
|
|
framework will need to be capable of working in an environment where
|
|
different loggers with the same name may exist in different class loaders.
|
|
</p>
|
|
|
|
<p>
|
|
A web application running on Apache Tomcat can:
|
|
</p>
|
|
<ul>
|
|
<li>
|
|
Use any logging framework of its choice.
|
|
</li>
|
|
<li>
|
|
Use system logging API, <code>java.util.logging</code>.
|
|
</li>
|
|
<li>
|
|
Use the logging API provided by the Java Servlets specification,
|
|
<code>javax.servlet.ServletContext.log(...)</code>
|
|
</li>
|
|
</ul>
|
|
|
|
<p>
|
|
The logging frameworks used by different web applications are independent.
|
|
See <a href="class-loader-howto.html">class loading</a> for more details.
|
|
The exception to this rule is <code>java.util.logging</code>. If it used
|
|
directly or indirectly by your logging library then elements of it will be
|
|
shared across web applications because it is loaded by the system class
|
|
loader.
|
|
</p>
|
|
|
|
<subsection name="Java logging API — java.util.logging">
|
|
|
|
<p>
|
|
Apache Tomcat has its own implementation of several key elements of
|
|
<code>java.util.logging</code> API. This implementation is called JULI.
|
|
The key component there is a custom LogManager implementation,
|
|
that is aware of different web applications running on Tomcat (and
|
|
their different class loaders). It supports private per-application
|
|
logging configurations. It is also notified by Tomcat when a web application
|
|
is unloaded from memory, so that the references to its classes can be
|
|
cleared, preventing memory leaks.
|
|
</p>
|
|
|
|
<p>
|
|
This <code>java.util.logging</code> implementation is enabled by providing
|
|
certain system properties when starting Java. The Apache Tomcat startup
|
|
scripts do this for you, but if you are using different tools to run
|
|
Tomcat (such as jsvc, or running Tomcat from within an IDE), you should
|
|
take care of them by yourself.
|
|
</p>
|
|
|
|
<p>
|
|
More details about java.util.logging may be found in the documentation
|
|
for your JDK and on its Javadoc pages for the <code>java.util.logging</code>
|
|
package.
|
|
</p>
|
|
|
|
<p>
|
|
More details about Tomcat JULI may be found below.
|
|
</p>
|
|
|
|
</subsection>
|
|
|
|
<subsection name="Servlets logging API">
|
|
|
|
<p>
|
|
The calls to <code>javax.servlet.ServletContext.log(...)</code> to write
|
|
log messages are handled by internal Tomcat logging. Such messages are
|
|
logged to the category named
|
|
</p>
|
|
<source>org.apache.catalina.core.ContainerBase.[${engine}].[${host}].[${context}]</source>
|
|
<p>
|
|
This logging is performed according to the Tomcat logging configuration. You
|
|
cannot overwrite it in a web application.
|
|
</p>
|
|
|
|
<p>
|
|
The Servlets logging API predates the <code>java.util.logging</code> API
|
|
that is now provided by Java. As such, it does not offer you much options.
|
|
E.g., you cannot control the log levels. It can be noted, though, that
|
|
in Apache Tomcat implementation the calls to <code>ServletContext.log(String)</code>
|
|
or <code>GenericServlet.log(String)</code> are logged at the INFO level.
|
|
The calls to <code>ServletContext.log(String, Throwable)</code> or
|
|
<code>GenericServlet.log(String, Throwable)</code>
|
|
are logged at the SEVERE level.
|
|
</p>
|
|
|
|
</subsection>
|
|
|
|
<subsection name="Console">
|
|
|
|
<p>
|
|
When running Tomcat on unixes, the console output is usually redirected
|
|
to the file named <code>catalina.out</code>. The name is configurable
|
|
using an environment variable. (See the startup scripts).
|
|
Whatever is written to <code>System.err/out</code> will be caught into
|
|
that file. That may include:
|
|
</p>
|
|
|
|
<ul>
|
|
<li>Uncaught exceptions printed by <code>java.lang.ThreadGroup.uncaughtException(..)</code></li>
|
|
<li>Thread dumps, if you requested them via a system signal</li>
|
|
</ul>
|
|
|
|
<p>
|
|
When running as a service on Windows, the console output is also caught
|
|
and redirected, but the file names are different.
|
|
</p>
|
|
|
|
<p>
|
|
The default logging configuration in Apache Tomcat writes the same
|
|
messages to the console and to a log file. This is great when using
|
|
Tomcat for development, but usually is not needed in production.
|
|
</p>
|
|
|
|
<p>
|
|
Old applications that still use <code>System.out</code> or <code>System.err</code>
|
|
can be tricked by setting <code>swallowOutput</code> attribute on a
|
|
<a href="config/context.html">Context</a>. If the attribute is set to
|
|
<code>true</code>, the calls to <code>System.out/err</code> during request
|
|
processing will be intercepted, and their output will be fed to the
|
|
logging subsystem using the
|
|
<code>javax.servlet.ServletContext.log(...)</code> calls.<br />
|
|
<strong>Note</strong>, that the <code>swallowOutput</code> feature is
|
|
actually a trick, and it has its limitations.
|
|
It works only with direct calls to <code>System.out/err</code>,
|
|
and only during request processing cycle. It may not work in other
|
|
threads that might be created by the application. It cannot be used to
|
|
intercept logging frameworks that themselves write to the system streams,
|
|
as those start early and may obtain a direct reference to the streams
|
|
before the redirection takes place.
|
|
</p>
|
|
|
|
</subsection>
|
|
|
|
<subsection name="Access logging">
|
|
|
|
<p>
|
|
Access logging is a related but different feature, which is
|
|
implemented as a <code>Valve</code>. It uses self-contained
|
|
logic to write its log files. The essential requirement for
|
|
access logging is to handle a large continuous stream of data
|
|
with low overhead, so it only uses Apache Commons Logging for
|
|
its own debug messages. This implementation approach avoids
|
|
additional overhead and potentially complex configuration.
|
|
Please refer to the <a href="config/valve.html#Access_Logging">Valves</a>
|
|
documentation for more details on its configuration, including
|
|
the various report formats.
|
|
</p>
|
|
|
|
</subsection>
|
|
|
|
</section>
|
|
|
|
<section name="Using java.util.logging (default)">
|
|
|
|
<p>
|
|
The default implementation of java.util.logging provided in the JDK is too
|
|
limited to be useful. The key limitation is the inability to have per-web
|
|
application logging, as the configuration is per-VM. As a result, Tomcat
|
|
will, in the default configuration, replace the default LogManager
|
|
implementation with a container friendly implementation called JULI, which
|
|
addresses these shortcomings.
|
|
</p>
|
|
<p>
|
|
JULI supports the same configuration mechanisms as the standard JDK
|
|
<code>java.util.logging</code>, using either a programmatic approach, or
|
|
properties files. The main difference is that per-classloader properties
|
|
files can be set (which enables easy redeployment friendly webapp
|
|
configuration), and the properties files support extended constructs which
|
|
allows more freedom for defining handlers and assigning them to loggers.
|
|
</p>
|
|
<p>
|
|
JULI is enabled by default, and supports per classloader configuration, in
|
|
addition to the regular global java.util.logging configuration. This means
|
|
that logging can be configured at the following layers:
|
|
</p>
|
|
<ul>
|
|
<li>Globally. That is usually done in the
|
|
<code>${catalina.base}/conf/logging.properties</code> file.
|
|
The file is specified by the <code>java.util.logging.config.file</code>
|
|
System property which is set by the startup scripts.
|
|
If it is not readable or is not configured, the default is to use the
|
|
<code>${java.home}/lib/logging.properties</code> file in the JRE.
|
|
</li>
|
|
<li>In the web application. The file will be
|
|
<code>WEB-INF/classes/logging.properties</code>
|
|
</li>
|
|
</ul>
|
|
<p>
|
|
The default <code>logging.properties</code> in the JRE specifies a
|
|
<code>ConsoleHandler</code> that routes logging to System.err.
|
|
The default <code>conf/logging.properties</code> in Apache Tomcat also
|
|
adds several <code>AsyncFileHandler</code>s that write to files.
|
|
</p>
|
|
<p>
|
|
A handler's log level threshold is <code>INFO</code> by default and can be set using
|
|
<code>SEVERE</code>, <code>WARNING</code>, <code>INFO</code>, <code>CONFIG</code>,
|
|
<code>FINE</code>, <code>FINER</code>, <code>FINEST</code> or <code>ALL</code>.
|
|
You can also target specific packages to collect logging from and specify
|
|
a level.
|
|
</p>
|
|
<p>
|
|
To enable debug logging for part of Tomcat's internals, you should
|
|
configure both the appropriate logger(s) and the appropriate handler(s) to
|
|
use the <code>FINEST</code> or <code>ALL</code> level. e.g.:
|
|
</p>
|
|
<source>org.apache.catalina.session.level=ALL
|
|
java.util.logging.ConsoleHandler.level=ALL</source>
|
|
<p>
|
|
When enabling debug logging it is recommended that it is enabled for the
|
|
narrowest possible scope as debug logging can generate large amounts of
|
|
information.
|
|
</p>
|
|
<p>
|
|
The configuration used by JULI is the same as the one supported by plain
|
|
<code>java.util.logging</code>, but uses a few extensions to allow better
|
|
flexibility in configuring loggers and handlers. The main differences are:
|
|
</p>
|
|
<ul>
|
|
<li>A prefix may be added to handler names, so that multiple handlers of a
|
|
single class may be instantiated. A prefix is a String which starts with a
|
|
digit, and ends with '.'. For example, <code>22foobar.</code> is a valid
|
|
prefix.</li>
|
|
<li>System property replacement is performed for property values which
|
|
contain <code>${systemPropertyName}</code>.</li>
|
|
<li>If using a class loader that implements the
|
|
<code>org.apache.juli.WebappProperties</code> interface (Tomcat's
|
|
web application class loader does) then property replacement is also
|
|
performed for <code>${classloader.webappName}</code>,
|
|
<code>${classloader.hostName}</code> and
|
|
<code>${classloader.serviceName}</code> which are replaced with the
|
|
web application name, the host name and the service name respectively.
|
|
</li>
|
|
<li>By default, loggers will not delegate to their parent if they have
|
|
associated handlers. This may be changed per logger using the
|
|
<code>loggerName.useParentHandlers</code> property, which accepts a
|
|
boolean value.</li>
|
|
<li>The root logger can define its set of handlers using the
|
|
<code>.handlers</code> property.</li>
|
|
<li> By default the log files will be kept on the file system forever.
|
|
This may be changed per handler using the
|
|
<code>handlerName.maxDays</code> property. If the specified value for the
|
|
property is <code>≤0</code> then the log files will be kept on the
|
|
file system forever, otherwise they will be kept the specified maximum
|
|
days.</li>
|
|
</ul>
|
|
<p>
|
|
There are several additional implementation classes, that can be used
|
|
together with the ones provided by Java. The notable ones are
|
|
<code>org.apache.juli.FileHandler</code> and <code>org.apache.juli.AsyncFileHandler</code>.
|
|
</p>
|
|
<p>
|
|
<code>org.apache.juli.FileHandler</code> supports buffering of the
|
|
logs. The buffering is not enabled by default. To configure it, use the
|
|
<code>bufferSize</code> property of a handler. The value of <code>0</code>
|
|
uses system default buffering (typically an 8K buffer will be used). A
|
|
value of <code><0</code> forces a writer flush upon each log write. A
|
|
value <code>>0</code> uses a BufferedOutputStream with the defined
|
|
value but note that the system default buffering will also be
|
|
applied.
|
|
</p>
|
|
<p>
|
|
<code>org.apache.juli.AsyncFileHandler</code> is a subclass of <code>FileHandler</code>
|
|
that queues the log messages and writes them asynchronously to the log files.
|
|
Its additional behaviour can be configured by setting some
|
|
<a href="config/systemprops.html#Logging">system properties</a>.
|
|
</p>
|
|
<p>
|
|
Example logging.properties file to be placed in $CATALINA_BASE/conf:
|
|
</p>
|
|
<source><![CDATA[handlers = 1catalina.org.apache.juli.FileHandler, \
|
|
2localhost.org.apache.juli.FileHandler, \
|
|
3manager.org.apache.juli.FileHandler, \
|
|
java.util.logging.ConsoleHandler
|
|
|
|
.handlers = 1catalina.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
|
|
|
|
############################################################
|
|
# Handler specific properties.
|
|
# Describes specific configuration info for Handlers.
|
|
############################################################
|
|
|
|
1catalina.org.apache.juli.FileHandler.level = FINE
|
|
1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
|
|
1catalina.org.apache.juli.FileHandler.prefix = catalina.
|
|
1catalina.org.apache.juli.FileHandler.maxDays = 90
|
|
1catalina.org.apache.juli.FileHandler.encoding = UTF-8
|
|
|
|
2localhost.org.apache.juli.FileHandler.level = FINE
|
|
2localhost.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
|
|
2localhost.org.apache.juli.FileHandler.prefix = localhost.
|
|
2localhost.org.apache.juli.FileHandler.maxDays = 90
|
|
2localhost.org.apache.juli.FileHandler.encoding = UTF-8
|
|
|
|
3manager.org.apache.juli.FileHandler.level = FINE
|
|
3manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
|
|
3manager.org.apache.juli.FileHandler.prefix = manager.
|
|
3manager.org.apache.juli.FileHandler.bufferSize = 16384
|
|
3manager.org.apache.juli.FileHandler.maxDays = 90
|
|
3manager.org.apache.juli.FileHandler.encoding = UTF-8
|
|
|
|
java.util.logging.ConsoleHandler.level = FINE
|
|
java.util.logging.ConsoleHandler.formatter = java.util.logging.OneLineFormatter
|
|
java.util.logging.ConsoleHandler.encoding = UTF-8
|
|
|
|
############################################################
|
|
# Facility specific properties.
|
|
# Provides extra control for each logger.
|
|
############################################################
|
|
|
|
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
|
|
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = \
|
|
2localhost.org.apache.juli.FileHandler
|
|
|
|
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO
|
|
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = \
|
|
3manager.org.apache.juli.FileHandler
|
|
|
|
# For example, set the org.apache.catalina.util.LifecycleBase logger to log
|
|
# each component that extends LifecycleBase changing state:
|
|
#org.apache.catalina.util.LifecycleBase.level = FINE]]></source>
|
|
|
|
<p>
|
|
Example logging.properties for the servlet-examples web application to be
|
|
placed in WEB-INF/classes inside the web application:
|
|
</p>
|
|
<source><![CDATA[handlers = org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
|
|
|
|
############################################################
|
|
# Handler specific properties.
|
|
# Describes specific configuration info for Handlers.
|
|
############################################################
|
|
|
|
org.apache.juli.FileHandler.level = FINE
|
|
org.apache.juli.FileHandler.directory = ${catalina.base}/logs
|
|
org.apache.juli.FileHandler.prefix = ${classloader.webappName}.
|
|
|
|
java.util.logging.ConsoleHandler.level = FINE
|
|
java.util.logging.ConsoleHandler.formatter = java.util.logging.OneLineFormatter]]></source>
|
|
|
|
|
|
<subsection name="Documentation references">
|
|
<p>See the following resources for additional information:</p>
|
|
<ul>
|
|
<li>Apache Tomcat Javadoc for the
|
|
<a href="api/org/apache/juli/package-summary.html"><code>org.apache.juli</code></a>
|
|
package.
|
|
</li>
|
|
<li>Oracle Java 7 Javadoc for the
|
|
<a href="https://docs.oracle.com/javase/7/docs/api/java/util/logging/package-summary.html"><code>java.util.logging</code></a>
|
|
package.
|
|
</li>
|
|
</ul>
|
|
</subsection>
|
|
|
|
<subsection name="Considerations for production usage">
|
|
<p>You may want to take note of the following:</p>
|
|
<ul>
|
|
<li>Consider removing <code>ConsoleHandler</code> from configuration. By
|
|
default (thanks to the <code>.handlers</code> setting) logging goes both
|
|
to a <code>FileHandler</code> and to a <code>ConsoleHandler</code>. The
|
|
output of the latter one is usually captured into a file, such as
|
|
<code>catalina.out</code>. Thus you end up with two copies of the same
|
|
messages.</li>
|
|
<li>Consider removing <code>FileHandler</code>s for the applications
|
|
that you do not use. E.g., the one for <code>host-manager</code>.</li>
|
|
<li>The handlers by default use the system default encoding to write
|
|
the log files. It can be configured with <code>encoding</code> property.
|
|
See Javadoc for details.</li>
|
|
<li>Consider configuring an
|
|
<a href="config/valve.html#Access_Logging">Access log</a>.</li>
|
|
</ul>
|
|
</subsection>
|
|
|
|
</section>
|
|
|
|
</body>
|
|
</document>
|