4 Filtering WebLogic Server Log Messages

WebLogic logging services provide several filtering options that give you the flexibility to determine which messages are written to WebLogic Server log files and standard out, and which are written to the log file and standard out that a client JVM maintains. Most of these filtering features are implementations of the Java Logging APIs, which are available in the java.util.logging package.

The following sections describe how to filter messages that the WebLogic logging services generate:

For related information, see:

The Role of Logger and Handler Objects

When WebLogic Server message catalogs and the NonCatalogLogger generate messages, they distribute their messages to a java.util.logging.Logger object. The Logger object publishes the messages to any message handler that has subscribed to the Logger.

WebLogic Server instantiates Logger and Handler objects in three distinct contexts (See Figure 4-1):

  • In client JVMs that use WebLogic logging services. This client Logger object publishes messages that are sent from client applications running in the client JVM.

    The following handlers subscribe to the Logger object in a client JVM:

    • ConsoleHandler, which prints messages from the client JVM to the client's standard out.

      If you use the -Dweblogic.log.StdoutSeverityLevel Java startup option for the client JVM, WebLogic logging services create a filter for this handler that limits the messages that the handler writes to standard out. See "Writing Messages from a Client Application" in Oracle Fusion Middleware Using Logging Services for Application Logging for Oracle WebLogic Server.

    • FileStreamHandler, which writes messages from the client JVM to the client's log file.

  • In each instance of WebLogic Server. This server Logger object publishes messages that are sent from subsystems and applications that run on a server instance.

    The following handlers subscribe to the server Logger object:

    • ConsoleHandler, which makes messages available to the server's standard out.

    • FileStreamHandler, which writes messages to the server log file.

    • An internal handler, which broadcasts messages to the domain log and JMX clients, and publishes messages to the Administration Server.

  • The Administration Server maintains a domain Logger object in addition to a server Logger object. The domain Logger object receives messages from each Managed Server's Logger object.

    The following handler subscribes to the domain Logger object:

    • FileStreamHandler, which writes messages to the domain log file.

Figure 4-1 WebLogic Logging Services Contexts

Description of Figure 4-1 follows
Description of "Figure 4-1 WebLogic Logging Services Contexts"

Filtering Messages by Severity Level or Other Criteria

When WebLogic Server message catalogs and the NonCatalogLogger generate messages, they convert the message severity to a weblogic.logging.WLLevel object. A WLLevel object can specify any of the following values, from lowest to highest impact:

TRACE, DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY

By default, a Logger object publishes messages of all levels. To set the lowest-level message that a Logger object publishes, you use a simple Logger.setLevel API. When a Logger object receives an incoming message, it checks the message level with the level set by the setLevel API. If the message level is below the Logger level, it returns immediately. If the message level is above the Logger level, the Logger allocates a WLLogRecord object to describe the message.

For example, if you set a Logger object level to WARNING, the Logger object publishes only WARNING, ERROR, CRITICAL, ALERT, or EMERGENCY messages.

To provide more control over the messages that a Logger object publishes, you can also create and set a filter. A filter is a class that compares data in the WLLogRecord object with a set of criteria. The Logger object publishes only the WLLogRecord objects that satisfy the filter criteria. For example, a filter can configure a Logger to publish only messages from the JDBC subsystem. To create a filter, you instantiate a java.util.logging.Filter object and use the Logger.setFilter API to set it for a Logger object.

Instead of (or in addition to) setting the level and a filter for the messages that a Logger object publishes, you can set the level and filters on individual message handlers.

For example, you can specify that a Logger publishes messages that are of the WARNING level or higher. Then you can do the following for each handler:

  • For the ConsoleHandler, set a level and filter that selects only ALERT messages from the JDBC, JMS, and EJB subsystems. This causes standard out to display only ALERT messages from the JDBC, JMS, and EJB subsystems.

  • For the FileStreamHandler, set no additional level or filter criteria. Because the Logger object has been configured to publish only messages of the WARNING level or higher, the log file will contain all messages from all subsystems that are of WARNING severity level or higher.

  • Publish all messages of WARNING severity level or higher to the domain-wide message log on the Administration Server.

Setting the Severity Level for Loggers and Handlers

The Administration Console and WLST provide a way to set the severity level for a Handler object through standard MBean commands. To set the Severity level for a Logger object, you can use the Logger API. You can also set the Severity level for a Logger via the Administrator Console, WLST, or the command line; see Specifying Severity Level for Loggers. To configure Logger and Handler severity level for WLS clients (such as EJB and Web Service clients), you must use the Java Logging API.

Setting the Level for Loggers

To set the severity level for a Logger object, create a class that does the following:

  1. Invokes one of the following LoggingHelper methods:

    • getClientLogger if the current context is a client JVM.

    • getServerLogger if the current context is a server JVM and you want to retrieve the Logger object that a server uses to manage its local server log.

    • getDomainLogger if the current context is the Administration Server and you want to retrieve the Logger object that manages the domain log.

    The LoggerHelper method returns a Logger object. See the Sun API documentation for Logger: at http://java.sun.com/javase/6/docs/api/java/util/logging/Logger.html.

  2. Invokes the Logger.setLevel(Level level) method.

    To set the level of a WebLogic Server Logger object, you must pass a value that is defined in the weblogic.logging.WLLevel class. WebLogic Server maps the java.util.logging.Level to the appropriate WLLevel. For a list of valid values, see the description of the weblogic.logging.WLLevel class in the Oracle Fusion Middleware Oracle WebLogic Server API Reference.

    For example:

    setLevel(WLLevel.ALERT) 
    

Setting the Level for Handlers

To set the severity level for a Handler object using the API, create a class that does the following (See Example 4-1):

  1. Invokes one of the following LoggingHelper methods:

    • getClientLogger if the current context is a client JVM.

    • getServerLogger if the current context is a server JVM and you want to retrieve the Logger object that a server uses to manage its local server log.

    • getDomainLogger if the current context is the Administration Server and you want to retrieve the Logger object that manages the domain log.

    The LoggerHelper method returns a Logger object. See the Sun API documentation for Logger at http://java.sun.com/javase/6/docs/api/java/util/logging/Logger.html.

  2. Invokes the Logger.getHandlers() method.

    The method returns an array of all handlers that are registered with the Logger object.

  3. Iterates through the list of handlers until it finds the Handler object for which you want to set a level.

    Use Handler.getClass().getName() to determine the type of handler to which the current array index refers.

  4. Invokes the Handler.setLevel(Level level) method.

    To set the level of a WebLogic Server Handler object, you must pass a value that is defined in the weblogic.logging.WLLevel class. WebLogic Server maps the java.util.logging.Level to the appropriate WLLevel. For a list of valid values, see the description of the weblogic.logging.WLLevel class in the Oracle Fusion Middleware Oracle WebLogic Server API Reference.

    For example:

    setLevel(WLLevel.ALERT) 
    

Example 4-1 Example: Setting Level for a Handler Object Using the API

import java.util.logging.Logger;
import java.util.logging.Handler;
import weblogic.logging.LoggingHelper;
import weblogic.logging.WLLevel;
public class LogLevel {
    public static void main(String[] argv) throws Exception {
        Logger serverlogger = LoggingHelper.getServerLogger();
        Handler[] handlerArray = serverlogger.getHandlers();
        for (int i=0; i < handlerArray.length; i++) {
            Handler h = handlerArray[i];
            if(h.getClass().getName().equals
                      ("weblogic.logging.ConsoleHandler")){
                h.setLevel(WLLevel.ALERT);
            }
        }
    }
}

You can configure the severity level for a Handler object through the LogMBean interface using the Administration Console or the command line:

  • See "Filter log messages" in the Oracle Fusion Middleware Oracle WebLogic Server Administration Console Help, for information on setting a severity level.

  • The WLST commands in Example 4-2 set the severity level for the Stdout Handler to INFO.

Example 4-2 Setting the Severity Level for the Stdout Handler

C:\>java weblogic.WLST
wls:/offline> connect('username','password')
wls:/mydomain/serverConfig> edit()
wls:/mydomain/edit> startEdit()
wls:/mydomain/edit !> cd("Servers/myserver/Log/myserver")
wls:/mydomain/edit/Servers/myserver/Log/myserver !> cmo.setStdoutSeverity("Info")
wls:/mydomain/edit/Servers/myserver/Log/myserver !> save()
wls:/mydomain/edit/Servers/myserver/Log/myserver !> activate()

For more information about using WLST, see "Using the WebLogic Scripting Tool" in Oracle Fusion Middleware Oracle WebLogic Scripting Tool. For more information about setStdoutSeverity, see LogMBean in the Oracle Fusion Middleware Oracle WebLogic Server MBean Reference.

Setting a Filter for Loggers and Handlers

When you set a filter on the Logger object, the filter specifies which messages the object publishes; therefore, the filter affects all handlers that are registered with the Logger object as well. When you set a filter on a handler, the filter affects only the behavior of the specific handler.

The Administration Console and WLST provide a way to set a filter on the Handler object through standard MBean commands. To set a filter on the Logger object, you must use the Logger API. For client-side logging, the only way to set a filter is through using the Java Logging API.

To set a filter:

  1. Create a class that implements java.util.logging.Filter. See Example 4-3.

    The class must include the Filter.isLoggable method and logic that evaluates incoming messages. If the logic evaluates as true, the isLoggable method enables the Logger object to publish the message.

  2. Place the filter object in the classpath of the JVM on which the Logger object is running.

  3. To set a filter for a Logger object, create a class that does the following:

    1. Invokes one of the following LoggingHelper methods:

    • getClientLogger if the current context is a client JVM.

    • getServerLogger if the current context is a server JVM and you want to filter the Logger object that a server uses to manage its local server log.

    • getDomainLogger if the current context is the Administration Server and you want to filter the Logger object that manages the domain server log.

    1. Invokes the Logger.setFilter(Filter newFilter) method.

  4. To set a filter for a Handler object using the API, create a class that does the following:

    1. Invokes one of the following LoggingHelper methods:

    • getClientLogger if the current context is a client JVM.

    • getServerLogger if the current context is a server JVM and you want to filter the Logger object that a server uses to manage its local server log.

    • getDomainLogger if the current context is the Administration Server and you want to filter the Logger object that manages the domain server log.

    1. Iterates through the list of handlers until it finds the Handler object for which you want to set a level.

      Use Handler.getClass().getName() to determine the type of handler to which the current array index refers.

    2. Invokes the Handler.setFilter(Filter newFilter) method.

Example 4-3 provides an example class that rejects all messages from the Deployer subsystem.

Example 4-3 Example Filter for a Java Logger Object

import java.util.logging.Logger;
import java.util.logging.Filter;
import java.util.logging.LogRecord;
import weblogic.logging.WLLogRecord;
import weblogic.logging.WLLevel;
public class MyFilter implements Filter {
    public boolean isLoggable(LogRecord record) {
        if (record instanceof WLLogRecord) {
            WLLogRecord rec = (WLLogRecord)record;
            if (rec.getLoggerName().equals("Deployer")) {
              return false;
            } else {
              return true;
            }
        } else {
          return false;
        }
    }
}

You can configure a filter for a Handler object through the LogMBean interface using the Administration Console or the command line:

  • See "Create log filters" for information on setting up a log filter for a WebLogic Server instance in the Oracle Fusion Middleware Oracle WebLogic Server Administration Console Help.

  • The WLST commands in Example 4-4 create and set a filter on the Domain Log Broadcaster.

Example 4-4 Setting up a Domain Log Filter

C:\>java weblogic.WLST
wls:/offline> connect('username','password')
wls:/mydomain/serverConfig> edit()
wls:/mydomain/edit> startEdit()
wls:/mydomain/edit !> cmo.createLogFilter('myFilter')
wls:/mydomain/edit !> cd("Servers/myserver/Log/myserver")
wls:/mydomain/edit/Servers/myserver/Log/myserver !> cmo.setDomainLogBroadcastFilter(getMBean('/LogFilters/myFilter'))
wls:/mydomain/edit/Servers/myserver/Log/myserver !> save()
wls:/mydomain/edit/Servers/myserver/Log/myserver !> activate()

For more information about using WLST, see "Using the WebLogic Scripting Tool" in Oracle Fusion Middleware Oracle WebLogic Scripting Tool. For more information about setDomainLogBroadcastFilter, see LogMBean in the Oracle Fusion Middleware Oracle WebLogic Server MBean Reference.

Filtering Domain Log Messages

To filter the messages that each Managed Server publishes to the domain log, you can use the Administration Console (see "Create log filters") or WLST (see Example 4-4) to create a log filter for the domain log.

Any Java Logging severity level or filter that you set on the Logger object that manages a server instance's log file supersedes a domain log filter. For example, if the level of the server Logger object is set to WARNING, a domain log filter will receive only messages of the WARNING level or higher.

You can define a domain log filter which modifies the set of messages that one or more servers send to the domain log. By default, all messages of severity NOTICE or higher are sent.

Note:

Messages of severity DEBUG are never sent to the domain log, even if you use a filter.

See "Filter log messages" in the Oracle Fusion Middleware Oracle WebLogic Server Administration Console Help, which describes configuring a domain log filter for a WebLogic Server instance using the Administration Console.

Setting a Severity Level and Filter on a Log4j Appender

The Administration Console and WLST provide a way to set the level for an Appender object through standard MBean commands. To set the level for a Logger object, you can use the Logger API as described in this section, or you can do so from the Administration Console, WLST, or the command line as described in Specifying Severity Level for Loggers.

To set the level for an Appender object using the API, create a class that does the following:

  1. Invokes the one of the following Log4jLoggingHelper methods (See Example 4-5).

    • getLog4jServerLogger if the current context is a server JVM and you want to retrieve the Logger object that a server uses to manage its local server log.

    • getLog4jDomainLogger if the current context is the Administration Server and you want to retrieve the Logger object that manages the domain log.

  2. Invokes the logger.getAllAppenders() method.

    Enumeration e = logger.getAllAppenders();
    

    The method returns all the appenders that are registered with the Logger object.

  3. Iterates through the list of appenders and gets each appender name.

  4. Invokes the app.setThreshold(WLLog4jLevel level) method.

    To set the level of a Log4j Appender object, you must pass a value that is defined in the weblogic.logging.log4j.WLLog4jLevel class. WebLogic Server maps the org.apache.log4j.Level to the appropriate WLLevel. For a list of valid values, see the description of the weblogic.logging.WLLevel class in the Oracle Fusion Middleware Oracle WebLogic Server API Reference.

To set a filter, implement a class that extends org.apache.log4j.Filter and adds the filter to the Appender, invoke the app.addFilter(Filter newFilter) method.

Example 4-5 provides an example class that does the following:

  • Publishes messages of the WARNING level or higher in the server log.

  • Publishes messages of the INFO level or higher to standard out.

  • Rejects INFO messages from the HTTP subsystem.

Example 4-5 Example: Setting a Log4j Level and Filter

package weblogic.logging.examples;
import java.util.Enumeration;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;
import weblogic.logging.LoggerNotAvailableException;
import weblogic.logging.NonCatalogLogger;
import weblogic.logging.Severities;
import weblogic.logging.log4j.AppenderNames;
import weblogic.logging.log4j.Log4jLoggingHelper;
import weblogic.logging.log4j.WLLog4jLevel;
import weblogic.logging.log4j.WLLog4jLogEvent;
/**
 * This class sets a level and filter on a Log4j Appender.
 */
public class Log4jFilterExamplesStartup {
  public static void main(String[] args) {
    try {
      System.out.println("Invoked the log4j filter example startup class");
      Logger logger = Log4jLoggingHelper.getLog4jServerLogger();
      Enumeration e = logger.getAllAppenders();
      while (e.hasMoreElements()) {
        AppenderSkeleton app = (AppenderSkeleton) e.nextElement();
        String name = app.getName();
        if (name == null) continue;
        if (name.equals(AppenderNames.LOG_FILE_APPENDER)) { 
          // Set the threshold level of messages going to the log file to WARNING
          // This will result in NOTICE, INFO, DEBUG, and TRACE messages being
          // suppressed from going to the server log file
          app.setThreshold(WLLog4jLevel.WARN);
          System.out.println("Set WARNING level on the log file appender");
        } else if (name.equals(AppenderNames.STDOUT_APPENDER)) {
          // Set level to INFO on the stdout filter
          app.setThreshold(WLLog4jLevel.INFO);
          // First clear the existing filters on the appender
          app.clearFilters();
          // Add a filter to block INFO messages from the HTTP subsystem
          app.addFilter(new MyFilter());
        } 
      }
      // Now test the filter
      NonCatalogLogger nc = new NonCatalogLogger("MyFilterTest");
      nc.info("INFO messages will not be published to the file but to stdout");
      nc.warning("WARNINFG messages will be published to the file and stdout"); 

    } catch(LoggerNotAvailableException lex) {
      System.err.println("Log4j logger is not available on this server
    }
  }
  /**
   * Deny messages from the HTTP subsystem of level INFO
   */
  private static class MyFilter extends Filter {
    public int decide(LoggingEvent event) {
      if (event instanceof WLLog4jLogEvent) {
        WLLog4jLogEvent wlsEvent = (WLLog4jLogEvent)event;
        if (wlsEvent.getSubsystem().equals("HTTP")
          && wlsEvent.getSeverity() == Severities.INFO) {
        return DENY;
      }
    }
    return ACCEPT;
  }
 }
}