PATH |
- Inherits from:
- Object
- Package:
- com.webobjects.foundation
NSLog is a static class that you use to access the WebObjects Foundation logging system. It allows you to log debugging messages, and provides functionality for controlling the level and focus of debugging output. Logging with NSLog offers greater flexibility and integration with the WebObjects runtime and debugging system than does logging with System.out, System.err, or java.rmi.server.LogStream.
By specifying debug groups and the debug level using NSLog's methods, you can control the scope and granularity of debugging output. Perhaps you are only interested in seeing debugging output that relates to the Enterprise Objects Framework, or more specifically, debugging output that relates to database fetches. NSLog is designed to allow you to specify the output you want to see, based on predefined debug groups and levels. See the section on "Creating Custom Debug Groups" (page 128) to understand how NSLog uses a bit mask to specify sets of debug groups.
Although NSLog provides functionality for advanced debugging, it is also as simple to use as outputting to System.out.*: NSLog.out.appendln("WebObjects");
The above code outputs "WebObjects" in the console by default, but output can be directed to custom NSLog.Loggers.
The logging system is made up of three classes: NSLog, NSLog.Logger, and NSLog.PrintStreamLogger. NSLog provides methods for controlling the level (amount of information sent to the logger) and focus (scope of the information sent to the logger) of debugging output. NSLog.Logger is an abstract class that provides the basic functionality for NSLog. NSLog.PrintStreamLogger is a subclass of NSLog.Logger and appends information to the debug logger which is directed to a java.io.PrintStream pointing to System.out, System.err, or to a custom java.io.PrintStream.
The NSLog class cannot be instantiated.
The Foundation logging system offers the ability to create custom logging implementations, and to redirect their output to custom java.io.PrintStreams, such as local files. This example illustrates these features of the logging system, and directs output to a custom java.io.PrintStream, the local file "/Local/Users/log.txt":
// Output defaults to System.out. NSLog.PrintStreamLogger aLogger = new NSLog.PrintStreamLogger(); // New print stream based on path. PrintStream aStream = NSLog.printStreamForPath ("/Local/Users/log.txt"); // Direct output to the custom PrintStream. aLogger.setPrintStream (aStream); // Assign the custom PrintStreamLogger to the declared instances of NSLogger in NSLog. NSLog.setOut(aLogger); NSLog.setErr(aLogger); NSLog.setDebug(aLogger); // Enable verbose logging. aLogger.setIsVerbose (true); String str = "WebObjects"; // Outputs "[2000-10-18 09:01:00 GMT] <main> WebObjects" aLogger.appendln (str); // Disables logging. aLogger.setIsEnabled (false); // Outputs nothing, since logging is disabled. daLogger.appendln (str);
By subclassing NSLog.Logger instead of NSLog.PrintStreamLogger, you can provide custom logging implementations that are not based on java.io.PrintStreams, such as outputting to email, Swing windows, etc. See the documentation for "NSLog.Logger" (page 139) for more details.
To control the scope of the debug information that is sent to the logger, NSLog declares a number of debug groups, which are listed in the "Constants" (page 129) section. By default, logging is enabled for all the debug groups declared by NSLog. All the WebObjects frameworks, including Foundation and EOF, use NSLog for debugging, and rely on debug groups to control the scope of their debug logging.
As an example, this code uses debug groups to disable logging for debug information related to the Enterprise Objects Framework:
NSLog.refuseDebugLoggingForGroups(NSLog.DebugGroupEnterpriseObjects)
Before sending debug information to the logger, all classes that log EOF-related debug information check to see if debug logging is allowed for EOF-related issues using one of the debugLoggingAllowedFor... methods. Since the above code removed the DebugGroupEnterpriseObjects bit from the bit mask, EOF-related issues won't be sent to the logger.
To control the granularity of debug information that is sent to the logger, NSLog declares a number of debug levels, which are listed in the "Constants" (page 129) section. A debug level specifies the importance of the information displayed in a message. These messages may be the result of exceptions or errors, but may also just be informational, such as printing variable values.
When an exception is encountered, debug information should only be sent to the logger if the debug level is DebugLevelCritical or greater. If the debug level is set to DebugLevelOff, any error message in the catch block should not be sent to the logger. A simple example:
} catch (SomeException e) { if (NSLog.debugLoggingAllowedForLevel(DebugLevelCritical) { NSLog.debug.appendln("Exception encountered: " + e.getMessage()); NSLog.debug.appendln(e); } }
When you want to see the value of a variable at particular points in your application, you use DebugLevelInformational to control logging. Logging the values of variables can be expensive, so it is prudent to wrap this kind of logging in a debug level conditional. For instance, you should conditionalize the logging of values in an array like this:
// Assuming declaration of int[] anArray = new int[10]; if debugLoggingAllowedForLevel(DebugLevelInformational) { for (i = 0, i < 9, i++) { NSLog.out.appendln(anArray[i]); } }
DebugLevelDetailed should be used to conditionalize logging for computationally intensive tasks, such as JDBC function calls.
Note that if you specify the allowed debug level using the setAllowedDebugLevel method, messsages of that level and lower will be logged. That is, DebugLevelDetailed will also log messages of level DebugLevelInformational and messages of level DebugLevelCritical. Likewise, DebugLevelInformational will also log messages of level DebugLevelCritical, but not messages of level DebugLevelDetailed.
NSLog uses a bit mask to specify a set of debug groups, which means that you can easily create a custom debug groups mask for more flexible logging. For instance, if you are interested in logging debugging output only for EOF-related issues and EOModel-related issues, you can simply bitwise inclusive OR the groups together using the "|" operator in Java. That creates a debug groups mask which you can use to more flexibly monitor and log errors relating to those two issues. To do this:
// First, remove all debug groups from the mask, since they are all enabled by default. NSLog.refuseDebugLoggingForGroupsMask(~0); // Create a custom debug groups mask. NSLog.allowDebugLoggingForGroupsMask (DebugGroupEnterpriseObjects | DebugGroupModel);
In addition to the debug groups provied for you by WebObject, you can add your own debug groups. The high 32 bits (i.e. bits 32 - 63) are available to developers. The low bits are reserved by WebObjects. An example of declaring a new debug group:
public static final long DebugGroupCustomGroup = 1 << 32;
You can enable debug groups and levels from the command line. For example:
% cd MyJavaWOApp.woa % ./MyJavaWOApp -DNSDebugLevel=2 -DNSDebugGroups=32
The above code enables DebugLevelInformational and DebugGroupResources. The argument for debug level is passed in as an int; for debug groups, the argument is passed in as a long. Therefore, you must calculate the long value for each debug group you pass on the command line (in order to get the bit position for each group).
To do this, calculate 2 ^ (value for the debug group as listed in the "Constants" (page 129) section). For example, to enable DebugGroupWebObjects, calculate 2 ^ 2, and pass the result as the argument on the command line.
You can enable multiple debug groups by summing the long values of each group. For example:
% ./MyJavaWOApp -DNSDebugLevel=2 -DNSDebugGroups=16 + 32 + 1024
The above code enables DebugGroupMultithreading. DebugGroupResources, and DebugGroupFormatting.
NSLog defines the following constants:
- Setting the debug groups mask
- setAllowedDebugGroups
- Setting and retrieving the debug level
- setAllowedDebugLevel
- allowedDebugLevel
- Adding and removing debug groups to the mask
- allowDebugLoggingForGroups
- refuseDebugLoggingForGroups
- Determining if debug logging is enabled for a particular debug group or groups mask
- debugLoggingAllowedForLevel
- debugLoggingAllowedForGroups
- debugLoggingAllowedForLevelAndGroups
- Redirecting output to custom PrintStreams
- setDebug
- setErr
- setOut
- Convenience methods
- printStreamForPath
- throwableAsString
public static synchronized void allowDebugLoggingForGroups( long debugGroups)
NSLog.allowDebugLoggingForGroups(DebugGroupEnterpriseObjects);
This differs from setAllowedDebugGroups in that allowDebugLoggingForGroups adds debug groups and debug groups masks to the bit mask in NSLog. setAllowedDebugGroups, however, replaces the bit mask in NSLog with the debug group or debug groups mask it is passed. For example,
// This will add the EOF debug group to the mask: NSLog.allowDebugLoggingForGroups(DebugGroupEnterpriseObjects); // This will replace all debug groups and masks in the bit mask with the EOF debug group NSLog.setAllowedDebugGroups(DebugGroupEnterpriseObjects);
Use the refuseDebugLoggingForGroups method to disallow specific debug groups.
By default, logging is allowed for all debug groups. If you set the debug level to be low (for example, DEBUG_LEVEL-DETAILED), the debugging output may be overwhelming.
See "Creating Custom Debug Groups" (page 128) for more information.public static int allowedDebugLevel()
public static boolean debugLoggingAllowedForLevel(int aDebugLevel)
true
if debug logging is allowed for aDebugLevel. Debug logging is allowed if aDebuglevel is less than or equal to the debug level set by setAllowedDebugLevel. This is because the highest debug level, DebugLevelDetailed, implies DebugLevelInformational which implies DebugLevelCritical. See the "Debug Levels" (page 127) for more information.
public static boolean debugLoggingAllowedForGroups(long debugGroups)
true
if the debug groups specified by debugGroups are enabled (that is, the debug groups are part of the debug groups bit mask). See the "Creating Custom Debug Groups" (page 128) for code examples.
public static boolean debugLoggingAllowedForLevelAndGroups( int aDebugLevel, long debugGroups)
true
if the debug groups specified by debugGroups are enabled, and if the debug level is less than or equal to the debug level set by setAllowedDebugLevel.
public static java.io.PrintStream printStreamForPath(String aPath)
public static synchronized void refuseDebugLoggingForGroups( long debugGroups)
By default, logging is allowed for all debug groups. If you set the debug level to be low (for example, DEBUG_LEVEL-DETAILED), the debugging output may be overwhelming.
See allowDebugLoggingForGroups for more information.public static void setAllowedDebugGroups( long debugGroups)
Note: This method completely overrides the global debug groups mask, and affects logging behavior in the entire application. It is suggested that you only use it once at the beginning of application execution. |
By default, logging is allowed for all debug groups. If you set the debug level to be low (for example, DEBUG_LEVEL-DETAILED), the debugging output may be overwhelming.
See allowDebugLoggingForGroups for an explanation of when to use that method or setAllowedDebugGroups.
public static void setAllowedDebugLevel(int aDebugLevel)
By default, logging is allowed for all debug groups. If you set the debug level to be low (for example, DEBUG_LEVEL-DETAILED), the debugging output may be overwhelming.
See the "Constants" section in this document for a list of predefined debug levels.public static void setDebug(NSLog.Logger aLogger)
public static void setErr(NSLog.Logger aLogger)
public static void setOut(NSLog.Logger aLogger)
public static String throwableAsString(Throwable aThrowable)
© 2001 Apple Computer, Inc. (Last Published April 17, 2001)