opends/build.xml
@@ -100,6 +100,10 @@ <!-- Properties for the EMMA code coverage tool. --> <property name="emma.dir" location="${ext.dir}/emma/lib" /> <!-- Properties for the AspectJ tools --> <property name="aj.dir" location="${ext.dir}/aspectj" /> <property name="aj.lib.dir" location="${aj.dir}/lib" /> <!-- Properties for the TestNG unit testing tool. --> <property name="testng.dir" location="${ext.dir}/testng" /> <property name="testng.lib.dir" location="${testng.dir}/lib" /> @@ -183,12 +187,16 @@ <format property="timestamp" pattern="yyyyMMddHHmmss" /> </tstamp> <condition property="DEBUG_BUILD" value="false"> <condition property="DEBUG_BUILD" value="true"> <not> <isset property="DEBUG_BUILD" /> </not> </condition> <condition property="weave.enabled" value="true"> <equals arg1="${DEBUG_BUILD}" arg2="true" /> </condition> <condition property="MEM" value="128M"> <not> <isset property="MEM" /> @@ -367,7 +375,7 @@ <!-- Compile the Directory Server source files. --> <target name="cleancompile" depends="cleaninit,compile,compilequicksetup,compilestatuspanel" depends="cleaninit,weave,compilequicksetup,compilestatuspanel" description="Recompile the Directory Server source files."> </target> @@ -380,7 +388,7 @@ <javac srcdir="${src.dir}" destdir="${classes.dir}" optimize="true" excludes="**/package-info.java" debug="on" debuglevel="lines,source" source="1.5" target="1.5" debug="on" debuglevel="lines,vars,source" source="1.5" target="1.5" deprecation="true" fork="true" memoryInitialSize="${MEM}" memoryMaximumSize="${MEM}"> <compilerarg value="-Xlint:all" /> @@ -393,8 +401,27 @@ </javac> </target> <target name="weave" if="weave.enabled" depends="compile"> <taskdef resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties"> <classpath> <pathelement location="${aj.lib.dir}/aspectjtools.jar" /> </classpath> </taskdef> <iajc inpath="${classes.dir}" destdir="${classes.dir}" debug="true" debuglevel="lines,source" source="1.5" target="1.5" deprecation="true" fork="true" maxmem="${MEM}"> <classpath> <fileset dir="${lib.dir}"> <include name="*.jar" /> </fileset> </classpath> </iajc> </target> <!-- Compile the Quick Setup source files. --> <target name="compilequicksetup" depends="buildtools,compile" <target name="compilequicksetup" depends="buildtools,weave" description="Compile the Quick Setup source files."> <mkdir dir="${quicksetup.classes.dir}" /> @@ -780,7 +807,7 @@ <!-- Prepare to execute the Directory Server TestNG unit tests. --> <target name="testinit" depends="buildtools,compile" <target name="testinit" depends="buildtools,weave" description="Prepare to execute the Directory Server TestNG unit tests."> <!-- If we are to perform coverage tests, then set that up. --> @@ -994,6 +1021,19 @@ <echo message=" -Dtest.failed=true"/> <echo message=" runs only the tests that failed last time"/> <echo message=""/> <echo message=" -DDEBUG_BUILD=false" /> <echo message=" builds the server without the debug logging facility." /> <echo message=" No debug logging messages will be included on test failures." /> <echo message=""/> <echo message=" -Dtest.debug.target=org.opends.server.core:level=verbose,category=data_access"/> <echo message=" for example only include debug messages in the core"/> <echo message=" package that are related to data access and at the" /> <echo message=" verbose level or higher. The syntax of this target" /> <echo message=" definition is the same as the org.opends.server.debug.target.x" /> <echo message=" property when starting OpenDS. " /> <echo message=" Default debug target:"/> <echo message=" org.opends.server:level=verbose,category=caught|data|database_access|message|protocol" /> <echo message=""/> <echo message=" -Dtest.packages=org.opends.server.api"/> <echo message=" for example runs only the tests in the api package"/> <echo message=" For multiple packages, separate them with a ',' and "/> @@ -1047,7 +1087,16 @@ </not> </condition> <!-- Cleanout the old reports. Otherwise, the old testng-failed.xml <!-- This sets org.opends.test.debug.target if and only if its's not alreadly set. --> <condition property="org.opends.test.debug.target" value="org.opends.server:level=verbose,category=caught|data|database_access|message|protocol"> <not> <isset property="org.opends.test.debug.target" /> </not> </condition> <!-- Cleanout the old reports. Otherwise, the old testng-failed.xml will hang around even if all of the tests pass. --> <delete> <fileset dir="${unittest.report.dir}" includes="*"/> @@ -1084,6 +1133,7 @@ <jvmarg value="-Demma.coverage.out.merge=false" /> <jvmarg value="-Dorg.opends.server.BuildRoot=${basedir}" /> <jvmarg value="-Dorg.opends.test.suppressOutput=${org.opends.test.suppressOutput}" /> <jvmarg value="-Dorg.opends.test.debug.target=${org.opends.test.debug.target}" /> <jvmarg value="-Xms${MEM}" /> <jvmarg value="-Xmx${MEM}" /> <xmlfileset dir="${unittest.resource.dir}" includes="testng.xml" /> opends/src/server/org/opends/server/api/DirectoryThread.java
@@ -34,6 +34,8 @@ import static org.opends.server.util.ServerConstants.*; import static org.opends.server.util.StaticUtils.*; import java.util.Map; import java.util.LinkedHashMap; /** @@ -211,5 +213,24 @@ { this.task = task; } /** * Retrieves any relevent debug information with which this tread is * associated so they can be included in debug messages. * * @return debug information about this thread as a string. */ public Map<String, String> getDebugProperties() { LinkedHashMap<String, String> properties = new LinkedHashMap<String, String>(); properties.put("parentThread", parentThread.getName() + "(" + parentThread.getId() + ")"); properties.put("isDaemon", String.valueOf(this.isDaemon())); return properties; } } opends/src/server/org/opends/server/api/LogPublisher.java
@@ -27,7 +27,7 @@ package org.opends.server.api; import org.opends.server.loggers.LogRecord; import org.opends.server.loggers.LogErrorHandler; import org.opends.server.loggers.LoggerErrorHandler; /** * LogPublishers are reponsible for distributing logged messages from @@ -45,7 +45,7 @@ * @param record the log record to publish. * @param handler the error handler to use when an error occurs. */ public void publish(LogRecord record, LogErrorHandler handler); public void publish(LogRecord record, LoggerErrorHandler handler); /** * Releases any resources and prepare for close. opends/src/server/org/opends/server/backends/task/TaskThread.java
@@ -38,6 +38,7 @@ import static org.opends.server.messages.MessageHandler.*; import static org.opends.server.util.StaticUtils.*; import java.util.Map; /** @@ -223,5 +224,19 @@ taskScheduler.threadDone(this, task); } } /** * Retrieves any relevent debug information with which this tread is * associated so they can be included in debug messages. * * @return debug information about this thread as a string. */ public Map<String, String> getDebugProperties() { Map<String, String> properties = super.getDebugProperties(); properties.put("task", task.toString()); return properties; } } opends/src/server/org/opends/server/extensions/TraditionalWorkerThread.java
@@ -47,6 +47,7 @@ import static org.opends.server.messages.MessageHandler.*; import static org.opends.server.util.StaticUtils.*; import java.util.Map; /** @@ -310,5 +311,21 @@ } } } /** * Retrieves any relevent debug information with which this tread is * associated so they can be included in debug messages. * * @return debug information about this thread as a string. */ public Map<String, String> getDebugProperties() { Map<String, String> properties = super.getDebugProperties(); properties.put("clientConnection", operation.getClientConnection().toString()); properties.put("operation", operation.toString()); return properties; } } opends/src/server/org/opends/server/loggers/AsyncronousLogPublisher.java
@@ -61,9 +61,9 @@ private static class PublishRequest { public final LogRecord record; public final LogErrorHandler handler; public final LoggerErrorHandler handler; PublishRequest(LogRecord record, LogErrorHandler handler) PublishRequest(LogRecord record, LoggerErrorHandler handler) { this.record = record; this.handler = handler; @@ -129,7 +129,7 @@ catch (Throwable t) { // Forward exception to error handler if (request != null && request.handler != null) { LogErrorHandler handler= request.handler; LoggerErrorHandler handler= request.handler; handler.handleError(request.record, t); } } @@ -141,7 +141,7 @@ // want shutdown to start after we check for it, but before we queue // request. private synchronized void publishAsynchronously(LogRecord record, LogErrorHandler handler) LoggerErrorHandler handler) { // If shutting down reject, otherwise publish (if we have a publisher!) if (isShuttingDown()) { @@ -167,7 +167,7 @@ * @param record the log record to publish. * @param handler the error handler to use if an error occurs. */ public void publish(LogRecord record, LogErrorHandler handler) public void publish(LogRecord record, LoggerErrorHandler handler) { // No publisher? Off to the bit bucket. if (publisher != null) { opends/src/server/org/opends/server/loggers/LogCategory.java
@@ -26,12 +26,17 @@ */ package org.opends.server.loggers; import java.util.ArrayList; /** * The category class defines a set of standard logging types that * can be used to control logging output. */ public abstract class LogCategory public class LogCategory { private static ArrayList<LogCategory> known = new ArrayList<LogCategory>(); /** * The non-localized name of the type. */ @@ -42,13 +47,15 @@ * <p> * Note that this constructor is "protected" to allow subclassing. * * @param name the name of the Level, for example "SEVERE". * @param name the name of the category, for example "MESSAGE". */ protected LogCategory(String name) { if (name == null) { throw new NullPointerException(); } this.name = name; known.add(this); } /** @@ -63,9 +70,42 @@ /** * Retrieves the string reprentation of this log category. * * @return the non-localized name of the Level, for example "INFO". * @return the non-localized name of the LogCategory, for example "ENTRY". */ public final String toString() { return name; } /** * Parse a category name string into a LogCategory. * <p> * For example: * <ul> * <li> "EXIT" * <li> "caught" * </ul> * @param name string to be parsed * @throws IllegalArgumentException if the value is not valid. * Known names are the categories defined by this class or created * by this class with appropriate package access, or new levels defined * or created by subclasses. * * @return The parsed category */ public static synchronized LogCategory parse(String name) throws IllegalArgumentException { // Check that name is not null. name.length(); // Look for a known Level with the given name. for (int i = 0; i < known.size(); i++) { LogCategory c = known.get(i); if (name.equalsIgnoreCase(c.name)) { return c; } } // OK, we've tried everything and failed throw new IllegalArgumentException("Bad category \"" + name + "\""); } } opends/src/server/org/opends/server/loggers/LogLevel.java
@@ -119,7 +119,7 @@ } /** * Parse a level name string into a Level. * Parse a level name string into a LogLevel. * <p> * The argument string may consist of either a level name * or an integer value. opends/src/server/org/opends/server/loggers/Logger.java
@@ -28,8 +28,7 @@ import org.opends.server.api.LogPublisher; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.ReentrantLock; import java.util.List; /** * A Logger is the entry point into a message distribution @@ -37,37 +36,36 @@ * filters out undesired messages using a RecordFilter, and * sends them to a LogPublisher for further distribution. * Any logging exceptions encountered will be sent to a * LoggingErrorHandler. * LoggerErrorHandler. */ public abstract class Logger { /** * Whether the debug logger is enabled or disabled. */ protected boolean enabled; /** * The logging error handler. */ protected LogErrorHandler handler; protected LoggerErrorHandler handler; /** * The set of publishers. */ protected CopyOnWriteArrayList<LogPublisher> publishers; /** * A mutex that will be used to provide threadsafe access to methods * changing the set of defined publishers. */ protected ReentrantLock publisherMutex; protected List<LogPublisher> publishers; /** * Construct a new logger object. * * @param handler the error handler to use when an error occurs. * @param config the logger configuration to use when construting the new * logger object. */ protected Logger(LogErrorHandler handler) protected Logger(LoggerConfiguration config) { this.publishers = new CopyOnWriteArrayList<LogPublisher>(); this.publisherMutex = new ReentrantLock(); this.handler = handler; this.enabled = config.getEnabled(); this.publishers = config.getPublishers(); this.handler = config.getErrorHandler(); } /** @@ -75,7 +73,7 @@ * * @param record The log record to publish. */ protected void publishRecord(LogRecord record) public void publishRecord(LogRecord record) { for(LogPublisher p : publishers) { @@ -84,97 +82,36 @@ } /** * Adds a new publisher to which log records should be sent. * Update this logger with the provided configuration. * * @param publisher The publisher to which records should be sent. * @param config the new configuration to use for this logger. */ protected void addPublisher(LogPublisher publisher) protected void updateConfiguration(LoggerConfiguration config) { publisherMutex.lock(); try boolean newEnabled = config.getEnabled(); if(enabled && !newEnabled) { for (LogPublisher p : publishers) //it is now disabled. Close all publishers if any. for(LogPublisher publisher : publishers) { if (p.equals(publisher)) publisher.shutdown(); publishers.remove(publisher); } } if(newEnabled) { List<LogPublisher> newPublishers = config.getPublishers(); for(LogPublisher oldPublisher : publishers) { if(!newPublishers.contains(oldPublisher)) { return; //A publisher was removed. Make sure to close it before removing it. oldPublisher.shutdown(); } } publishers.add(publisher); } catch (Exception e) { // This should never happen. e.printStackTrace(); } finally { publisherMutex.unlock(); } } /** * Removes the provided publisher so records will no longer be sent to it. * * @param publisher The publisher to remove. */ protected void removePublisher(LogPublisher publisher) { publisherMutex.lock(); try { publishers.remove(publisher); } catch (Exception e) { // This should never happen. e.printStackTrace(); } finally { publisherMutex.unlock(); } } /** * Removes all publishers so records are not sent anywhere. * * @param closePublishers whether to close the publishers when removing them. */ protected void removeAllPublishers(boolean closePublishers) { publisherMutex.lock(); try { if(closePublishers) { LogPublisher[] pubs = new LogPublisher[publishers.size()]; publishers.toArray(pubs); publishers.clear(); for(LogPublisher pub : pubs) { pub.shutdown(); } } else { publishers.clear(); } } catch(Exception e) { // This should never happen. e.printStackTrace(); } finally { publisherMutex.unlock(); this.publishers = config.getPublishers(); this.handler = config.getErrorHandler(); } } } opends/src/server/org/opends/server/loggers/LoggerConfiguration.java
New file @@ -0,0 +1,274 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Portions Copyright 2006-2007 Sun Microsystems, Inc. */ package org.opends.server.loggers; import org.opends.server.api.LogPublisher; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.CopyOnWriteArrayList; import java.util.*; /** * A LoggerConfiguration encapsulates the information defining an * abstract log messaging system. A LoggerConfiguration maintains at * least three things: * <ul> * <li>a destination to send log messages to (a LogPublisher).</li> * <li>an optional filter used to restrict the log messages sent * (a RecordFilter).</li> * <li>an error handler to be notified in the case of any logging * exceptions (a LoggerErrorHandler).</li> * </ul> * * A Logger will use this information to initialize the log messaging * system. Additionally, a Logger will register with the LoggerConfiguration * object it used to allow the LoggerConfiguration to provide a single * point of configuration management. On configuration changes, registered * Loggers will be notified. * */ public class LoggerConfiguration { /** * Whether the debug logger is enabled or disabled. */ protected boolean enabled; /** The log destination for this configuration. */ protected CopyOnWriteArrayList<LogPublisher> publishers; /** * A mutex that will be used to provide threadsafe access to methods * changing the set of defined publishers. */ protected ReentrantLock publisherMutex; /** * The logging error handler. */ protected LoggerErrorHandler handler; /** The record filter for this configuration. */ //protected RecordFilter _filter; /** The loggers that need notification of configuration changes. */ protected Set<Logger> loggers; /** * Creates a LoggerConfiguration describing an disabled logging system. * * @param handler the error handler to use for the logger configured by this * configuration. */ public LoggerConfiguration(LoggerErrorHandler handler) { this.enabled = false; this.publishers = new CopyOnWriteArrayList<LogPublisher>(); this.publisherMutex = new ReentrantLock(); this.handler = handler; this.loggers = new HashSet<Logger>(); } /** * Enable or disable the debug logger. * * @param enable if the debug logger should be enabled. */ public void setEnabled(boolean enable) { this.enabled = enable; } /** * Obtain the status of this logger singleton. * * @return the status of this logger. */ public boolean getEnabled() { return enabled; } /** * Adds a new publisher to which log records should be sent. * * @param publisher The publisher to which records should be sent. */ public void addPublisher(LogPublisher publisher) { publisherMutex.lock(); try { for (LogPublisher p : publishers) { if (p.equals(publisher)) { return; } } publishers.add(publisher); } catch (Exception e) { // This should never happen. e.printStackTrace(); } finally { publisherMutex.unlock(); } } /** * Removes the provided publisher so records will no longer be sent to it. * * @param publisher The publisher to remove. */ public void removePublisher(LogPublisher publisher) { publisherMutex.lock(); try { publishers.remove(publisher); } catch (Exception e) { // This should never happen. e.printStackTrace(); } finally { publisherMutex.unlock(); } } /** * Removes all publishers so records are not sent anywhere. * * @param closePublishers whether to close the publishers when removing them. */ public void removeAllPublishers(boolean closePublishers) { publisherMutex.lock(); try { if(closePublishers) { LogPublisher[] pubs = new LogPublisher[publishers.size()]; publishers.toArray(pubs); publishers.clear(); for(LogPublisher pub : pubs) { pub.shutdown(); } } else { publishers.clear(); } } catch(Exception e) { // This should never happen. e.printStackTrace(); } finally { publisherMutex.unlock(); } } /** * Retrieves the set of publishers included in this configuration. * * @return the set of publishers included in this configuration. */ public List<LogPublisher> getPublishers() { return Collections.unmodifiableList(publishers); } /** * Retrieves the error handler included in this configuration. * * @return the error handler used by this configuration. */ public LoggerErrorHandler getErrorHandler() { return handler; } /** * Set an error handler for this configuration. * * @param handler the error handler to set for this configuration. */ public void setErrorHandler(LoggerErrorHandler handler) { this.handler= handler; notifyLoggers(); } /** * Request that a logger be notified of configuration changes. * * @param logger - The Logger interested in configuration change * notifications. */ public synchronized void registerLogger(Logger logger) { loggers.add(logger); } /** * Request that a logger no longer be notifed of configuration changes. * * @param logger - The Logger no longer interested in configuration change * notifications. */ public synchronized void deregisterLogger(Logger logger) { loggers.remove(logger); } /** * Notify all registered loggers that the configuration has changed. */ protected synchronized void notifyLoggers() { for(Logger logger : loggers) { logger.updateConfiguration(this); } } } opends/src/server/org/opends/server/loggers/LoggerErrorHandler.java
File was renamed from opends/src/server/org/opends/server/loggers/LogErrorHandler.java @@ -27,13 +27,13 @@ package org.opends.server.loggers; /** * A LoggingErrorHandler is used for notification of exceptions which * A LoggerErrorHandler is used for notification of exceptions which * occur during the publishing of a record. * * The advantage of using a handler is that we can handle exceptions * asynchronously (useful when dealing with an AsynchronousPublisher). */ public interface LogErrorHandler public interface LoggerErrorHandler { /** * Handle an exception which occurred during the publishing opends/src/server/org/opends/server/loggers/TextLogPublisher.java
@@ -56,7 +56,8 @@ * @param record the log record to publish. * @param handler the error handler to use if an error occurs. */ public void publish(LogRecord record, LogErrorHandler handler) public synchronized void publish(LogRecord record, LoggerErrorHandler handler) { try { opends/src/server/org/opends/server/loggers/debug/DebugConfiguration.java
New file @@ -0,0 +1,274 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Portions Copyright 2006-2007 Sun Microsystems, Inc. */ package org.opends.server.loggers.debug; import org.opends.server.loggers.*; import org.opends.server.util.DynamicConstants; import org.opends.server.types.DebugLogLevel; import static org.opends.server.util.ServerConstants.PROPERTY_DEBUG_ENABLED; import static org.opends.server.util.ServerConstants.PROPERTY_DEBUG_TARGET; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.TreeMap; /** * A LoggingConfiguration for the debug logging system. */ public class DebugConfiguration extends LoggerConfiguration { private static final String GLOBAL= "_global"; private Map<String, TraceSettings> classTraceSettings; private Map<String, Map<String, TraceSettings>> methodTraceSettings; /** * Error handler for tracing. Tracing will be disabled * if too many errors occur. */ private class DebugErrorHandler implements LoggerErrorHandler { private static final int ERROR_THRESHOLD= 10; private int _loggingErrors= 0; /** * Error handler for tracing. Tracing will be disabled * if too many errors occur. * * @param record the log record that caused the error to occur. * @param ex the exception thrown. */ public synchronized void handleError(LogRecord record, Throwable ex) { _loggingErrors++; DebugLogFormatter formatter = new DebugLogFormatter(); System.err.println("Error publishing record: " + formatter.format(record) + ex); // If we've had too many write errors, just turn off // tracing to prevent an overflow of messages. if (_loggingErrors >= ERROR_THRESHOLD) { System.err.println("TOO MANY ERRORS FROM DEBUG LOGGER. SHUTTING DOWN"); enabled = false; } } } /** * Construct a default configuration where the logger is disabled and the * global scope will only log at the ERROR level. */ public DebugConfiguration() { super(null); this.setErrorHandler(new DebugErrorHandler()); classTraceSettings = null; methodTraceSettings = null; //Set the global settings so that only errors are logged. addTraceSettings(null, new TraceSettings(DebugLogLevel.ERROR)); } /** * Gets the method trace levels for a specified class. * @param className - a fully qualified class name to get method trace * levels for * @return an unmodifiable map of trace levels keyed by method name. If * no method level tracing is configured for the scope, <b>null</b> is * returned. */ public Map<String, TraceSettings> getMethodSettings(String className) { Map<String, TraceSettings> levels = null; if (enabled && methodTraceSettings != null) { // Method levels are always at leaves in the // hierarchy, so don't bother searching up. Map<String, TraceSettings> value= methodTraceSettings.get(className); if (value != null ) { levels= value; } } return levels != null ? Collections.unmodifiableMap(levels) : null; } /** * Get the trace settings for a specified class. * @param className - a fully qualified class name to get the * trace level for * @return the current trace settings for the class. */ public TraceSettings getTraceSettings(String className) { TraceSettings settings = TraceSettings.DISABLED; // If we're not enabled, trace level is DISABLED. if (enabled && classTraceSettings != null) { // Find most specific trace setting which covers this // fully qualified class name // Search up the hierarchy for a match. String searchName= className; Object value= null; value= classTraceSettings.get(searchName); while (value == null && searchName != null) { int clipPoint= searchName.lastIndexOf('$'); if (clipPoint == -1) clipPoint= searchName.lastIndexOf('.'); if (clipPoint != -1) { searchName= searchName.substring(0, clipPoint); value= classTraceSettings.get(searchName); } else { searchName= null; } } // Use global settings, if nothing more specific was found. if (value == null) value= classTraceSettings.get(GLOBAL); if (value != null) { settings= (TraceSettings)value; } } return settings; } /** * Adds a trace settings to the current set for a specified scope. If a * scope is not specified, the settings will be set for the global scope. * The global scope settings are used when no other scope matches. * * @param scope - the scope to set trace settings for; this is a fully * qualified class name or null to set the trace settings for the global * scope. * @param settings - the trace settings for the scope */ public void addTraceSettings(String scope, TraceSettings settings) { if (scope == null) { setClassSettings(GLOBAL, settings); } else { int methodPt= scope.lastIndexOf('#'); if (methodPt != -1) { String methodName= scope.substring(methodPt+1); scope= scope.substring(0, methodPt); setMethodSettings(scope, methodName, settings); } else { setClassSettings(scope, settings); } } } private synchronized void setClassSettings(String className, TraceSettings settings) { if(classTraceSettings == null) classTraceSettings = new HashMap<String, TraceSettings>(); classTraceSettings.put(className, settings); } private synchronized void setMethodSettings(String className, String methodName, TraceSettings settings) { if (methodTraceSettings == null) methodTraceSettings = new HashMap<String, Map<String, TraceSettings>>(); Map<String, TraceSettings> methodLevels= methodTraceSettings.get(className); if (methodLevels == null) { methodLevels= new TreeMap<String, TraceSettings>(); methodTraceSettings.put(className, methodLevels); } methodLevels.put(methodName, settings); } /** * Retrieve the initial configuration to use on debug logger startup. Settings * are read from system properties. * If this is not a debug build of OpenDS, the resulting configuration is * always disabled. * * @return the initial configuration to use for the debug logger. */ public static DebugConfiguration getStartupConfiguration() { String enabledProp = System.getProperty(PROPERTY_DEBUG_ENABLED); if(DynamicConstants.DEBUG_BUILD && (enabledProp != null && (enabledProp.startsWith("T") || enabledProp.startsWith("t") || enabledProp.startsWith("Y") || enabledProp.startsWith("y")))) { DebugConfiguration config = new DebugConfiguration(); config.setEnabled(true); TextLogPublisher consolePublisher = new TextLogPublisher(TextWriter.STDOUT, new DebugLogFormatter()); config.addPublisher(consolePublisher); Set<Map.Entry<Object, Object>> propertyEntries = System.getProperties().entrySet(); for(Map.Entry<Object, Object> entry : propertyEntries) { if(((String)entry.getKey()).startsWith(PROPERTY_DEBUG_TARGET)) { String value = (String)entry.getValue(); int settingsStart= value.indexOf(":"); //See if the scope and settings exists if(settingsStart > 0) { String scope = value.substring(0, settingsStart); TraceSettings settings = TraceSettings.parseTraceSettings( value.substring(settingsStart+1)); if(settings != null) { config.addTraceSettings(scope, settings); } } } } return config; } else { //If it is not enabled or not a debug build, just return the default //off config. return new DebugConfiguration(); } } } opends/src/server/org/opends/server/loggers/debug/DebugErrorHandler.java
File was deleted opends/src/server/org/opends/server/loggers/debug/DebugLogFormatter.java
@@ -30,6 +30,7 @@ import org.opends.server.loggers.LogRecord; import java.util.Locale; import java.util.Map; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -66,25 +67,44 @@ buf.append(_timestamper.format(dlr.getTimestamp())); buf.append(" "); // Emit the debug level. buf.append(dlr.getLevel()); // Emit the seq num buf.append(dlr.getSequenceNumber()); buf.append(" "); // Emit thread info. buf.append(dlr.getThreadName()); buf.append("("); buf.append(dlr.getThreadID()); buf.append(") "); // Emit debug category. buf.append(dlr.getCategory()); buf.append(" "); // Emit the debug level. buf.append(dlr.getLevel()); buf.append(" "); // Emit thread info. buf.append("thread={"); buf.append(dlr.getThreadName()); buf.append("("); buf.append(dlr.getThreadID()); buf.append(")} "); if(dlr.getThreadProperties() != null) { buf.append("threadDetail={"); for(Map.Entry entry : dlr.getThreadProperties().entrySet()) { buf.append(entry.getKey()); buf.append("="); buf.append(entry.getValue()); buf.append(" "); } buf.append("} "); } // Emit method info. buf.append("signature={"); buf.append(dlr.getSignature()); buf.append(" @ "); buf.append(dlr.getSourceLocation()); buf.append(" "); buf.append("} "); // Emit message. buf.append(dlr.getMessage()); @@ -92,7 +112,7 @@ // Emit Stack Trace. if(dlr.getStackTrace() != null) { buf.append("\nStack Trace\n"); buf.append("\nStack Trace:\n"); buf.append(dlr.getStackTrace()); } opends/src/server/org/opends/server/loggers/debug/DebugLogRecord.java
@@ -34,6 +34,7 @@ import org.opends.server.types.DebugLogCategory; import java.util.Date; import java.util.Map; /** * A DebugLogRecord is reponsible for passing tracing log messages from the @@ -69,6 +70,11 @@ private long threadID; /** * Detailed debug properties for thread that issued logging call. */ private Map<String, String> threadProperties; /** * Event time in milliseconds since 1970. */ private Date timestamp; @@ -387,4 +393,24 @@ public void setSequenceNumber(long seq) { sequenceNumber = seq; } /** * Set the thread properties. * * @param threadProperties the thread properties map to set. */ public void setThreadProperties(Map<String, String> threadProperties) { this.threadProperties = threadProperties; } /** * Retrives the thread properties. * * @return the thread properties. */ public Map<String, String> getThreadProperties() { return threadProperties; } } opends/src/server/org/opends/server/loggers/debug/DebugLogger.java
@@ -27,10 +27,8 @@ package org.opends.server.loggers.debug; import org.opends.server.api.ProtocolElement; import org.opends.server.api.LogPublisher; import org.opends.server.loggers.Logger; import org.opends.server.loggers.LogLevel; import org.opends.server.loggers.LogRecord; import java.util.Map; import java.util.HashMap; @@ -55,35 +53,21 @@ */ public class DebugLogger extends Logger { /** * Whether the debug logger is enabled or disabled. */ static boolean enabled = false; private static DebugLogger logger = null; static boolean staticEnabled = false; private Map<String, Tracer> classTracers; private TraceConfiguration config; private DebugLogger() private DebugConfiguration configuration; private DebugLogger(DebugConfiguration config) { super(new DebugErrorHandler()); super(config); configuration = config; classTracers = new HashMap<String, Tracer>(); config = new TraceConfiguration(); staticEnabled = enabled; } /** * Publish a record to all the registered publishers. * * @param record The log record to publish. */ protected void publishRecord(LogRecord record) { for(LogPublisher p : publishers) { p.publish(record, handler); } } /** * Obtain the trace logger singleton. @@ -92,30 +76,26 @@ public static synchronized DebugLogger getLogger() { if (logger == null) { logger= new DebugLogger(); /** * The debug logger is being intialized for the first time. * Bootstrap the debug logger when the server first starts up so * all debug messages are log from the first initialization of a * server class. */ logger= new DebugLogger(DebugConfiguration.getStartupConfiguration()); } return logger; } /** * Enable or disable the debug logger. * * @param enable if the debug logger should be enabled. */ public static void enabled(boolean enable) { enabled = enable; } /** * Obtain the status of this logger singleton. * * @return the status of this logger. */ public static boolean debugEnabled() { return enabled; return staticEnabled; } /** @@ -129,21 +109,8 @@ Tracer traceLogger = classTracers.get(className); if (traceLogger == null) { classTracers.put(className, tracer); tracer.updateSettings(this.configuration); } else { //TODO: handle dup case! } } /** * Retrives the current tracing configuration of the debug logger. * * @return the current tracing configuration of the debug logger. */ protected TraceConfiguration getConfiguration() { return config; } /** @@ -152,14 +119,17 @@ * * @param config the new configuration to apply. */ public void updateConfiguration(TraceConfiguration config) public synchronized void updateConfiguration(DebugConfiguration config) { this.config = config; super.updateConfiguration(config); staticEnabled = enabled; for(Tracer tracer : classTracers.values()) { tracer.updateSettings(); tracer.updateSettings(config); } this.configuration = config; } /** opends/src/server/org/opends/server/loggers/debug/DebugMessageFormatter.java
New file @@ -0,0 +1,273 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Portions Copyright 2006-2007 Sun Microsystems, Inc. */ package org.opends.server.loggers.debug; import java.util.*; /** * This class is responsible for formatting messages and replacing * format tokens with the text value of message arguments in debug logging * records. */ public class DebugMessageFormatter { /** * Construct a new debug message formatter. */ public DebugMessageFormatter() { //no implementation needed. } /** * Format the message format string with the provided arguments. * * @param msg the message format string to be formatted. * @param msgArgs the arguments to use when replacing tokens in the message. * @return the formatted message string. */ public String format(String msg, Object[] msgArgs) { StringBuilder buffer= new StringBuilder(); Object[] decoratedArgs = decorateMessageArgs(msgArgs); if (msg == null) { concatenateArgs(decoratedArgs, buffer); return buffer.toString(); } try { return String.format(msg, decoratedArgs); } catch (IllegalFormatException e) { // Make a more useful message than a stack trace. buffer.append(msg); concatenateArgs(decoratedArgs, buffer); return buffer.toString(); } } private void concatenateArgs(Object[] args, StringBuilder buffer) { for (int i = 0; (args != null) && (i < args.length); i++) { buffer.append(" ").append(args[i]); } } private Object[] decorateMessageArgs(Object[] undecoratedArgs) { Object[] args= null; if (undecoratedArgs != null) { args= new Object[undecoratedArgs.length]; for (int i= 0; i < args.length; i++) { args[i]= decorateArg(undecoratedArgs[i]); } } return args; } private Object decorateArg(Object arg) { Object decoratedArg= arg; if (arg instanceof Map) { decoratedArg= decorateMapArg((Map)arg); } else if (arg instanceof List) { decoratedArg= decorateListArg((List)arg); } else if (arg instanceof Object[]) { decoratedArg= decorateArrayArg((Object[])arg); } else if (arg instanceof boolean[]) { decoratedArg = decorateArrayArg((boolean[])arg); } else if (arg instanceof byte[]) { decoratedArg = decorateArrayArg((byte[])arg); } else if (arg instanceof char[]) { decoratedArg = decorateArrayArg((char[])arg); } else if (arg instanceof double[]) { decoratedArg = decorateArrayArg((double[])arg); } else if (arg instanceof float[]) { decoratedArg = decorateArrayArg((float[])arg); } else if (arg instanceof int[]) { decoratedArg = decorateArrayArg((int[])arg); } else if (arg instanceof long[]) { decoratedArg = decorateArrayArg((long[])arg); } return decoratedArg; } private String decorateArrayArg(Object[] array) { return decorateListArg(Arrays.asList(array)); } private String decorateArrayArg(boolean[] array) { StringBuilder buffer= new StringBuilder(); buffer.append("[ "); boolean firstElement= true; for (int i= 0; i < array.length; i++) { if (i > 0) buffer.append(", "); buffer.append(array[i]); } buffer.append(" ]"); return buffer.toString(); } private String decorateArrayArg(byte[] array) { StringBuilder buffer= new StringBuilder(); buffer.append("[ "); boolean firstElement= true; for (int i= 0; i < array.length; i++) { if (i > 0) buffer.append(", "); buffer.append(array[i]); } buffer.append(" ]"); return buffer.toString(); } private String decorateArrayArg(char[] array) { StringBuilder buffer= new StringBuilder(); buffer.append("[ "); boolean firstElement= true; for (int i= 0; i < array.length; i++) { if (i > 0) buffer.append(", "); buffer.append(array[i]); } buffer.append(" ]"); return buffer.toString(); } private String decorateArrayArg(double[] array) { StringBuilder buffer= new StringBuilder(); buffer.append("[ "); boolean firstElement= true; for (int i= 0; i < array.length; i++) { if (i > 0) buffer.append(", "); buffer.append(array[i]); } buffer.append(" ]"); return buffer.toString(); } private String decorateArrayArg(float[] array) { StringBuilder buffer= new StringBuilder(); buffer.append("[ "); boolean firstElement= true; for (int i= 0; i < array.length; i++) { if (i > 0) buffer.append(", "); buffer.append(array[i]); } buffer.append(" ]"); return buffer.toString(); } private String decorateArrayArg(int[] array) { StringBuilder buffer= new StringBuilder(); buffer.append("[ "); boolean firstElement= true; for (int i= 0; i < array.length; i++) { if (i > 0) buffer.append(", "); buffer.append(array[i]); } buffer.append(" ]"); return buffer.toString(); } private String decorateArrayArg(long[] array) { StringBuilder buffer= new StringBuilder(); buffer.append("[ "); boolean firstElement= true; for (int i= 0; i < array.length; i++) { if (i > 0) buffer.append(", "); buffer.append(array[i]); } buffer.append(" ]"); return buffer.toString(); } private String decorateListArg(List list) { StringBuilder buffer= new StringBuilder(); Iterator iter= list.iterator(); buffer.append("[ "); boolean firstElement= true; while (iter.hasNext()) { Object lValue= iter.next(); if (!firstElement) buffer.append(", "); buffer.append(decorateArg(lValue)); firstElement= false; } buffer.append(" ]"); return buffer.toString(); } private String decorateMapArg(Map map) { StringBuilder buffer= new StringBuilder(); Iterator iter= map.entrySet().iterator(); buffer.append("{ "); boolean firstEntry= true; while (iter.hasNext()) { Map.Entry entry= (Map.Entry)iter.next(); if (!firstEntry) buffer.append(", "); buffer.append(decorateArg(entry.getKey())); buffer.append("="); buffer.append(decorateArg(entry.getValue())); firstEntry= false; } buffer.append(" }"); return buffer.toString(); } } opends/src/server/org/opends/server/loggers/debug/TraceConfiguration.java
File was deleted opends/src/server/org/opends/server/loggers/debug/TraceSettings.java
@@ -28,10 +28,12 @@ package org.opends.server.loggers.debug; import org.opends.server.types.DebugLogLevel; import org.opends.server.types.DebugLogCategory; import org.opends.server.loggers.LogLevel; import org.opends.server.loggers.LogCategory; import java.util.Set; import java.util.HashSet; /** * This class encapsulates the trace settings in effect at a given traceing @@ -43,6 +45,13 @@ static final TraceSettings DISABLED = new TraceSettings(DebugLogLevel.DISABLED); static final String STACK_DUMP_KEYWORD = "stack"; static final String INCLUDE_CAUSE_KEYWORD = "cause"; static final String SUPPRESS_ARG_KEYWORD = "noargs"; static final String SUPPRESS_RETVAL_KEYWORD = "noretval"; static final String INCLUDE_CATEGORY_KEYWORD = "category"; static final String LEVEL_KEYWORD = "level"; final LogLevel level; final Set<LogCategory> includeCategories; @@ -115,4 +124,140 @@ this.stackDepth = stackDepth; this.includeCause = includeCause; } /** * Parse trace settings from the string representation. * * @param value the trace settings string to be parsed. * @return the trace settings parsed from the string. */ protected static TraceSettings parseTraceSettings(String value) { TraceSettings settings = null; if(value != null) { //Touch DebugLogLevel and DebugLogCategory so they are statically //initialized or parse will not see all the levels/categories. LogLevel level = DebugLogLevel.ERROR; LogCategory categoryStub = DebugLogCategory.MESSAGE; Set<LogCategory> includeCategories = null; boolean noArgs = false; boolean noRetVal = false; int stackDepth = 0; boolean includeCause = false; String[] keywords = value.split(","); for(String keyword : keywords) { //See if stack dump keyword is included if(keyword.startsWith(STACK_DUMP_KEYWORD)) { //See if a stack depth is included if(keyword.length() == STACK_DUMP_KEYWORD.length()) { stackDepth = DebugStackTraceFormatter.COMPLETE_STACK; } else { int depthStart= keyword.indexOf("=", STACK_DUMP_KEYWORD.length()); if (depthStart == STACK_DUMP_KEYWORD.length()) { try { stackDepth = Integer.valueOf(keyword.substring(depthStart+1)); } catch(NumberFormatException nfe) { System.err.println("The keyword " + STACK_DUMP_KEYWORD + " contains an invalid depth value. The complete stack " + "will be included."); } } } } //See if to include cause in exception messages. else if(keyword.equals(INCLUDE_CAUSE_KEYWORD)) { includeCause = true; } //See if to supress method arguments. else if(keyword.equals(SUPPRESS_ARG_KEYWORD)) { noArgs = true; } //See if to supress return values. else if(keyword.equals(SUPPRESS_RETVAL_KEYWORD)) { noRetVal = true; } else if(keyword.startsWith(INCLUDE_CATEGORY_KEYWORD)) { int categoryStart = keyword.indexOf("=", INCLUDE_CATEGORY_KEYWORD.length()); if(keyword.length() == INCLUDE_CATEGORY_KEYWORD.length() || categoryStart != INCLUDE_CATEGORY_KEYWORD.length()) { System.err.println("The keyword " + INCLUDE_CATEGORY_KEYWORD + " does not contain an equal sign to define the set of " + "categories to include. All categories will be included."); } else { String[] categories = keyword.substring(categoryStart+1).split("[|]"); includeCategories = new HashSet<LogCategory>(); for(String category : categories) { try { includeCategories.add(DebugLogCategory.parse(category)); } catch(IllegalArgumentException iae) { System.err.println("The keyword " + INCLUDE_CATEGORY_KEYWORD + " contains an invalid debug log category: " + iae.toString() + ". It will be ignored."); } } } } else if(keyword.startsWith(LEVEL_KEYWORD)) { int levelStart = keyword.indexOf("=", LEVEL_KEYWORD.length()); if(keyword.length() == LEVEL_KEYWORD.length() || levelStart != LEVEL_KEYWORD.length()) { System.err.println("The keyword " + LEVEL_KEYWORD + " does not contain an equal sign to specify the log level. " + "Default level of " + level.toString() + " will be used."); } else { try { level = LogLevel.parse(keyword.substring(levelStart+1)); } catch(IllegalArgumentException iae) { System.err.println("The keyword " + LEVEL_KEYWORD + " contains an invalid debug log level: " + iae.toString() + ". Default level of " + level.toString() + " will be used."); } } } } settings = new TraceSettings(level, includeCategories, noArgs, noRetVal, stackDepth, includeCause); } return settings; } } opends/src/server/org/opends/server/loggers/debug/Tracer.java
@@ -39,6 +39,7 @@ import org.opends.server.util.ServerConstants; import org.opends.server.util.StaticUtils; import org.opends.server.api.ProtocolElement; import org.opends.server.api.DirectoryThread; import org.opends.server.loggers.*; import org.opends.server.types.DebugLogCategory; import org.opends.server.types.DebugLogLevel; @@ -53,7 +54,11 @@ * Logging is always done at a level basis, with debug log messages * exceeding the trace threshold being traced, others being discarded. */ @Aspect("pertypewithin(*)") @Aspect("pertypewithin(!@Tracer.NoDebugTracing org.opends.server..*+ && " + "!org.opends.server.loggers.*+ && " + "!org.opends.server.loggers.debug..*+ &&" + "!org.opends.server.types.DebugLogLevel+ && " + "!org.opends.server.types.DebugLogCategory+)") public class Tracer { /** @@ -76,7 +81,7 @@ /** * Pointcut for matching all toString() methods. */ @Pointcut("execution(String *..toString())") @Pointcut("execution(* *..toString(..))") private void toStringMethod() { } @@ -91,6 +96,16 @@ } /** * Pointcut for matching all getDebugProperties() methods. * TODO: Make this less general. Find out if pointcut matches * subclass methods. */ @Pointcut("execution(* *..getDebugProperties(..))") private void getDebugPropertiesMethod() { } /** * Pointcut for matching debugMessage() methods. */ @Pointcut("call(public static void org.opends.server." + @@ -194,9 +209,8 @@ * Pointcut to exclude all pointcuts which should not be adviced by the * debug logger. */ @Pointcut("within(Tracer+) || within(org.opends.server.loggers.debug..*) " + "|| toStringMethod() " + "|| getMessageMethod() || logMethods()") @Pointcut("toStringMethod() || getMessageMethod() || " + "getDebugPropertiesMethod() || logMethods()") private void excluded() { } @@ -204,16 +218,47 @@ /** * Pointcut for matching the execution of all public methods. */ @Pointcut("execution(!@NoDebugTracing public * *(..)) && !excluded()") void tracedMethod() @Pointcut("execution(!@(Tracer.NoDebugTracing || " + "Tracer.NoEntryDebugTracing) public * *(..)) && " + "!excluded()") void tracedEntryMethod() { } /** * Pointcut for matching the execution of all public methods. */ @Pointcut("execution(!@(Tracer.NoDebugTracing || " + "Tracer.NoExitDebugTracing) public * *(..)) && " + "!excluded()") void tracedExitMethod() { } /** * Pointcut for matching the execution of all public methods. */ @Pointcut("execution(@Tracer.TraceThrown public * *(..)) && " + "!excluded()") void tracedThrownMethod() { } /** * Pointcut for matching the execution of all constructors. */ @Pointcut("execution(!@NoDebugTracing public new(..)) && !excluded()") void tracedConstructor() @Pointcut("execution(!@(Tracer.NoDebugTracing || " + "Tracer.NoEntryDebugTracing) public new(..)) && !excluded()") void tracedEntryConstructor() { } /** * Pointcut for matching the execution of all constructors. */ @Pointcut("execution(!@(Tracer.NoDebugTracing || " + "Tracer.NoExitDebugTracing) public new(..)) && !excluded()") void tracedExitConstructor() { } @@ -222,19 +267,12 @@ * * @return if debug logging is enabled. */ @Pointcut("if() && tracingScope()") @Pointcut("if()") public static boolean shouldTrace() { return DebugLogger.enabled; return DebugLogger.staticEnabled; } /** * Pointcut for matching only within the scope of the server packages. */ @Pointcut("within(!@NoDebugTracing org.opends.server..*)") protected void tracingScope() { } //The default level to log constructor exectuions. private static final LogLevel DEFAULT_CONSTRUCTOR_LEVEL = @@ -242,6 +280,12 @@ //The default level to log method entry and exit pointcuts. private static final LogLevel DEFAULT_ENTRY_EXIT_LEVEL = DebugLogLevel.VERBOSE; //The default level to log method entry and exit pointcuts. private static final LogLevel DEFAULT_THROWN_LEVEL = DebugLogLevel.ERROR; private static final DebugMessageFormatter msgFormatter = new DebugMessageFormatter(); // The class this tracer traces. private String className; @@ -258,13 +302,12 @@ * * @param thisJoinPointStaticPart the JoinPoint reflection object. */ @Before("staticinitialization(*) && tracingScope()") @Before("staticinitialization(*)") public void initializeTracer(JoinPoint.StaticPart thisJoinPointStaticPart) { className = thisJoinPointStaticPart.getSignature().getDeclaringTypeName(); logger = DebugLogger.getLogger(); logger.registerTracer(className, this); updateSettings(); } /** @@ -272,7 +315,7 @@ * * @param thisJoinPoint the JoinPoint reflection object. */ @Before("shouldTrace() && tracedConstructor()") @Before("shouldTrace() && tracedEntryConstructor()") public void traceConstructor(JoinPoint thisJoinPoint) { LogCategory category = DebugLogCategory.CONSTRUCTOR; @@ -294,7 +337,7 @@ * @param thisJoinPoint the JoinPoint reflection object. * @param obj the object this method operations on. */ @Before("shouldTrace() && tracedMethod() && nonStaticContext(obj)") @Before("shouldTrace() && tracedEntryMethod() && nonStaticContext(obj)") public void traceNonStaticMethodEntry(JoinPoint thisJoinPoint, Object obj) { LogCategory category = DebugLogCategory.ENTER; @@ -315,7 +358,7 @@ * * @param thisJoinPoint the JoinPoint reflection object. */ @Before("shouldTrace() && tracedMethod() && staticContext()") @Before("shouldTrace() && tracedEntryMethod() && staticContext()") public void traceStaticMethodEntry(JoinPoint thisJoinPoint) { LogCategory category = DebugLogCategory.ENTER; @@ -337,8 +380,8 @@ * @param thisJoinPointStaticPart the JoinPoint reflection object. * @param ret the return value of the method. */ @AfterReturning(pointcut = "shouldTrace() && tracedMethod() &&" + "traceConstructor()", @AfterReturning(pointcut = "shouldTrace() && " + "(tracedExitMethod() || tracedExitConstructor())", returning = "ret") public void traceReturn(JoinPoint.StaticPart thisJoinPointStaticPart, Object ret) @@ -359,12 +402,42 @@ /** * AspectJ Implementation. * * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object. * @param thisJoinPointStaticPart the JoinPoint reflection object. * @param ex the exception thrown. */ @AfterThrowing(pointcut = "shouldTrace() && tracedThrownMethod()", throwing = "ex") public void traceThrown(JoinPoint.StaticPart thisJoinPointStaticPart, Throwable ex) { LogCategory category = DebugLogCategory.THROWN; LogLevel level = DEFAULT_THROWN_LEVEL; Signature signature = thisJoinPointStaticPart.getSignature(); TraceSettings settings = getSettings(signature.getName()); if (level.intValue() >= getEffectiveLevel(settings, category).intValue()) { SourceLocation sl = thisJoinPointStaticPart.getSourceLocation(); publish(category, level, signature.toLongString(), sl.toString(), null, null , new Object[]{ex}, settings); } } /** * AspectJ Implementation. * * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object * of the code that contains the * debug call. * @param thisJoinPointStaticPart the JoinPoint reflection object. * @param msg message to format and log. */ @Around("shouldTrace() && logVerboseMethod() && args(msg)") public void traceVerbose(JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart, String msg) thisEnclosingJoinPointStaticPart, JoinPoint.StaticPart thisJoinPointStaticPart, String msg) { LogLevel level = DebugLogLevel.VERBOSE; LogCategory category = DebugLogCategory.MESSAGE; @@ -373,7 +446,7 @@ if (level.intValue() >= getEffectiveLevel(settings, category).intValue()) { SourceLocation sl = thisEnclosingJoinPointStaticPart.getSourceLocation(); SourceLocation sl = thisJoinPointStaticPart.getSourceLocation(); publish(category, level, signature.toLongString(), sl.toString(), null, msg, null, settings); } @@ -382,13 +455,18 @@ /** * AspectJ Implementation. * * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object. * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object * of the code that contains the * debug call. * @param thisJoinPointStaticPart the JoinPoint reflection object. * @param msg message to format and log. * @param msgArgs arguments to place into the format string. */ @Around("shouldTrace() && logVerboseMethod() && args(msg, msgArgs)") public void traceVerbose(JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart, JoinPoint.StaticPart thisJoinPointStaticPart, String msg, Object[] msgArgs) { LogLevel level = DebugLogLevel.VERBOSE; @@ -398,7 +476,7 @@ if (level.intValue() >= getEffectiveLevel(settings, category).intValue()) { SourceLocation sl = thisEnclosingJoinPointStaticPart.getSourceLocation(); SourceLocation sl = thisJoinPointStaticPart.getSourceLocation(); publish(category, level, signature.toLongString(), sl.toString(), null, msg, msgArgs, settings); } @@ -407,12 +485,18 @@ /** * AspectJ Implementation. * * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object. * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object * of the code that contains the * debug call. * @param thisJoinPointStaticPart the JoinPoint reflection object. * @param msg message to format and log. */ @Around("shouldTrace() && logInfoMethod() && args(msg)") public void traceInfo(JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart, String msg) thisEnclosingJoinPointStaticPart, JoinPoint.StaticPart thisJoinPointStaticPart, String msg) { LogLevel level = DebugLogLevel.INFO; LogCategory category = DebugLogCategory.MESSAGE; @@ -421,7 +505,7 @@ if (level.intValue() >= getEffectiveLevel(settings, category).intValue()) { SourceLocation sl = thisEnclosingJoinPointStaticPart.getSourceLocation(); SourceLocation sl = thisJoinPointStaticPart.getSourceLocation(); publish(category, level, signature.toLongString(), sl.toString(), null, msg, null, settings); } @@ -430,13 +514,18 @@ /** * AspectJ Implementation. * * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object. * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object * of the code that contains the * debug call. * @param thisJoinPointStaticPart the JoinPoint reflection object. * @param msg message to format and log. * @param msgArgs arguments to place into the format string. */ @Around("shouldTrace() && logInfoMethod() && args(msg, msgArgs)") public void traceInfo(JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart, JoinPoint.StaticPart thisJoinPointStaticPart, String msg, Object[] msgArgs) { LogLevel level = DebugLogLevel.INFO; @@ -446,7 +535,7 @@ if (level.intValue() >= getEffectiveLevel(settings, category).intValue()) { SourceLocation sl = thisEnclosingJoinPointStaticPart.getSourceLocation(); SourceLocation sl = thisJoinPointStaticPart.getSourceLocation(); publish(category, level, signature.toLongString(), sl.toString(), null, msg, msgArgs, settings); } @@ -455,12 +544,18 @@ /** * AspectJ Implementation. * * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object. * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object * of the code that contains the * debug call. * @param thisJoinPointStaticPart the JoinPoint reflection object. * @param msg message to format and log. */ @Around("shouldTrace() && logWarningMethod() && args(msg)") public void traceWarning(JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart, String msg) thisEnclosingJoinPointStaticPart, JoinPoint.StaticPart thisJoinPointStaticPart, String msg) { LogLevel level = DebugLogLevel.WARNING; @@ -470,7 +565,7 @@ if (level.intValue() >= getEffectiveLevel(settings, category).intValue()) { SourceLocation sl = thisEnclosingJoinPointStaticPart.getSourceLocation(); SourceLocation sl = thisJoinPointStaticPart.getSourceLocation(); publish(category, level, signature.toLongString(), sl.toString(), null, msg, null, settings); } @@ -479,13 +574,18 @@ /** * AspectJ Implementation. * * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object. * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object * of the code that contains the * debug call. * @param thisJoinPointStaticPart the JoinPoint reflection object. * @param msg message to format and log. * @param msgArgs arguments to place into the format string. */ @Around("shouldTrace() && logWarningMethod() && args(msg, msgArgs)") public void traceWarning(JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart, JoinPoint.StaticPart thisJoinPointStaticPart, String msg, Object[] msgArgs) { LogLevel level = DebugLogLevel.WARNING; @@ -495,7 +595,7 @@ if (level.intValue() >= getEffectiveLevel(settings, category).intValue()) { SourceLocation sl = thisEnclosingJoinPointStaticPart.getSourceLocation(); SourceLocation sl = thisJoinPointStaticPart.getSourceLocation(); publish(category, level, signature.toLongString(), sl.toString(), null, msg, msgArgs, settings); } @@ -504,12 +604,18 @@ /** * AspectJ Implementation. * * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object. * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object * of the code that contains the * debug call. * @param thisJoinPointStaticPart the JoinPoint reflection object. * @param msg message to format and log. */ @Around("shouldTrace() && logErrorMethod() && args(msg)") public void traceError(JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart, String msg) thisEnclosingJoinPointStaticPart, JoinPoint.StaticPart thisJoinPointStaticPart, String msg) { LogLevel level = DebugLogLevel.ERROR; @@ -519,7 +625,7 @@ if (level.intValue() >= getEffectiveLevel(settings, category).intValue()) { SourceLocation sl = thisEnclosingJoinPointStaticPart.getSourceLocation(); SourceLocation sl = thisJoinPointStaticPart.getSourceLocation(); publish(category, level, signature.toLongString(), sl.toString(), null, msg, null, settings); } @@ -528,13 +634,18 @@ /** * AspectJ Implementation. * * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object. * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object * of the code that contains the * debug call. * @param thisJoinPointStaticPart the JoinPoint reflection object. * @param msg message to format and log. * @param msgArgs arguments to place into the format string. */ @Around("shouldTrace() && logErrorMethod() && args(msg, msgArgs)") public void traceError(JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart, JoinPoint.StaticPart thisJoinPointStaticPart, String msg, Object[] msgArgs) { LogLevel level = DebugLogLevel.ERROR; @@ -544,7 +655,7 @@ if (level.intValue() >= getEffectiveLevel(settings, category).intValue()) { SourceLocation sl = thisEnclosingJoinPointStaticPart.getSourceLocation(); SourceLocation sl = thisJoinPointStaticPart.getSourceLocation(); publish(category, level, signature.toLongString(), sl.toString(), null, msg, msgArgs, settings); } @@ -553,13 +664,18 @@ /** * AspectJ Implementation. * * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object. * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object * of the code that contains the * debug call. * @param thisJoinPointStaticPart the JoinPoint reflection object. * @param level the level of the log message. * @param msg message to format and log. */ @Around("shouldTrace() && logMessageMethod() && args(level, msg)") public void traceMessage(JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart, JoinPoint.StaticPart thisJoinPointStaticPart, LogLevel level, String msg) { LogCategory category = DebugLogCategory.MESSAGE; @@ -568,7 +684,7 @@ if (level.intValue() >= getEffectiveLevel(settings, category).intValue()) { SourceLocation sl = thisEnclosingJoinPointStaticPart.getSourceLocation(); SourceLocation sl = thisJoinPointStaticPart.getSourceLocation(); publish(category, level, signature.toLongString(), sl.toString(), null, msg, null, settings); } @@ -577,7 +693,10 @@ /** * AspectJ Implementation. * * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object. * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object * of the code that contains the * debug call. * @param thisJoinPointStaticPart the JoinPoint reflection object. * @param level the level of the log message. * @param msg message to format and log. * @param msgArgs arguments to place into the format string. @@ -585,6 +704,8 @@ @Around("shouldTrace() && logMessageMethod() && args(level, msg, msgArgs)") public void traceMessage(JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart, JoinPoint.StaticPart thisJoinPointStaticPart, LogLevel level, String msg, Object... msgArgs) { LogCategory category = DebugLogCategory.MESSAGE; @@ -593,7 +714,7 @@ if (level.intValue() >= getEffectiveLevel(settings, category).intValue()) { SourceLocation sl = thisEnclosingJoinPointStaticPart.getSourceLocation(); SourceLocation sl = thisJoinPointStaticPart.getSourceLocation(); publish(category, level, signature.toLongString(), sl.toString(), null, msg, msgArgs, settings); } @@ -602,13 +723,18 @@ /** * AspectJ Implementation. * * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object. * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object * of the code that contains the * debug call. * @param thisJoinPointStaticPart the JoinPoint reflection object. * @param level the level of the log message. * @param ex the exception thrown. */ @Around("shouldTrace() && logThrownMethod() && args(level, ex)") public void traceThrown(JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart, JoinPoint.StaticPart thisJoinPointStaticPart, LogLevel level, Throwable ex) { LogCategory category = DebugLogCategory.THROWN; @@ -617,7 +743,7 @@ if (level.intValue() >= getEffectiveLevel(settings, category).intValue()) { SourceLocation sl = thisEnclosingJoinPointStaticPart.getSourceLocation(); SourceLocation sl = thisJoinPointStaticPart.getSourceLocation(); publish(category, level, signature.toLongString(), sl.toString(), null, null , new Object[]{ex}, settings); } @@ -626,13 +752,18 @@ /** * AspectJ Implementation. * * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object. * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object * of the code that contains the * debug call. * @param thisJoinPointStaticPart the JoinPoint reflection object. * @param level the level of the log message. * @param ex the exception caught. */ @Around("shouldTrace() && logCaughtMethod() && args(level, ex)") public void traceCaught(JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart, JoinPoint.StaticPart thisJoinPointStaticPart, LogLevel level, Throwable ex) { LogCategory category = DebugLogCategory.CAUGHT; @@ -641,7 +772,7 @@ if (level.intValue() >= getEffectiveLevel(settings, category).intValue()) { SourceLocation sl = thisEnclosingJoinPointStaticPart.getSourceLocation(); SourceLocation sl = thisJoinPointStaticPart.getSourceLocation(); publish(category, level, signature.toLongString(), sl.toString(), null, null , new Object[]{ex}, settings); } @@ -650,7 +781,10 @@ /** * AspectJ Implementation. * * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object. * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object * of the code that contains the * debug call. * @param thisJoinPointStaticPart the JoinPoint reflection object. * @param level the level of the log message. * @param status status of the JE operation. * @param database the database handle. @@ -662,6 +796,8 @@ "database, txn, key, data)") public void traceJEAccess(JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart, JoinPoint.StaticPart thisJoinPointStaticPart, LogLevel level, OperationStatus status, Database database, Transaction txn, DatabaseEntry key, DatabaseEntry data) @@ -704,26 +840,29 @@ builder.append(" txnid=none"); } // If the operation was successful we log the same common information // plus the key and data under category DATABASE_READ or DATABASE_WRITE if (status == OperationStatus.SUCCESS) builder.append(ServerConstants.EOL); if(key != null) { builder.append(ServerConstants.EOL); builder.append(" key:"); builder.append("key:"); builder.append(ServerConstants.EOL); StaticUtils.byteArrayToHexPlusAscii(builder, key.getData(), 4); if (data != null) { builder.append("data(len="); builder.append(data.getSize()); builder.append("):"); builder.append(ServerConstants.EOL); StaticUtils.byteArrayToHexPlusAscii(builder, data.getData(), 4); } } // If the operation was successful we log the same common information // plus the data if (status == OperationStatus.SUCCESS && data != null) { builder.append("data(len="); builder.append(data.getSize()); builder.append("):"); builder.append(ServerConstants.EOL); StaticUtils.byteArrayToHexPlusAscii(builder, data.getData(), 4); } SourceLocation sl = thisEnclosingJoinPointStaticPart.getSourceLocation(); SourceLocation sl = thisJoinPointStaticPart.getSourceLocation(); publish(category, level, signature.toLongString(), sl.toString(), null, builder.toString(), null, settings); } @@ -731,13 +870,18 @@ /** * AspectJ Implementation. * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object. * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object * of the code that contains the * debug call. * @param thisJoinPointStaticPart the JoinPoint reflection object. * @param level the level of the log message. * @param data the data to dump. */ @Around("shouldTrace() && logDataMethod() && args(level, data)") public void traceData(JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart, JoinPoint.StaticPart thisJoinPointStaticPart, LogLevel level, byte[] data) { LogCategory category = DebugLogCategory.DATA; @@ -756,7 +900,7 @@ builder.append(ServerConstants.EOL); StaticUtils.byteArrayToHexPlusAscii(builder, data, 4); SourceLocation sl = thisEnclosingJoinPointStaticPart.getSourceLocation(); thisJoinPointStaticPart.getSourceLocation(); publish(category, level, signature.toLongString(), sl.toString(), null, builder.toString(), null, settings); } @@ -766,13 +910,18 @@ /** * AspectJ Implementation. * * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object. * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object * of the code that contains the * debug call. * @param thisJoinPointStaticPart the JoinPoint reflection object. * @param level the level of the log message. * @param element the protocol element to dump. */ @Around("shouldTrace() && logProtocolElementMethod() && args(level, element)") public void traceProtocolElement(JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart, JoinPoint.StaticPart thisJoinPointStaticPart, LogLevel level, ProtocolElement element) { LogCategory category = DebugLogCategory.PROTOCOL; @@ -787,7 +936,7 @@ builder.append(ServerConstants.EOL); element.toString(builder, 4); SourceLocation sl = thisEnclosingJoinPointStaticPart.getSourceLocation(); thisJoinPointStaticPart.getSourceLocation(); publish(category, level, signature.toLongString(), sl.toString(), null, builder.toString(), null, settings); } @@ -797,13 +946,18 @@ /** * AspectJ Implementation. * * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object. * @param thisEnclosingJoinPointStaticPart the JoinPoint reflection object * of the code that contains the * debug call. * @param thisJoinPointStaticPart the JoinPoint reflection object. * @param level the level of the log message. * @param buffer the data to dump. */ @Around("shouldTrace() && logDataMethod() && args(level, buffer)") public void traceData(JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart, JoinPoint.StaticPart thisJoinPointStaticPart, LogLevel level, ByteBuffer buffer) { LogCategory category = DebugLogCategory.DATA; @@ -823,7 +977,7 @@ builder.append(ServerConstants.EOL); StaticUtils.byteArrayToHexPlusAscii(builder, data, 4); SourceLocation sl = thisEnclosingJoinPointStaticPart.getSourceLocation(); thisJoinPointStaticPart.getSourceLocation(); publish(category, level, signature.toLongString(), sl.toString(), null, builder.toString(), null, settings); } @@ -839,9 +993,10 @@ { int stackDepth = 0; if(DebugLogCategory.ENTER.equals(category)) if (DebugLogCategory.ENTER.equals(category) || DebugLogCategory.CONSTRUCTOR.equals(category)) { if (settings.noArgs) if(settings.noArgs) { msgArgs = null; } @@ -849,12 +1004,11 @@ { msg = buildDefaultEntryMessage(msgArgs.length); } stackDepth = settings.stackDepth; } if(DebugLogCategory.EXIT.equals(category)) else if(DebugLogCategory.EXIT.equals(category)) { if (settings.noRetVal) if(settings.noRetVal) { msgArgs = null; } @@ -863,18 +1017,26 @@ msg = "returned={%s}"; } } if(DebugLogCategory.THROWN.equals(category)) else if(DebugLogCategory.THROWN.equals(category)) { if (msg == null) if(msg == null) { msg = "threw={%s}"; } stackDepth = settings.stackDepth; } else if(DebugLogCategory.CAUGHT.equals(category)) { if(msg == null) { msg = "caught={%s}"; } } if (msg != null && msgArgs != null) { msg = String.format(msg, msgArgs); msg = msgFormatter.format(msg, msgArgs); } @@ -883,21 +1045,25 @@ record.setSignature(method); record.setSourceLocation(srcLocation); Thread thread = Thread.currentThread(); if(thread instanceof DirectoryThread) { record.setThreadProperties( ((DirectoryThread)thread).getDebugProperties()); } //Stack trace applies only to entry and thrown exception messages. if(DebugLogCategory.ENTER.equals(category) || DebugLogCategory.THROWN.equals(category)) { stackDepth = settings.stackDepth; } // Inject a stack trace if requested if (stackDepth > 0) { //Generate a dummy exception to get stack trace if necessary Throwable t; if(!DebugLogCategory.THROWN.equals(category) || msgArgs == null || msgArgs[0] == null) { t= new NullPointerException(); } else { t = (Throwable)msgArgs[0]; } Throwable t= new NullPointerException(); String stack= DebugStackTraceFormatter.formatStackTrace(t, DebugStackTraceFormatter.SMART_FRAME_FILTER, @@ -988,15 +1154,15 @@ /** * Update the settings for this tracer. * * @param config the new trace configuration. */ protected void updateSettings() protected void updateSettings(DebugConfiguration config) { synchronized (this) { this.settings = logger.getConfiguration().getTraceSettings(className); this.methodSettings = logger.getConfiguration().getMethodSettings(className); this.settings = config.getTraceSettings(className); this.methodSettings = config.getMethodSettings(className); } } @@ -1027,4 +1193,28 @@ return getEffectiveLevel(settings, category); } /** * Classes and methods annotated with @NoDebugTracing will not be weaved with * debug logging statements by AspectJ. */ public @interface NoDebugTracing {} /** * Methods annotated with @NoEntryDebugTracing will not be weaved with * entry debug logging statements by AspectJ. */ public @interface NoEntryDebugTracing {} /** * Methods annotated with @NoExitDebugTracing will not be weaved with * exit debug logging statements by AspectJ. */ public @interface NoExitDebugTracing {} /** * Methods annotated with @TraceThrown will not be weaved by AspectJ with * debug logging statements when an exception is thrown from the method. */ public @interface TraceThrown {} } opends/src/server/org/opends/server/types/DebugLogCategory.java
@@ -67,7 +67,7 @@ * Only logger related classes may use this. */ public static final LogCategory CAUGHT = new DebugLogCategory( DEBUG_CATEGORY_THROWN); DEBUG_CATEGORY_CAUGHT); /** * The log category that will be used for method entry messages. opends/src/server/org/opends/server/types/FilePermission.java
@@ -1054,9 +1054,48 @@ */ public void toString(StringBuilder buffer) { buffer.append("FilePermission("); toUNIXMode(buffer, this); buffer.append(")"); buffer.append("Owner="); if (isOwnerReadable()) { buffer.append("r"); } if (isOwnerWritable()) { buffer.append("w"); } if (isOwnerExecutable()) { buffer.append("x"); } buffer.append(", Group="); if (isGroupReadable()) { buffer.append("r"); } if (isGroupWritable()) { buffer.append("w"); } if (isGroupExecutable()) { buffer.append("x"); } buffer.append(", Other="); if (isOtherReadable()) { buffer.append("r"); } if (isOtherWritable()) { buffer.append("w"); } if (isOtherExecutable()) { buffer.append("x"); } } } opends/src/server/org/opends/server/util/ServerConstants.java
@@ -2250,6 +2250,24 @@ /** * The name of the system property that can be used to enable or disable * the debug logger on startup. */ public static final String PROPERTY_DEBUG_ENABLED = "org.opends.server.debug.enabled"; /** * The name of the system property that can be used to specify a target * for the debug logger on startup. */ public static final String PROPERTY_DEBUG_TARGET = "org.opends.server.debug.target"; /** * The column at which to wrap long lines of output in the command-line tools. */ public static final int MAX_LINE_WIDTH = 79; opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java
@@ -56,6 +56,9 @@ import org.opends.server.extensions.ConfigFileHandler; import org.opends.server.loggers.Access; import org.opends.server.loggers.Error; import org.opends.server.loggers.debug.DebugLogFormatter; import org.opends.server.loggers.debug.DebugConfiguration; import org.opends.server.loggers.debug.DebugLogger; import org.opends.server.plugins.InvocationCounterPlugin; import org.opends.server.protocols.internal.InternalClientConnection; import org.opends.server.types.DN; @@ -147,6 +150,19 @@ return; } String debugTarget = System.getProperty("org.opends.test.debug.target"); if(debugTarget != null) { System.setProperty("org.opends.server.debug.target.1", debugTarget); } DebugConfiguration testDebugConfig = DebugConfiguration.getStartupConfiguration(); testDebugConfig.removeAllPublishers(true); testDebugConfig.addPublisher(TestListener.DEBUG_LOG_PUBLISHER); DebugLogger debugLogger = DebugLogger.getLogger(); debugLogger.updateConfiguration(testDebugConfig); InvocationCounterPlugin.resetStartupCalled(); // Get the build root and use it to create a test package directory. opends/tests/unit-tests-testng/src/server/org/opends/server/TestListener.java
@@ -36,6 +36,12 @@ import org.testng.xml.XmlSuite; import static org.opends.server.util.ServerConstants.EOL; import static org.opends.server.TestCaseUtils.originalSystemErr; import org.opends.server.loggers.debug.DebugLogFormatter; import org.opends.server.loggers.debug.DebugConfiguration; import org.opends.server.loggers.debug.TraceSettings; import org.opends.server.loggers.debug.DebugLogger; import org.opends.server.loggers.LogLevel; import org.opends.server.types.DebugLogLevel; import java.util.List; import java.util.LinkedHashMap; @@ -64,6 +70,12 @@ // fails, we can do the coverage report before failing the build. public static final String ANT_TESTS_FAILED_FILE_NAME = ".tests-failed-marker"; /** * The Log Publisher for the Debug Logger */ public static TestLogPublisher DEBUG_LOG_PUBLISHER = new TestLogPublisher(new DebugLogFormatter()); private static final String DIVIDER_LINE = "-------------------------------------------------------------------------------" + EOL; public void onStart(ITestContext testContext) { @@ -173,6 +185,8 @@ TestErrorLogger.clear(); TestCaseUtils.clearSystemOutContents(); TestCaseUtils.clearSystemErrContents(); DEBUG_LOG_PUBLISHER.clear(); } @@ -231,6 +245,19 @@ } } messages = DEBUG_LOG_PUBLISHER.getMessages(); if(! messages.isEmpty()) { failureInfo.append(EOL); failureInfo.append("Debug Log Messages:"); failureInfo.append(EOL); for (String message : messages) { failureInfo.append(message); failureInfo.append(EOL); } } String systemOut = TestCaseUtils.getSystemOutContents(); if (systemOut.length() > 0) { failureInfo.append(EOL + "System.out contents:" + EOL + systemOut); opends/tests/unit-tests-testng/src/server/org/opends/server/TestLogPublisher.java
New file @@ -0,0 +1,99 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Portions Copyright 2006-2007 Sun Microsystems, Inc. */ package org.opends.server; import org.opends.server.api.LogPublisher; import org.opends.server.loggers.LoggerErrorHandler; import org.opends.server.loggers.TextLogFormatter; import org.opends.server.loggers.LogRecord; import java.util.LinkedList; import java.util.List; import java.util.ArrayList; /** * This class provides an implementation of an log publisher which will store * all messages logged in memory. It provides methods to retrieve and clear the * sets of accumulated log messages. It is only intended for use in the context * of the unit test framework, where it will provide a means of getting any * log messages associated with failed test cases. */ public class TestLogPublisher implements LogPublisher { private TextLogFormatter formatter; // The list that will hold the messages logged. private final LinkedList<String> messageList; public TestLogPublisher(TextLogFormatter formatter) { this.messageList = new LinkedList<String>(); this.formatter = formatter; } public synchronized void publish(LogRecord record, LoggerErrorHandler handler) { try { messageList.add(formatter.format(record)); } catch(Throwable t) { if(handler != null) { handler.handleError(record, t); } } } public synchronized void shutdown() { messageList.clear(); } /** * Retrieves a copy of the set of messages logged to this error logger since * the last time it was cleared. A copy of the list is returned to avoid * a ConcurrentModificationException. * * @return The set of messages logged to this error logger since the last * time it was cleared. */ public synchronized List<String> getMessages() { return new ArrayList<String>(messageList); } /** * Clears any messages currently stored by this logger. */ public synchronized void clear() { messageList.clear(); } }