From 04dfafe19f0d3687d0f0b3e51d2d5bf3d19b58bf Mon Sep 17 00:00:00 2001
From: boli <boli@localhost>
Date: Wed, 07 Mar 2007 23:38:55 +0000
Subject: [PATCH] Enable AspectJ weaving for the new debug logging framework: - This commit does not allow for configuring the debug logger over protocol. It can only be configured on server startup using properties. - The settings specified during startup will remain in effect for the duration of the server. - All messages are printed to standard out. - Weaving could be turned off with the -DDEBUG_BUILD=false property when building the server. - By default, the debug logger is off on server startup. It could be enabled by using the -Dorg.opends.server.debug.enabled=true. - Debug targets may be defined with the -Dorg.opends.server.debug.target property. The syntax of this property can be found on the opends.dev.java.net documentation section. - Debug logging is turned on by default on unit tests and printed on test failure. - Default debug target for unit tests could be changed by using the -Dorg.opends.test.debug.target property.
---
opends/src/server/org/opends/server/loggers/debug/Tracer.java | 390 +++++++--
opends/src/server/org/opends/server/extensions/TraditionalWorkerThread.java | 17
opends/src/server/org/opends/server/loggers/debug/DebugLogRecord.java | 26
opends/src/server/org/opends/server/api/DirectoryThread.java | 21
opends/src/server/org/opends/server/util/ServerConstants.java | 18
opends/src/server/org/opends/server/loggers/LoggerErrorHandler.java | 4
opends/src/server/org/opends/server/backends/task/TaskThread.java | 15
opends/src/server/org/opends/server/loggers/debug/TraceSettings.java | 145 +++
opends/src/server/org/opends/server/loggers/debug/DebugLogger.java | 74 -
opends/src/server/org/opends/server/loggers/debug/DebugConfiguration.java | 274 +++++++
opends/src/server/org/opends/server/loggers/LoggerConfiguration.java | 274 +++++++
opends/src/server/org/opends/server/api/LogPublisher.java | 4
opends/src/server/org/opends/server/types/FilePermission.java | 45 +
opends/src/server/org/opends/server/loggers/LogCategory.java | 46 +
opends/src/server/org/opends/server/loggers/TextLogPublisher.java | 3
opends/src/server/org/opends/server/loggers/debug/DebugLogFormatter.java | 40
opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java | 16
opends/tests/unit-tests-testng/src/server/org/opends/server/TestListener.java | 27
opends/src/server/org/opends/server/loggers/Logger.java | 139 +--
opends/src/server/org/opends/server/types/DebugLogCategory.java | 2
opends/src/server/org/opends/server/loggers/debug/DebugMessageFormatter.java | 273 +++++++
/dev/null | 165 ----
opends/tests/unit-tests-testng/src/server/org/opends/server/TestLogPublisher.java | 99 ++
opends/build.xml | 62 +
opends/src/server/org/opends/server/loggers/AsyncronousLogPublisher.java | 10
opends/src/server/org/opends/server/loggers/LogLevel.java | 2
26 files changed, 1,739 insertions(+), 452 deletions(-)
diff --git a/opends/build.xml b/opends/build.xml
index 13a470a..2d45b20 100644
--- a/opends/build.xml
+++ b/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" />
diff --git a/opends/src/server/org/opends/server/api/DirectoryThread.java b/opends/src/server/org/opends/server/api/DirectoryThread.java
index 9046dfe..d4c49d2 100644
--- a/opends/src/server/org/opends/server/api/DirectoryThread.java
+++ b/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;
+ }
}
diff --git a/opends/src/server/org/opends/server/api/LogPublisher.java b/opends/src/server/org/opends/server/api/LogPublisher.java
index 861c534..122d893 100644
--- a/opends/src/server/org/opends/server/api/LogPublisher.java
+++ b/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.
diff --git a/opends/src/server/org/opends/server/backends/task/TaskThread.java b/opends/src/server/org/opends/server/backends/task/TaskThread.java
index 9f3623e..3929d32 100644
--- a/opends/src/server/org/opends/server/backends/task/TaskThread.java
+++ b/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;
+ }
}
diff --git a/opends/src/server/org/opends/server/extensions/TraditionalWorkerThread.java b/opends/src/server/org/opends/server/extensions/TraditionalWorkerThread.java
index 0f41e34..a368fd6 100644
--- a/opends/src/server/org/opends/server/extensions/TraditionalWorkerThread.java
+++ b/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;
+ }
}
diff --git a/opends/src/server/org/opends/server/loggers/AsyncronousLogPublisher.java b/opends/src/server/org/opends/server/loggers/AsyncronousLogPublisher.java
index 8670895..3cff741 100644
--- a/opends/src/server/org/opends/server/loggers/AsyncronousLogPublisher.java
+++ b/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) {
diff --git a/opends/src/server/org/opends/server/loggers/LogCategory.java b/opends/src/server/org/opends/server/loggers/LogCategory.java
index e28fc76..df42e4e 100644
--- a/opends/src/server/org/opends/server/loggers/LogCategory.java
+++ b/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 + "\"");
+ }
}
diff --git a/opends/src/server/org/opends/server/loggers/LogLevel.java b/opends/src/server/org/opends/server/loggers/LogLevel.java
index 206f029..05e2c8f 100644
--- a/opends/src/server/org/opends/server/loggers/LogLevel.java
+++ b/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.
diff --git a/opends/src/server/org/opends/server/loggers/Logger.java b/opends/src/server/org/opends/server/loggers/Logger.java
index 5cab7a3..b30383f 100644
--- a/opends/src/server/org/opends/server/loggers/Logger.java
+++ b/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();
}
}
}
diff --git a/opends/src/server/org/opends/server/loggers/LoggerConfiguration.java b/opends/src/server/org/opends/server/loggers/LoggerConfiguration.java
new file mode 100644
index 0000000..52877ef
--- /dev/null
+++ b/opends/src/server/org/opends/server/loggers/LoggerConfiguration.java
@@ -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);
+ }
+ }
+}
diff --git a/opends/src/server/org/opends/server/loggers/LogErrorHandler.java b/opends/src/server/org/opends/server/loggers/LoggerErrorHandler.java
similarity index 93%
rename from opends/src/server/org/opends/server/loggers/LogErrorHandler.java
rename to opends/src/server/org/opends/server/loggers/LoggerErrorHandler.java
index a0cd43a..af36c76 100644
--- a/opends/src/server/org/opends/server/loggers/LogErrorHandler.java
+++ b/opends/src/server/org/opends/server/loggers/LoggerErrorHandler.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
diff --git a/opends/src/server/org/opends/server/loggers/TextLogPublisher.java b/opends/src/server/org/opends/server/loggers/TextLogPublisher.java
index 39b558a..e27012e 100644
--- a/opends/src/server/org/opends/server/loggers/TextLogPublisher.java
+++ b/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
{
diff --git a/opends/src/server/org/opends/server/loggers/debug/DebugConfiguration.java b/opends/src/server/org/opends/server/loggers/debug/DebugConfiguration.java
new file mode 100644
index 0000000..5672d0c
--- /dev/null
+++ b/opends/src/server/org/opends/server/loggers/debug/DebugConfiguration.java
@@ -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();
+ }
+ }
+}
diff --git a/opends/src/server/org/opends/server/loggers/debug/DebugErrorHandler.java b/opends/src/server/org/opends/server/loggers/debug/DebugErrorHandler.java
deleted file mode 100644
index 953f866..0000000
--- a/opends/src/server/org/opends/server/loggers/debug/DebugErrorHandler.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.LogErrorHandler;
-import org.opends.server.loggers.LogRecord;
-
-/**
- * Error handler for tracing. Tracing will be disabled
- * if too many errors occur.
- */
-public class DebugErrorHandler implements LogErrorHandler
-{
- 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");
-
- DebugLogger.enabled(false);
- }
- }
-}
diff --git a/opends/src/server/org/opends/server/loggers/debug/DebugLogFormatter.java b/opends/src/server/org/opends/server/loggers/debug/DebugLogFormatter.java
index 8a9b29a..13530dd 100644
--- a/opends/src/server/org/opends/server/loggers/debug/DebugLogFormatter.java
+++ b/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());
}
diff --git a/opends/src/server/org/opends/server/loggers/debug/DebugLogRecord.java b/opends/src/server/org/opends/server/loggers/debug/DebugLogRecord.java
index ae94b4f..69ce418 100644
--- a/opends/src/server/org/opends/server/loggers/debug/DebugLogRecord.java
+++ b/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;
+ }
}
diff --git a/opends/src/server/org/opends/server/loggers/debug/DebugLogger.java b/opends/src/server/org/opends/server/loggers/debug/DebugLogger.java
index f3013aa..f00b353 100644
--- a/opends/src/server/org/opends/server/loggers/debug/DebugLogger.java
+++ b/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;
}
/**
diff --git a/opends/src/server/org/opends/server/loggers/debug/DebugMessageFormatter.java b/opends/src/server/org/opends/server/loggers/debug/DebugMessageFormatter.java
new file mode 100644
index 0000000..41ff2f6
--- /dev/null
+++ b/opends/src/server/org/opends/server/loggers/debug/DebugMessageFormatter.java
@@ -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();
+ }
+}
diff --git a/opends/src/server/org/opends/server/loggers/debug/TraceConfiguration.java b/opends/src/server/org/opends/server/loggers/debug/TraceConfiguration.java
deleted file mode 100644
index 1f71697..0000000
--- a/opends/src/server/org/opends/server/loggers/debug/TraceConfiguration.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * 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.Map;
-import java.util.TreeMap;
-import java.util.HashMap;
-import java.util.Collections;
-
-/**
- * A LoggingConfiguration for the debug logging system.
- */
-public class TraceConfiguration
-{
- private static final String GLOBAL= "_global";
-
- private Map<String, TraceSettings> classTraceSettings;
- private Map<String, Map<String, TraceSettings>> methodTraceSettings;
-
-
- /**
- * Construct a default configuration where all settings are disabled.
- */
- public TraceConfiguration()
- {
- classTraceSettings = null;
- methodTraceSettings = null;
- }
-
- /**
- * 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 (DebugLogger.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 (DebugLogger.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.
- * @param scope - the scope to set trace settings for; this is a fully
- * qualified class name.
- * @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);
- }
-}
diff --git a/opends/src/server/org/opends/server/loggers/debug/TraceSettings.java b/opends/src/server/org/opends/server/loggers/debug/TraceSettings.java
index 2ea1daa..4cb7f86 100644
--- a/opends/src/server/org/opends/server/loggers/debug/TraceSettings.java
+++ b/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;
+ }
}
diff --git a/opends/src/server/org/opends/server/loggers/debug/Tracer.java b/opends/src/server/org/opends/server/loggers/debug/Tracer.java
index 687fc8d..c3f5183 100644
--- a/opends/src/server/org/opends/server/loggers/debug/Tracer.java
+++ b/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 {}
+
}
diff --git a/opends/src/server/org/opends/server/types/DebugLogCategory.java b/opends/src/server/org/opends/server/types/DebugLogCategory.java
index b8af073..67171c9 100644
--- a/opends/src/server/org/opends/server/types/DebugLogCategory.java
+++ b/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.
diff --git a/opends/src/server/org/opends/server/types/FilePermission.java b/opends/src/server/org/opends/server/types/FilePermission.java
index 7ad9cce..ba7c383 100644
--- a/opends/src/server/org/opends/server/types/FilePermission.java
+++ b/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");
+ }
}
}
diff --git a/opends/src/server/org/opends/server/util/ServerConstants.java b/opends/src/server/org/opends/server/util/ServerConstants.java
index 72b3678..7ceca54 100644
--- a/opends/src/server/org/opends/server/util/ServerConstants.java
+++ b/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;
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java
index c2b72ab..f9bd769 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java
+++ b/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.
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/TestListener.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/TestListener.java
index ee14f82..8b45097 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/TestListener.java
+++ b/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);
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/TestLogPublisher.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/TestLogPublisher.java
new file mode 100644
index 0000000..aeb3c84
--- /dev/null
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/TestLogPublisher.java
@@ -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();
+ }
+}
--
Gitblit v1.10.0