Resin Logging

From Resin 3.0

Revision as of 08:58, 17 December 2009 by Reza (Talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

<document> <header>

 <product>resin</product>
 <title>Log</title>
 <description>

Resin can perform access logging, specify where JDK logging interface messages go, and redirect the stderr and stdout for your applications.

 </description>

</header>

<body> <localtoc/>

<s1 title="java.util.logging">

<s2 title="Logger: Application logging">

You can take advantage of the JDK's logging facility to add logging to your application. Choosing a good logging name and levels are important for troubleshooting and debugging your code. Logging to much can be almost as confusing as logging too little.

The logging name should be the full class name of the class you're instrumenting. Although other schemes are possible, the class name is more maintainable.

The logging level should be consistent across your application. For Resin, we use the following level conventions:

<example title="Example: logging at finer"> import java.util.logging.Logger; import java.util.logging.Level;

public class Foo {

 private static final Logger log
   = Logger.getLogger(Foo.class.getName());
 ...
 void doFoo(String bar)
 {
   // check for log level if your logging call does anything more
   // than pass parameters
   if (log.isLoggable(Level.FINER))
       log.finer(this + "doFoo(" + bar + ")");
   ...
   log.info(...);
   try {
       ...
   } catch (ExpectedException ex) {
     log.log(Level.FINEST, "expected exception", ex);
   }
 }
 ...

} </example> </s2>

<s2 title="Log names">

The JDK logging api uses a hierarchical naming scheme. Typically the name is aligned with a java class name. When you specify a name, all logging requests that use a name that starts with the name you have specified are matched. For example: <logger name="example.hogwarts" ...> matches a logging request for both "example.hogwarts.System" and "example.hogwarts.gryffindor.System"

Resin's logging is based on Resin's source class names. The following are useful logs.

<deftable title="Resin log names"> <tr>

 <th>name</th>
 <th>Meaning</th>

</tr> <tr>

 <td>""</td>
 <td>Debug everything</td>

</tr> <tr>

 <td>com.caucho.amber</td>
 <td>Amber (JPA) handling</td>

</tr> <tr>

 <td>com.caucho.ejb</td>
 <td>EJB handling</td>

</tr> <tr>

 <td>com.caucho.jsp</td>
 <td>Debug jsp</td>

</tr> <tr>

 <td>com.caucho.java</td>
 <td>Java compilation</td>

</tr> <tr>

 <td>com.caucho.server.port</td>
 <td>TCP port debugging and threading</td>

</tr> <tr>

 <td>com.caucho.server.port.AcceptPool</td>
 <td>port thread creation</td>

</tr> <tr>

 <td>com.caucho.server.http</td>
 <td>HTTP-related debugging</td>

</tr> <tr>

 <td>com.caucho.server.webapp</td>
 <td>web-app related debugging</td>

</tr> <tr>

 <td>com.caucho.server.cache</td>
 <td>Cache related debugging</td>

</tr> <tr>

 <td>com.caucho.sql</td>
 <td>Database pooling</td>

</tr> <tr>

 <td>com.caucho.transaction</td>
 <td>Transaction handling</td>

</tr> </deftable>

</s2>

<s2 title="Log levels">

The level for log tags matches the levels in the JDK <a href="javadoc|java.util.logging.Level|"/>.

<deftable title="Logging Level values"> <tr>

 <th>Name</th>
 <th>API</th>
 <th>Suggested Use</th>

</tr> <tr>

 <td>off</td>
 <td> </td>
 <td>turn off logging</td>

</tr> <tr>

 <td>severe</td>
 <td>log.severe("...")</td>
 <td>a major failure which prevents normal program execution,

e.g. a web-app failing to start or a server restart</td> </tr> <tr>

<td>warning</td>
 <td>log.warning("...")</td>
 <td>a serious issue, likely causing incorrect behavior, like a

500 response code to a browser</td> </tr> <tr>

 <td>info</td>
 <td>log.info("...")</td>
 <td>major lifecycle events, like a web-app starting</td>

</tr> <tr>

 <td>config</td>
 <td>log.config("...")</td>
 <td>detailed configuration logging</td>

</tr> <tr>

 <td>fine</td>
 <td>log.fine("...")</td>
 <td>debugging at an administrator level, i.e. for someone not familiar with

the source code being debugged</td> </tr> <tr>

 <td>finer</td>
 <td>log.finer("...")</td>
 <td>detailed debugging for a developer of the code being debugged</td>

</tr> <tr>

 <td>finest</td>
 <td>log.finest("...")</td>
 <td>events not normally debugged, e.g. expected exceptions logged to

avoid completely swallowing, or Hessian or XML protocol parsing</td> </tr> <tr>

 <td>all</td>
 <td> </td>
 <td>all messages should be logged</td>

</tr> </deftable>

</s2>

<s2 title="<log-handler>" type="defun"> <parents>resin, server, host-default, host, web-app-default, web-app</parents>

Configure a log handler for the JDK java.util.logging.* API. java.util.logging has two steps: configure a set of log handlers, and configure the levels for each logger. The <log-handler> creates a destination for logs, sets a minimum logging level for the handler, and attaches the handler to a logging name.

In addition to configuring custom handlers, <log-handler> has the most common configuration build-in: logging to a rotating file. Most of the configuration attributes are used for the rotating file and are shared with the other logging configuration.

<deftable-childtags title="<log-handler> values"> <tr>

 <th>Attribute</th>
 <th>Description</th>
 <th>Default</th>

</tr> <tr>

 <td>archive-format</td>
 <td>the format for the archive filename when a rollover occurs,
       see <a href="#rollover">Rollovers</a>.
   </td>
 <td>see below</td>

</tr> <tr>

 <td>class</td>
 <td>configures a custom Handler class</td>
 <td></td>

</tr> <tr>

 <td>formatter</td>
 <td>Configures a custom java.util.logging.Formatter to format

the output.</td>

 <td></td>

</tr> <tr>

 <td>init</td>
 <td>IoC-style initialization configuration for the formatter.</td>
 <td></td>

</tr> <tr>

 <td>level</td>
 <td>The <a href="#Log-Levels">log level</a> for the handler.  Typically,

the handler's level will be finer than the logger's level</td>

 <td>info</td>

</tr> <tr>

 <td>mbean-name</td>
 <td>an mbean name, see <a href="#mbean">MBean control</a>.</td>
 <td>no mbean name, no mbean registration</td>

</tr> <tr>

 <td>name</td>
 <td>A hierarchical name, typically aligned with the Java packaging names.

The handler will be registered with the Logger with the matching name.</td>

 <td>match all names</td>

</tr> <tr>

 <td>path</td>
 <td>Output path for the log messages, see 
      <a href="#path">"Log Paths"</a>
   </td>
 <td>required</td>

</tr> <tr>

 <td>path-format</td>
 <td>Selects a format for generating path names.  The syntax is the same as for archive-format</td>
 <td>optional</td>

</tr> <tr>

 <td>timestamp</td>
 <td>a timestamp <a href="#timestamp">format string</a> 
       to use at the beginning of each log line.
   </td>
 <td>"[%Y/%m/%d %H:%M:%S.%s] "</td>

</tr> <tr>

 <td>rollover-count</td>
 <td>maximum number of rollover files before the oldest ones get overwritten.
       See <a href="#rollover">Rollovers</a>. 
   </td>
 <td>none</td>

</tr> <tr>

 <td>rollover-cron</td>
 <td>cron-style specification on rollover times.</td>
 <td>none</td>

</tr> <tr>

 <td>rollover-period</td>
 <td>how often to rollover the log.  Specify in days (15D), weeks (2W), 
       months (1M), or hours (1h). See <a href="#rollover">Rollovers</a>. 
   </td>
 <td>none</td>

</tr> <tr>

 <td>rollover-size</td>
 <td>maximum size of the file before a rollover occurs, in bytes (50000), 
       kb (128kb), or megabytes (10mb).  
       See <a href="#rollover">Rollovers</a>.
   </td>
 <td>1mb</td>

</tr> <tr>

 <td>uri</td>
 <td>configures a symbolic alias for the handler's class.  The handler implementer will register the schema</td>
 <td></td>

</tr> </deftable-childtags>

<def title="<log-handler> schema"> element log-handler {

 archive-format?
 & class?
 & filter?
 & format?
 & formatter?
 & init?
 & level?
 & mbean-name?
 & name
 & path?
 & path-format?
 & rollover-count?
 & rollover-period?
 & rollover-size?
 & timestamp?
 & uri?
 & use-parent-handlers?

} </def>

The following example sends warning messages to a JMS queue. The uri="jms:" is an alias for com.caucho.log.handler.JmsHandler. The uri="timestamp:" is a formatter alias for com.caucho.log.formatter.TimestampFormatter

<example title="Example: logging to a JMS queue"> <web-app xmlns="http://caucho.com/ns/resin">

 <jms-queue name="myQueue" uri="memory:"/>
 <log-handler name="qa.test" level="warning" uri="jms:">
   <init target="${myQueue}"/>
   <formatter uri="timestamp:"/>
 </log-handler>

</web-app> </example>

The following example is a standard log handler writing to a rollover file. Because the handler's level is "all", the <logger> configuration will set the actual logging level.

<example title="Example: logging to a rollover file"> <web-app xmlns="http://caucho.com/ns/resin">

 <jms-queue name="myQueue" uri="memory:"/>
 <log-handler name="" level="all"
      timestamp="[%Y/%m/%d %H:%M:%S.%s] {%{thread}} "/>
 <logger name="com.caucho" level="info"/>

</web-app> </example>

</s2>

<s2 title="<log>" type="defun"> <parents>resin, server, host-default, host, web-app-default, web-app</parents>

Configure the amount and destination of debug logging for the JDK java.util.logging.* API.

<deftable-childtags title="<log> values"> <tr>

 <th>Attribute</th>
 <th>Description</th>
 <th>Default</th>

</tr> <tr>

 <td>name</td>
 <td>A hierarchical name, typically aligned with the Java packaging names</td>
 <td>match all names</td>

</tr> <tr>

 <td>level</td>
 <td>The <a href="#Log-Levels">log level</a></td>
 <td>info</td>

</tr> <tr>

 <td>path</td>
 <td>Output path for the log messages, see 
      <a href="#path">"Log Paths"</a>
   </td>
 <td>required</td>

</tr> <tr>

 <td>path-format</td>
 <td>Selects a format for generating path names.  The syntax is the same as for archive-format</td>
 <td>optional</td>

</tr> <tr>

 <td>timestamp</td>
 <td>a timestamp <a href="#timestamp">format string</a> 
       to use at the beginning of each log line.
   </td>
 <td>"[%Y/%m/%d %H:%M:%S.%s] "</td>

</tr> <tr>

 <td>format</td>
 <td>a <a href="#Format-String">format string</a> to control the 
       output of each log message. Since Resin 3.0.5.
   </td>
 <td>${log.message}</td>

</tr> <tr>

 <td>rollover-count</td>
 <td>maximum number of rollover files before the oldest ones get overwritten.
       See <a href="#rollover">Rollovers</a>. 
   </td>
 <td>none</td>

</tr> <tr>

 <td>rollover-period</td>
 <td>how often to rollover the log.  Specify in days (15D), weeks (2W), 
       months (1M), or hours (1h). See <a href="#rollover">Rollovers</a>. 
   </td>
 <td>none</td>

</tr> <tr>

 <td>rollover-size</td>
 <td>maximum size of the file before a rollover occurs, in bytes (50000), 
       kb (128kb), or megabytes (10mb).  
       See <a href="#rollover">Rollovers</a>.
   </td>
 <td>1mb</td>

</tr> <tr>

 <td>archive-format</td>
 <td>the format for the archive filename when a rollover occurs,
       see <a href="#rollover">Rollovers</a>.
   </td>
 <td>see below</td>

</tr> <tr>

 <td>mbean-name</td>
 <td>an mbean name, see <a href="#mbean">MBean control</a>.</td>
 <td>no mbean name, no mbean registration</td>

</tr> <tr>

 <td>handler</td>
 <td>add a custom Handler, the name of a class that extends 
       <a href="javadoc|java.util.logging.Handler"/>
   </td>
 <td> </td>

</tr> <tr>

 <td>formatter</td>
 <td>set a custom Formatter, the name of a class that extends 
       <a href="javadoc|java.util.logging.Formatter"/>
   </td>
 <td>none, or <a href="javadoc|com.caucho.log.ELFormatter"/> if 
       format is used.</td>

</tr> </deftable-childtags>

The default archive format is

<def title="default archive-format"> path + ".%Y%m%d" if rollover-period >= 1 day. path + ".%Y%m%d.%H" if rollover-period < 1 day. </def>

For example, to log everything to standard error use:

<example title="Example: logging everything to System.err"> <resin xmlns="http://caucho.com/ns/resin">

 <log name= level='all' path='stderr:' timestamp="[%H:%M:%S.%s]"/>
 ...

</resin> </example>

A useful technique is to enable full debug logging to track down a problem:

<example title="debug logging">

<resin>

 ...
 <log name= level='finer' path='log/debug.log'
      timestamp="[%H:%M:%S.%s]"
      rollover-period='1h' rollover-count='1'/>
 ...

</resin> </example>

More examples of debug logging are in the <a href="troubleshoot-technique.xtp#debug-log">Troubleshooting</a> section.

The class that corresponds to <log> is <a href="javadoc|com.caucho.log.LogConfig|"/>.

<s3 name="Format-String" title="Log format string">

The format for log tags is used to specify a format string for each log message. format recognizes EL-expressions. The EL variable log is a <a href="javadoc|com.caucho.log.ELFormatter.ELFormatterLogRecord|"/> object.

<example title="log format string">

<log name= level='all' path='stderr:' timestamp="[%H:%M:%S.%s]"

    format=" ${log.level} ${log.loggerName} ${log.message}"/>

</example>

<deftable title="log EL variable 'log' is a LogRecord"> <tr><th>Accessor</th><th>Value </th></tr><tr><td>${log.level}</td><td>The level of the log record </td></tr><tr><td>${log.name}</td><td>The source loggers name </td></tr><tr><td>${log.shortName}</td><td>A shorter version of the source loggers name, "Foo" instead of "com.hogwarts.Foo" </td></tr><tr><td>${log.message}</td><td>The message, with no formatting or localization </td></tr><tr><td>${log.millis}</td><td>event time in milliseconds since 1970 </td></tr><tr><td>${log.sourceClassName}</td><td>Get the name of the class that issued the logging request (may not be available at runtime) </td></tr><tr><td>${log.sourceMethodName}</td><td>Get the name of the method that issued the logging request (may not be available at runtime) </td></tr><tr><td>${log.threadID}</td><td>Get an int identifier of the thread where the logging request originated </td></tr><tr><td>${log.thrown}</td><td>Get any <a href="javadoc|java.lang.Throwable|"/> associated with the logging request </td></tr></deftable>

You can also use the <a href="el-var.xtp">Environment EL variables</a> in your format string:

<example title="log format string using an Environment EL variable."> <host ...>

 <web-app>
   <log name= level='all' path='log/debug.log' timestamp="[%H:%M:%S.%s]"
        format=" [${app.contextPath}] ${log.message}"/>
   ...
 </web-app>
 ...

</host> </example> <results> [14:55:10.189] [/foo] `null' returning JNDI java:

      model for EnvironmentClassLoader[web-app:http://localhost:8080/foo]

[14:55:10.189] [/foo] JNDI lookup `java:comp/env/caucho/auth'

      exception javax.naming.NameNotFoundException: java:comp/env/caucho/auth

[14:55:10.199] [/foo] Application[1] starting

</results>

The <a href="el-var.xtp#sprintf">fmt.sprintf()</a> function can space pad the values and make the results look a little nicer:

<example title="fmt.sprintf() in log format string"> <log name= level='all' path='stderr:' timestamp="[%H:%M:%S.%s]"

    format=" ${fmt.sprintf('%-7s %45s %s',log.level,log.loggerName,log.message)}"/>

</example>

<results> [14:28:08.137] INFO com.caucho.vfs.QJniServerSocket Loaded Socket JNI library. [14:28:08.137] INFO com.caucho.server.port.Port http listening to *:8080 [14:28:08.137] INFO com.caucho.server.resin.ServletServer ServletServer[] starting [14:28:08.307] INFO com.caucho.server.port.Port hmux listening to localhost:6802 [14:28:08.437] INFO com.caucho.server.host.Host Host[] starting </results>


<a href="config-el.xtp#sprintf">fmt.sprintf()</a> and <a href="config-el.xtp#timestamp">fmt.timestamp()</a> can be used to produce CSV files:

<example title="CSV log files"> <log name= level='all' path='log/debug.csv' timestamp=""

    format="${fmt.sprintf('%vs,%d,%d,%vs,%vs',fmt.timestamp('%Y-%m-%d %H:%M:%S.%s'), 
              log.threadID, log.level.intLevel(), log.loggerName, log.message)}"/>

</example>

<results> "2003-11-17 14:46:14.529",10,800,"com.caucho.vfs.QJniServerSocket",

           "Loaded Socket JNI library."

"2003-11-17 14:46:14.549",10,800,"com.caucho.server.port.Port",

           "http listening to *:8080"

"2003-11-17 14:46:14.549",10,800,"com.caucho.server.resin.ServletServer",

           "ServletServer[] starting"

"2003-11-17 14:46:14.719",10,800,"com.caucho.server.port.Port",

           "hmux listening to localhost:6802"

"2003-11-17 14:46:14.850",10,800,"com.caucho.server.host.Host",

           "Host[] starting"

"2003-11-17 14:46:15.100",10,800,"com.caucho.server.webapp.Application",

           "Application[2] starting"

</results>

</s3>

</s2>

<s2 title="Log Handlers">

Resin provides a number of predefined custom log handlers for common logging patterns, including sending messages to JMS, <a href="hmtp">HMTP</a>, and the syslog service. Creating your own custom handler is also straightforward.

<s3 name="bam" title="BamHandler, uri='bam:' (3.2.0)">

The BAM handler publishes the log message to a <a href="hmtp.xtp">BAM</a> agent. The agent can be a custom HMTP service to process log messages. The BamHandler needs a JID (Jabber id) as the address of the target service.

<example title="Example: BAM handler configuration"> <web-app xmlns="http://caucho.com/ns/resin">

 <log-handler name="com.foo" level="warning" uri="bam:">
   <init>
      <to>test@localhost</to>
  </init>
 </log-handler>

</web-app> </example>

</s3>

<s3 name="event" title="EventHandler, uri='event:'">

The event handler publishes a LogEvent to the WebBeans event system. Any WebBeans component with an @Observes method for LogEvent will receive the notifications. The log handler classname is com.caucho.log.handler.EventHandler and the shortcut is uri="event:".

<example title="Example: event handler configuration"> <web-app xmlns="http://caucho.com/ns/resin">

 <log-handler name="com.foo" level="warning" uri="event:"/>

</web-app> </example>

</s3>

<s3 name="jms" title="JmsHandler, uri='jms:'">

The JMS handler publishes the log message to a <a href="resin-messaging.xtp">JMS</a> queue.

<example title="Example: JMS handler configuration"> <web-app xmlns="http://caucho.com/ns/resin">

 <jms-queue name="myQueue" uri="memory:"/>
 <log-handler name="com.foo" level="warning" uri="jms:">
   <init>
      <target>${myQueue}</target>
  </init>
 </log-handler>

</web-app> </example>

</s3>

<s3 name="mail" title="MailHandler, uri='mail:' (3.2.0)">

The Mail handler sends log messages to an email address. To keep the number of mails down, the handler will concatenate messages and only send them after a period of time.

<deftable title="mail: attributes"> <tr>

 <th>attribute</th>
 <th>description</th>
 <th>default</th>

</tr> <tr>

 <td>to</td>
 <td>mail address</td>
 <td>required</td>

</tr> <tr>

 <td>delay-time</td>
 <td>time to wait before sending first mail</td>
 <td>1m</td>

</tr> <tr>

 <td>mail-interval-min</td>
 <td>minimum time between mail messages</td>
 <td>1h</td>

</tr> <tr>

 <td>properties</td>
 <td>javamail properties in property file format</td>
 <td></td>

</tr> </deftable>

<example title="Example: Mail handler configuration"> <web-app xmlns="http://caucho.com/ns/resin">

 <log-handler name="" level="warning" uri="mail:">
   <init>
      <to>admin@foo.com</to>
      <properties>
        mail.smtp.host=127.0.0.1
        mail.smtp.port=25
      </properties>
  </init>
 </log-handler>

</web-app> </example>

</s3>

<s3 name="syslog" title="SyslogHandler, uri='syslog:'">

On Unix systems, the SyslogHandler lets you log messages to syslog.

<example title="Example: syslog configuration"> <resin xmlns="http://caucho.com/ns/resin">

<log-handler name="" level="warning" uri="syslog:">

   <init>
     <facility>daemon</facility>
     <severity>notice</severity>
   </init>

</log-handler> </example>

The possible values for facility are user, mail, daemon, auth, lpr, news, uucp, cron, authpriv, ftp, local0, local1, local2, local3, local4, local5, local6, local7. The default is daemon.

The possible values for severity are emerg, alert, crit, err, warning, notice, info, debug. The default is info.

See also `man 3 syslog' and `man syslog.conf'.

</s3>

<s3 title="custom handler">

<example title="Example: custom formatter configuration"> <web-app xmlns="http://caucho.com/ns/resin">

 <log-handler name="" level="warning" class="demo.MyHandler"/>
 

</web-app> </example>

<example title="Example: MyHandler.java"> package demo;

import java.util.logging.*;

public class MyHandler extends Handler {

 @Override
 public void publish(LogRecord record)
 {
   System.out.println(getFormatter().format(record));
 }
 
 @Override
 public void flush();
 {
 }
 
 @Override
 public void close();
 {
 }

} </example>

</s3>

</s2>

<s2 title="Log Formatting">

Sites may wish to change the formatting of log messages to gather information more appropriate for the site. The formatter can be custom-configured just like the handlers.

<s3 title="custom handler">

<example title="Example: custom formatter configuration"> <web-app xmlns="http://caucho.com/ns/resin">

 <log-handler name="com.foo" level="warning" path="WEB-INF/log.log">
   <formatter class="qa.MyFormatter"/>
 </log-handler>
 

</web-app> </example>

<example title="Example: MyFormatter.java"> package demo;

import java.util.logging.*;

public class MyFormatter extends Formatter {

 @Override
 public String format(LogRecord record)
 {
   return "[" + record.getLevel() + "] " + record.getMessage();
 }

} </example>

</s3>

</s2>

</s1>

<s1 title="Standard Output Redirection">

<s2 title="stdout-log" type="defun"> <parents>resin, server, host-default, web-app-default, web-app</parents> <default>use the JDK's destination for System.out</default>

Configure the destination for System.out.

Usage of the stdout-log overrides a previous usage. For example, specifying stdout-log as a child of a <a config-tag="web-app"/> causes a redirection of System.out for that web application only, and will override the System.out location in the enclosing <a config-tag="host"/>.

<warn>The path must not be the same as the path specified on the command line with -stdout. If it is, there will be conflicts with which process owns the file.</warn>

<deftable-childtags> <tr>

 <td>archive-format</td>
 <td>the format for the archive filename when a rollover occurs,
       see <a href="#rollover">Rollovers</a>.
   </td>
 <td>see below</td>

</tr> <tr>

 <td>path</td>
 <td>Output path for the stream, see <a href="#path">"Log Paths"</a>.</td>
 <td>required</td>

</tr> <tr>

 <td>path-format</td>
 <td>Selects a format for generating path names.  The syntax is the same as for archive-format</td>
 <td>optional</td>

</tr> <tr>

 <td>rollover-count</td>
 <td>maximum number of rollover files before the oldest ones get overwritten.
     See <a href="#rollover">Rollovers</a>. 
   </td>
<td>none</td>

</tr> <tr>

 <td>rollover-period</td>
 <td>how often to rollover the log.  Specify in days (15D), weeks (2W), 
       months (1M), or hours (1h). See <a href="#rollover">Rollovers</a>. 
   </td>
<td>none</td>

</tr> <tr>

 <td>rollover-size</td>
 <td>maximum size of the file before a rollover occurs, in bytes (50000), 
       kb (128kb), or megabytes (10mb).  
       See <a href="#rollover">Rollovers</a>.
   </td>
 <td>1mb
 </td>

</tr> <tr>

 <td>timestamp</td>
 <td>a timestamp <a href="#timestamp">format string</a> to use at the beginning of each log line.</td>
 <td>no timestamp</td>

</tr> </deftable-childtags>

The default archive format is

  <var>path</var> + ".%Y%m%d" or
  <var>path</var> + ".%Y%m%d.%H" if rollover-period < 1 day.

The following example configures System.out for a <a config-tag="host"/>. Unless a <a config-tag="web-app">web-app</a> overrides with it's own stdout-log, all web-apps in the host will write to the same output file.

<example> ... <host id='foo.com'>

 <stdout-log path='/var/log/foo/stdout.log'
             rollover-period='1W'/>
 ...

</host> ...

 </example>

</s2>

<s2 title="stderr-log" type="defun"> <parents>resin, server, host-default, web-app-default, web-app</parents> <default>use the JDK's destination for System.err</default>

Configure the destination for System.err.

Usage of the stderr-log overrides a previous usage. For example, specifying stderr-log as a child of a <a config-tag="web-app"/> causes a redirection of System.err for that web application only, and will override the System.err location in the enclosing <a config-tag="host"/>.

<warn>The path must not be the same as the path specified on the command line with -stderr. If it is, there will be conflicts with which process owns the file.</warn>

<deftable-childtags> <tr><td>path

   </td><td>Output path for the stream, see <a href="#path">"Log Paths"</a>.  
   </td><td>required

</td></tr> <tr>

 <td>path-format</td>
 <td>Selects a format for generating path names.  The syntax is the same as for archive-format</td>
 <td>optional</td>

</tr> <tr><td>timestamp

   </td><td>a timestamp <a href="#timestamp">format string</a> 
       to use at the beginning of each log line.
   </td><td>no timestamp
   </td></tr><tr><td>rollover-count
   </td><td>maximum number of rollover files before the oldest ones get overwritten.
       See <a href="#rollover">Rollovers</a>. 
   </td><td>none

</td></tr><tr><td>rollover-period

   </td><td>how often to rollover the log.  Specify in days (15D), weeks (2W), 
       months (1M), or hours (1h). See <a href="#rollover">Rollovers</a>. 
   </td><td>none

</td></tr><tr><td>rollover-size

   </td><td>maximum size of the file before a rollover occurs, in bytes (50000), 
       kb (128kb), or megabytes (10mb).  
       See <a href="#rollover">Rollovers</a>.
   </td><td>1mb

</td></tr><tr><td>archive-format

   </td><td>the format for the archive filename when a rollover occurs,
       see <a href="#rollover">Rollovers</a>.
   </td><td>see below

</td></tr></deftable-childtags>

The default archive format is

  <var>path</var> + ".%Y%m%d" or
  <var>path</var> + ".%Y%m%d.%H" if rollover-period < 1 day.

The following example configures System.err for a <a config-tag="host"/>. Unless a <a config-tag="web-app">web-app</a> overrides with it's own stderr-log, all web-apps in the host will write to the same output file.

<example> ... <host id='foo.com'>

 <stderr-log path='/var/log/foo/stderr.log'
             rollover-period='1W'/>
 ...

</host> ... </example>

</s2>

</s1>

<s1 title="Access logging"> <parents>server, host-default, host, web-app-default, web-app</parents>

Specify the access log file.

As a child of <a config-tag="web-app"/>, overrides the definition in the <a config-tag="host"/> that the web-app is deployed in. As a child of <a config-tag="host"/>, overrides the definition in the <a config-tag="server"/> that the host is in.

<deftable-childtags> <tr>

 <td>path</td>
 <td>Output path for the log entries, see 
       <a href="#path">"Log Paths"</a>.
 </td>
 <td>required</td>

</tr> <tr>

 <td>path-format</td>
 <td>Selects a format for generating path names.  The syntax is the same as for archive-format</td>
 <td>optional</td>

</tr> <tr><td>format

   </td><td>Access log format.
   </td><td>see below

</td></tr><tr><td>rollover-count

   </td><td>maximum number of rollover files before the oldest ones get overwritten.
       See <a href="#rollover">Rollovers</a>. 
   </td><td>none

</td></tr><tr><td>rollover-period

   </td><td>how often to rollover the log.  Specify in days (15D), weeks (2W), 
       months (1M), or hours (1h). See <a href="#rollover">Rollovers</a>. 
   </td><td>none

</td></tr><tr><td>rollover-size

   </td><td>maximum size of the file before a rollover occurs, in bytes (50000), 
       kb (128kb), or megabytes (10mb).  
       See <a href="#rollover">Rollovers</a>.
   </td><td>1mb

</td></tr><tr><td>archive-format

   </td><td>the format for the archive filename when a rollover occurs,
       see <a href="#rollover">Rollovers</a>.
   </td><td>see below

</td></tr><tr><td>auto-flush

   </td><td>true to flush the memory buffer with each request
   </td><td>false

</td></tr><tr><td>resin:type

   </td><td>a class extending <a href="javadoc|com.caucho.server.log.AccessLog|"/>
       for custom logging
   </td><td>com.caucho.server.log.AccessLog

</td></tr><tr><td>init</td><td>bean-style initialization for the custom class</td><td>n/a </td></tr></deftable-childtags>

The default archive format is

  <var>path</var> + ".%Y%m%d" or
  <var>path</var> + ".%Y%m%d.%H" if rollover-period < 1 day.

<example> ... <host id=>

 <access-log path='log/access.log'>
   <rollover-period>2W</rollover-period>
 </access-log>
 ...

</host> ... </example>

The access log formatting variables follow the Apache variables:

<deftable> <tr><td>%b</td>

   <td>result content length</td></tr>

<tr><td>%D</td>

   <td>time taken to complete the request in microseconds (since 3.0.16)</td></tr>

<tr><td>%h</td>

   <td>remote IP addr</td></tr>

<tr><td>%{xxx}i</td>

   <td>request header xxx</td></tr>

<tr><td>%{xxx}o</td>

   <td>response header xxx</td></tr>

<tr><td>%{xxx}c</td>

   <td>cookie value xxx</td></tr>

<tr><td>%n</td>

   <td>request attribute</td></tr>

<tr><td>%r</td>

   <td>request URL</td></tr>

<tr><td>%s</td>

   <td>status code</td></tr>

<tr><td>%{xxx}t</td>

   <td>request date with optional time format string.</td></tr>

<tr><td>%T</td>

   <td>time taken to complete the request in seconds</td></tr>

<tr><td>%u</td>

   <td>remote user</td></tr>

<tr><td>%U</td>

   <td>request URI</td></tr>

</deftable>

The default format is:

<def> "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" </def>

resin:type allows for custom logging. Applications can extend a custom class from <a href="javadoc|com.caucho.http.log.AccessLog|"/>. <a href="ioc-bean.xtp">Bean-style initialization</a> can be used to set bean parameters in the custom class.

<example> ... <host id='foo.com'>

 <access-log resin:type='test.MyLog'>
            path='$server-root/foo/error.log'
            rollover-period='1W'>
   <init>
     <foo>bar</foo>
   </init>
 </access-log>
 ...

</host> ... </example>

</s1>

<s1 name="path" title="Log Paths">

path is used to configure a destination for the messages. Typically, access-log, stdout-log, and stderr-log are configured to go to files, and log is configured to go to a file or to stderr or stdout so that they show up on the console screen.

<deftable> <tr><th>Path</th><th>Result </th></tr><tr><td>filesystem path</td><td>output log entries to a file </td></tr><tr><td>stdout:</td><td>output log entries to stdout </td></tr><tr><td>stderr:</td><td>output log entries to stderr </td></tr></deftable>

<example title="Log messages to stdout">

 <log name="" level="all" path="stdout:"/>

</example>

You can use the <a href="config-el.xtp">Environment EL variables</a> as part of your filesystem path:

<example title="Filesystem path using Environment EL variables">

 <log name="" level="all" 
      path="log/debug-${server.id}.log"
      rollover-period="1h" rollover-count="1"/>

</example>

</s1>

<s1 name="rollover" title="Rollovers">

Log rollovers are a way to stop your log files from getting too large. When a rollover is triggered, the existing log file is renamed and a new file is started.

<s2 title="Size based rollover">

A size based rollover is triggered when the size of the file reaches a certain amount. The default Resin behaviour for log's is to rollover when the file size reaches 1mb.

rollover-size is used to specify the maximum size, and can be in bytes (50000), kilobytes (128kb), or megabytes (10mb). A value of -1 disables size based rollovers.

</s2>

<s2 title="Time based rollover">

A time based rollover is triggered when a certain period of time has passed since the last rollover. The default Resin behaviour is to perform no time based rollover, unless rollover-size has been disabled with a value of -1 in which case the default time period is 1 month.

rollover-period is used to specify the time period, and can be in days (15D), weeks (2W), months (1M), or hours (1h).

</s2>

<s2 title="Archive files">

When a rollover is triggered, the log file is renamed (archived) and a new log file is started.

archive-format is used to specify the name of the archive file. It can contain regular characters, <a href="el-var.xtp">EL Environment variables</a>, and % codes that capture the current date and time. The % codes are the same as the ones used for timestamp (see <a href="#timestamp">Timestamp format string)</a>.

The default behaviour depends on the value of rollover-period. If rollover-period is greater than one day, or is not being used because rollover-size has been specified, the archive filename is the original path with .%Y%m%d appended. If rollover-period is less than one day, the archive filename is the original path with .%Y%m%d.%H appended.

</s2>

<s2 title="Disabling rollovers">

To completely disable rollovers, set the rollover-size to such a high number that it will never occur:

<example title="disable log rollovers">

 <stdout-log path="log//stdout.log" rollover-size="1024mb"/>

</example>

</s2>

<s2 title="Compression">

Rollover log files can be compressed with gzip or zip. The extension of the archive-format determines the compression.

<example> <log name="" level="warning" path='log/error.log'

    archive-format="%Y-%m-%d.error.log.gz"
    rollover-period="1D"/>

<access-log path="log/access.log"

           archive-format="access-%Y%m%d.log.gz"
           rollover-period="1D"/>

</example>

</s2>

</s1>

<s1 name="timestamp" title="Timestamp format string">

The timestamp for log tags is a format string which can contain percent codes which are substituted with time and date values.

<deftable> <tr><th>Code</th><th>Meaning </th></tr><tr><td>%a</td><td>day of week (short) </td></tr><tr><td>%A</td><td>day of week (verbose) </td></tr><tr><td>%b</td><td>day of month (short) </td></tr><tr><td>%B</td><td>day of month (verbose) </td></tr><tr><td>%c</td><td>Java locale date </td></tr><tr><td>%d</td><td>day of month (two-digit) </td></tr><tr><td>%H</td><td>24-hour (two-digit) </td></tr><tr><td>%I</td><td>12-hour (two-digit) </td></tr><tr><td>%j</td><td>day of year (three-digit) </td></tr><tr><td>%m</td><td>month (two-digit) </td></tr><tr><td>%M</td><td>minutes </td></tr><tr><td>%p</td><td>am/pm </td></tr><tr><td>%S</td><td>seconds </td></tr><tr><td>%s</td><td>milliseconds </td></tr><tr><td>%W</td><td>week in year (three-digit) </td></tr><tr><td>%w</td><td>day of week (one-digit) </td></tr><tr><td>%y</td><td>year (two-digit) </td></tr><tr><td>%Y</td><td>year (four-digit) </td></tr><tr><td>%Z</td><td>time zone (name) </td></tr><tr><td>%z</td><td>time zone (+/-0800) </td></tr></deftable>


<example title="Example: typical timestamp for the log tag"> <resin xmlns="http://caucho.com/ns/resin">

 <log-handler name= path='stderr:' timestamp="[%H:%M:%S.%s]"/>
 ...

</resin> </example>

<results> [22:50:11.648] WebApp[/doc] starting [22:50:11.698] http listening to *:8080 [22:50:11.828] hmux listening to *:6800 </results>

</s1>

</body> </document>

Personal tools