[jboss-svn-commits] JBoss Common SVN: r4812 - in jboss-logmanager/trunk: src/main/java/org/jboss/logmanager and 1 other directory.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Thu Jul 29 17:41:20 EDT 2010
Author: david.lloyd at jboss.com
Date: 2010-07-29 17:41:19 -0400 (Thu, 29 Jul 2010)
New Revision: 4812
Modified:
jboss-logmanager/trunk/pom.xml
jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/LogContext.java
jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/Logger.java
jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/LoggerNode.java
jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/LoggingMXBeanImpl.java
Log:
Attempt to fix JBLOGGING-44 by decoupling Logger instances from the LoggerNode tree, at the price of eliminating duplicate logger folding.
Modified: jboss-logmanager/trunk/pom.xml
===================================================================
--- jboss-logmanager/trunk/pom.xml 2010-07-29 20:58:23 UTC (rev 4811)
+++ jboss-logmanager/trunk/pom.xml 2010-07-29 21:41:19 UTC (rev 4812)
@@ -33,6 +33,12 @@
<packaging>jar</packaging>
<version>1.2.0.CR4-SNAPSHOT</version>
+ <parent>
+ <groupId>org.jboss</groupId>
+ <artifactId>jboss-parent</artifactId>
+ <version>5</version>
+ </parent>
+
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
@@ -50,26 +56,10 @@
<build>
<plugins>
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
- <version>2.0.2</version>
- <configuration>
- <source>1.5</source>
- <target>1.5</target>
- </configuration>
</plugin>
<plugin>
<artifactId>maven-source-plugin</artifactId>
- <version>2.1.1</version>
- <executions>
- <execution>
- <id>attach-sources</id>
- <phase>verify</phase>
- <goals>
- <goal>jar</goal>
- </goals>
- </execution>
- </executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
@@ -81,30 +71,12 @@
</plugin>
<plugin>
<artifactId>maven-enforcer-plugin</artifactId>
- <version>1.0-beta-1</version>
- <executions>
- <execution>
- <id>enforce-maven-environment</id>
- <goals>
- <goal>enforce</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <rules>
- <requireJavaVersion>
- <version>1.6.0</version>
- </requireJavaVersion>
- </rules>
- </configuration>
</plugin>
</plugins>
- <finalName>jboss-logmanager</finalName>
</build>
<reporting>
<plugins>
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.6.1</version>
<configuration>
@@ -125,11 +97,4 @@
</plugin>
</plugins>
</reporting>
- <distributionManagement>
- <repository>
- <id>repository.jboss.org</id>
- <name>JBoss Maven2 Repository</name>
- <url>http://repository.jboss.org/maven2</url>
- </repository>
- </distributionManagement>
</project>
Modified: jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/LogContext.java
===================================================================
--- jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/LogContext.java 2010-07-29 20:58:23 UTC (rev 4811)
+++ jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/LogContext.java 2010-07-29 21:41:19 UTC (rev 4812)
@@ -119,22 +119,10 @@
* @see java.util.logging.LogManager#getLogger(String)
*/
public Logger getLogger(String name) {
- return rootLogger.getOrCreate(name).getOrCreateLogger();
+ return rootLogger.getOrCreate(name).createLogger();
}
/**
- * Get a logger with the given name from this logging context if it already exists. If no logger of the given
- * name currently exists, {@code null} is returned.
- *
- * @param name the logger name
- * @return the logger instance, or {@code null} if none exists with the given name
- */
- public Logger getLoggerIfExists(String name) {
- final LoggerNode node = rootLogger.getIfExists(name);
- return node == null ? null : node.getLogger();
- }
-
- /**
* Get the {@code LoggingMXBean} associated with this log context.
*
* @return the {@code LoggingMXBean} instance
Modified: jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/Logger.java
===================================================================
--- jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/Logger.java 2010-07-29 20:58:23 UTC (rev 4811)
+++ jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/Logger.java 2010-07-29 21:41:19 UTC (rev 4812)
@@ -25,12 +25,6 @@
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.ResourceBundle;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
-import java.util.concurrent.locks.Lock;
import java.util.logging.Filter;
import java.util.logging.Handler;
@@ -50,38 +44,6 @@
*/
private final LoggerNode loggerNode;
- /**
- * The handlers for this logger. May only be updated using the {@link #handlersUpdater} atomic updater. The array
- * instance should not be modified (treat as immutable).
- */
- @SuppressWarnings({ "UnusedDeclaration" })
- private volatile Handler[] handlers;
-
- /**
- * Flag to specify whether parent handlers are used.
- */
- private volatile boolean useParentHandlers = true;
-
- /**
- * The filter for this logger instance.
- */
- private volatile Filter filter;
-
- /**
- * The attachments map.
- */
- private volatile Map<AttachmentKey, Object> attachments = Collections.emptyMap();
-
- /**
- * The atomic updater for the {@link #handlers} field.
- */
- private static final AtomicArray<Logger, Handler> handlersUpdater = AtomicArray.create(AtomicReferenceFieldUpdater.newUpdater(Logger.class, Handler[].class, "handlers"), Handler.class);
-
- /**
- * The atomic updater for the {@link #attachments} field.
- */
- private static final AtomicReferenceFieldUpdater<Logger, Map> attachmentsUpdater = AtomicReferenceFieldUpdater.newUpdater(Logger.class, Map.class, "attachments");
-
private static final String LOGGER_CLASS_NAME = Logger.class.getName();
/**
@@ -127,7 +89,6 @@
// We maintain our own level
super.setLevel(Level.ALL);
this.loggerNode = loggerNode;
- handlersUpdater.clear(this);
}
// Serialization
@@ -141,61 +102,24 @@
/** {@inheritDoc} */
public void setFilter(Filter filter) throws SecurityException {
LogContext.checkAccess();
- this.filter = filter;
+ loggerNode.setFilter(filter);
}
/** {@inheritDoc} */
public Filter getFilter() {
- return filter;
+ return loggerNode.getFilter();
}
// Level mgmt
/**
- * The actual level. May only be modified when the logmanager's level change lock is held; in addition, changing
- * this field must be followed immediately by recursively updating the effective loglevel of the child tree.
- */
- private volatile Level level;
- /**
- * The effective level. May only be modified when the logmanager's level change lock is held; in addition, changing
- * this field must be followed immediately by recursively updating the effective loglevel of the child tree.
- */
- private volatile int effectiveLevel = INFO_INT;
-
- /**
* {@inheritDoc} This implementation grabs a lock, so that only one thread may update the log level of any
* logger at a time, in order to allow readers to never block (though there is a window where retrieving the
* log level reflects an older effective level than the actual level).
*/
public void setLevel(Level newLevel) throws SecurityException {
LogContext.checkAccess();
- final LogContext context = loggerNode.getContext();
- final Lock lock = context.treeLock;
- lock.lock();
- try {
- final int oldEffectiveLevel = effectiveLevel;
- final int newEffectiveLevel;
- if (newLevel != null) {
- level = newLevel;
- newEffectiveLevel = newLevel.intValue();
- } else {
- final Logger parent = (Logger) getParent();
- if (parent == null) {
- level = Level.INFO;
- newEffectiveLevel = INFO_INT;
- } else {
- level = null;
- newEffectiveLevel = parent.effectiveLevel;
- }
- }
- effectiveLevel = newEffectiveLevel;
- if (oldEffectiveLevel != newEffectiveLevel) {
- // our level changed, recurse down to children
- loggerNode.updateChildEffectiveLevel(newEffectiveLevel);
- }
- } finally {
- lock.unlock();
- }
+ loggerNode.setLevel(newLevel);
}
/**
@@ -210,35 +134,22 @@
}
/**
- * Update the effective level if it is inherited from a parent. Must only be called while the logmanager's level
- * change lock is held.
- *
- * @param newLevel the new effective level
- */
- void setEffectiveLevel(int newLevel) {
- if (level == null) {
- effectiveLevel = newLevel;
- loggerNode.updateChildEffectiveLevel(newLevel);
- }
- }
-
- /**
* Get the effective numerical log level, inherited from the parent.
*
* @return the effective level
*/
public int getEffectiveLevel() {
- return effectiveLevel;
+ return loggerNode.getEffectiveLevel();
}
/** {@inheritDoc} */
public Level getLevel() {
- return level;
+ return loggerNode.getLevel();
}
/** {@inheritDoc} */
public boolean isLoggable(Level level) {
- final int effectiveLevel = this.effectiveLevel;
+ final int effectiveLevel = loggerNode.getEffectiveLevel();
return level.intValue() >= effectiveLevel && effectiveLevel != OFF_INT;
}
@@ -253,11 +164,7 @@
*/
@SuppressWarnings({ "unchecked" })
public <V> V getAttachment(AttachmentKey<V> key) {
- if (key == null) {
- throw new NullPointerException("key is null");
- }
- final Map<AttachmentKey, Object> attachments = this.attachments;
- return (V) attachments.get(key);
+ return loggerNode.getAttachment(key);
}
/**
@@ -270,29 +177,9 @@
* @return the old attachment, if there was one
* @throws SecurityException if a security manager exists and if the caller does not have {@code LoggingPermission(control)}
*/
- @SuppressWarnings({ "unchecked" })
public <V> V attach(AttachmentKey<V> key, V value) throws SecurityException {
LogContext.checkAccess();
- if (key == null) {
- throw new NullPointerException("key is null");
- }
- if (value == null) {
- throw new NullPointerException("value is null");
- }
- Map<AttachmentKey, Object> oldAttachments;
- Map<AttachmentKey, Object> newAttachments;
- V old;
- do {
- oldAttachments = attachments;
- if (oldAttachments.isEmpty() || oldAttachments.size() == 1 && oldAttachments.containsKey(key)) {
- old = (V) oldAttachments.get(key);
- newAttachments = Collections.<AttachmentKey, Object>singletonMap(key, value);
- } else {
- newAttachments = new HashMap<AttachmentKey, Object>(oldAttachments);
- old = (V) newAttachments.put(key, value);
- }
- } while (! attachmentsUpdater.compareAndSet(this, oldAttachments, newAttachments));
- return old;
+ return loggerNode.attach(key, value);
}
/**
@@ -308,27 +195,7 @@
@SuppressWarnings({ "unchecked" })
public <V> V attachIfAbsent(AttachmentKey<V> key, V value) throws SecurityException {
LogContext.checkAccess();
- if (key == null) {
- throw new NullPointerException("key is null");
- }
- if (value == null) {
- throw new NullPointerException("value is null");
- }
- Map<AttachmentKey, Object> oldAttachments;
- Map<AttachmentKey, Object> newAttachments;
- do {
- oldAttachments = attachments;
- if (oldAttachments.isEmpty()) {
- newAttachments = Collections.<AttachmentKey, Object>singletonMap(key, value);
- } else {
- if (oldAttachments.containsKey(key)) {
- return (V) oldAttachments.get(key);
- }
- newAttachments = new HashMap<AttachmentKey, Object>(oldAttachments);
- newAttachments.put(key, value);
- }
- } while (! attachmentsUpdater.compareAndSet(this, oldAttachments, newAttachments));
- return null;
+ return loggerNode.attachIfAbsent(key, value);
}
/**
@@ -342,37 +209,7 @@
@SuppressWarnings({ "unchecked" })
public <V> V detach(AttachmentKey<V> key) throws SecurityException {
LogContext.checkAccess();
- if (key == null) {
- throw new NullPointerException("key is null");
- }
- Map<AttachmentKey, Object> oldAttachments;
- Map<AttachmentKey, Object> newAttachments;
- V result;
- do {
- oldAttachments = attachments;
- result = (V) oldAttachments.get(key);
- if (result == null) {
- return null;
- }
- final int size = oldAttachments.size();
- if (size == 1) {
- // special case - the new map is empty
- newAttachments = Collections.emptyMap();
- } else if (size == 2) {
- // special case - the new map is a singleton
- final Iterator<Map.Entry<AttachmentKey,Object>> it = oldAttachments.entrySet().iterator();
- // find the entry that we are not removing
- Map.Entry<AttachmentKey, Object> entry = it.next();
- if (entry.getKey() == key) {
- // must be the next one
- entry = it.next();
- }
- newAttachments = Collections.singletonMap(entry.getKey(), entry.getValue());
- } else {
- newAttachments = new HashMap<AttachmentKey, Object>(oldAttachments);
- }
- } while (! attachmentsUpdater.compareAndSet(this, oldAttachments, newAttachments));
- return result;
+ return loggerNode.detach(key);
}
// Handler mgmt
@@ -383,7 +220,7 @@
if (handler == null) {
throw new NullPointerException("handler is null");
}
- handlersUpdater.add(this, handler);
+ loggerNode.addHandler(handler);
}
/** {@inheritDoc} */
@@ -392,12 +229,12 @@
if (handler == null) {
return;
}
- handlersUpdater.remove(this, handler, true);
+ loggerNode.removeHandler(handler);
}
/** {@inheritDoc} */
public Handler[] getHandlers() {
- final Handler[] handlers = this.handlers;
+ final Handler[] handlers = loggerNode.getHandlers();
return handlers.length > 0 ? handlers.clone() : handlers;
}
@@ -408,26 +245,25 @@
*/
public Handler[] clearHandlers() throws SecurityException {
LogContext.checkAccess();
- final Handler[] handlers = this.handlers;
- handlersUpdater.clear(this);
- return handlers.length > 0 ? handlers.clone() : handlers;
+ return loggerNode.clearHandlers();
}
/** {@inheritDoc} */
public void setUseParentHandlers(boolean useParentHandlers) {
- this.useParentHandlers = useParentHandlers;
+ loggerNode.setUseParentHandlers(useParentHandlers);
}
/** {@inheritDoc} */
public boolean getUseParentHandlers() {
- return useParentHandlers;
+ return loggerNode.getUseParentHandlers();
}
// Parent/child
/** {@inheritDoc} */
public Logger getParent() {
- return loggerNode.getParentLogger();
+ final LoggerNode parentNode = loggerNode.getParent();
+ return parentNode == null ? null : parentNode.createLogger();
}
/**
@@ -440,19 +276,19 @@
// Logger
- private static final int OFF_INT = Level.OFF.intValue();
+ static final int OFF_INT = Level.OFF.intValue();
- private static final int SEVERE_INT = Level.SEVERE.intValue();
- private static final int WARNING_INT = Level.WARNING.intValue();
- private static final int INFO_INT = Level.INFO.intValue();
- private static final int CONFIG_INT = Level.CONFIG.intValue();
- private static final int FINE_INT = Level.FINE.intValue();
- private static final int FINER_INT = Level.FINER.intValue();
- private static final int FINEST_INT = Level.FINEST.intValue();
+ static final int SEVERE_INT = Level.SEVERE.intValue();
+ static final int WARNING_INT = Level.WARNING.intValue();
+ static final int INFO_INT = Level.INFO.intValue();
+ static final int CONFIG_INT = Level.CONFIG.intValue();
+ static final int FINE_INT = Level.FINE.intValue();
+ static final int FINER_INT = Level.FINER.intValue();
+ static final int FINEST_INT = Level.FINEST.intValue();
/** {@inheritDoc} */
public void log(LogRecord record) {
- final int effectiveLevel = this.effectiveLevel;
+ final int effectiveLevel = loggerNode.getEffectiveLevel();
if (record.getLevel().intValue() < effectiveLevel || effectiveLevel == OFF_INT) {
return;
}
@@ -461,7 +297,7 @@
/** {@inheritDoc} */
public void entering(final String sourceClass, final String sourceMethod) {
- if (FINER_INT < effectiveLevel) {
+ if (FINER_INT < loggerNode.getEffectiveLevel()) {
return;
}
final ExtLogRecord rec = new ExtLogRecord(Level.FINER, "ENTRY", LOGGER_CLASS_NAME);
@@ -472,7 +308,7 @@
/** {@inheritDoc} */
public void entering(final String sourceClass, final String sourceMethod, final Object param1) {
- if (FINER_INT < effectiveLevel) {
+ if (FINER_INT < loggerNode.getEffectiveLevel()) {
return;
}
final ExtLogRecord rec = new ExtLogRecord(Level.FINER, "ENTRY {0}", LOGGER_CLASS_NAME);
@@ -484,7 +320,7 @@
/** {@inheritDoc} */
public void entering(final String sourceClass, final String sourceMethod, final Object[] params) {
- if (FINER_INT < effectiveLevel) {
+ if (FINER_INT < loggerNode.getEffectiveLevel()) {
return;
}
final StringBuilder builder = new StringBuilder("ENTRY");
@@ -500,7 +336,7 @@
/** {@inheritDoc} */
public void exiting(final String sourceClass, final String sourceMethod) {
- if (FINER_INT < effectiveLevel) {
+ if (FINER_INT < loggerNode.getEffectiveLevel()) {
return;
}
final ExtLogRecord rec = new ExtLogRecord(Level.FINER, "RETURN", LOGGER_CLASS_NAME);
@@ -511,7 +347,7 @@
/** {@inheritDoc} */
public void exiting(final String sourceClass, final String sourceMethod, final Object result) {
- if (FINER_INT < effectiveLevel) {
+ if (FINER_INT < loggerNode.getEffectiveLevel()) {
return;
}
final ExtLogRecord rec = new ExtLogRecord(Level.FINER, "RETURN {0}", LOGGER_CLASS_NAME);
@@ -523,7 +359,7 @@
/** {@inheritDoc} */
public void throwing(final String sourceClass, final String sourceMethod, final Throwable thrown) {
- if (FINER_INT < effectiveLevel) {
+ if (FINER_INT < loggerNode.getEffectiveLevel()) {
return;
}
final ExtLogRecord rec = new ExtLogRecord(Level.FINER, "THROW", LOGGER_CLASS_NAME);
@@ -535,7 +371,7 @@
/** {@inheritDoc} */
public void severe(final String msg) {
- if (SEVERE_INT < effectiveLevel) {
+ if (SEVERE_INT < loggerNode.getEffectiveLevel()) {
return;
}
logRaw(new ExtLogRecord(Level.SEVERE, msg, LOGGER_CLASS_NAME));
@@ -543,7 +379,7 @@
/** {@inheritDoc} */
public void warning(final String msg) {
- if (WARNING_INT < effectiveLevel) {
+ if (WARNING_INT < loggerNode.getEffectiveLevel()) {
return;
}
logRaw(new ExtLogRecord(Level.WARNING, msg, LOGGER_CLASS_NAME));
@@ -551,7 +387,7 @@
/** {@inheritDoc} */
public void info(final String msg) {
- if (INFO_INT < effectiveLevel) {
+ if (INFO_INT < loggerNode.getEffectiveLevel()) {
return;
}
logRaw(new ExtLogRecord(Level.INFO, msg, LOGGER_CLASS_NAME));
@@ -559,7 +395,7 @@
/** {@inheritDoc} */
public void config(final String msg) {
- if (CONFIG_INT < effectiveLevel) {
+ if (CONFIG_INT < loggerNode.getEffectiveLevel()) {
return;
}
logRaw(new ExtLogRecord(Level.CONFIG, msg, LOGGER_CLASS_NAME));
@@ -567,7 +403,7 @@
/** {@inheritDoc} */
public void fine(final String msg) {
- if (FINE_INT < effectiveLevel) {
+ if (FINE_INT < loggerNode.getEffectiveLevel()) {
return;
}
logRaw(new ExtLogRecord(Level.FINE, msg, LOGGER_CLASS_NAME));
@@ -575,7 +411,7 @@
/** {@inheritDoc} */
public void finer(final String msg) {
- if (FINER_INT < effectiveLevel) {
+ if (FINER_INT < loggerNode.getEffectiveLevel()) {
return;
}
logRaw(new ExtLogRecord(Level.FINER, msg, LOGGER_CLASS_NAME));
@@ -583,7 +419,7 @@
/** {@inheritDoc} */
public void finest(final String msg) {
- if (FINEST_INT < effectiveLevel) {
+ if (FINEST_INT < loggerNode.getEffectiveLevel()) {
return;
}
logRaw(new ExtLogRecord(Level.FINEST, msg, LOGGER_CLASS_NAME));
@@ -591,7 +427,7 @@
/** {@inheritDoc} */
public void log(final Level level, final String msg) {
- final int effectiveLevel = this.effectiveLevel;
+ final int effectiveLevel = loggerNode.getEffectiveLevel();
if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) {
return;
}
@@ -600,7 +436,7 @@
/** {@inheritDoc} */
public void log(final Level level, final String msg, final Object param1) {
- final int effectiveLevel = this.effectiveLevel;
+ final int effectiveLevel = loggerNode.getEffectiveLevel();
if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) {
return;
}
@@ -611,7 +447,7 @@
/** {@inheritDoc} */
public void log(final Level level, final String msg, final Object[] params) {
- final int effectiveLevel = this.effectiveLevel;
+ final int effectiveLevel = loggerNode.getEffectiveLevel();
if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) {
return;
}
@@ -622,7 +458,7 @@
/** {@inheritDoc} */
public void log(final Level level, final String msg, final Throwable thrown) {
- final int effectiveLevel = this.effectiveLevel;
+ final int effectiveLevel = loggerNode.getEffectiveLevel();
if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) {
return;
}
@@ -633,7 +469,7 @@
/** {@inheritDoc} */
public void logp(final Level level, final String sourceClass, final String sourceMethod, final String msg) {
- final int effectiveLevel = this.effectiveLevel;
+ final int effectiveLevel = loggerNode.getEffectiveLevel();
if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) {
return;
}
@@ -645,7 +481,7 @@
/** {@inheritDoc} */
public void logp(final Level level, final String sourceClass, final String sourceMethod, final String msg, final Object param1) {
- final int effectiveLevel = this.effectiveLevel;
+ final int effectiveLevel = loggerNode.getEffectiveLevel();
if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) {
return;
}
@@ -658,7 +494,7 @@
/** {@inheritDoc} */
public void logp(final Level level, final String sourceClass, final String sourceMethod, final String msg, final Object[] params) {
- final int effectiveLevel = this.effectiveLevel;
+ final int effectiveLevel = loggerNode.getEffectiveLevel();
if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) {
return;
}
@@ -671,7 +507,7 @@
/** {@inheritDoc} */
public void logp(final Level level, final String sourceClass, final String sourceMethod, final String msg, final Throwable thrown) {
- final int effectiveLevel = this.effectiveLevel;
+ final int effectiveLevel = loggerNode.getEffectiveLevel();
if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) {
return;
}
@@ -684,7 +520,7 @@
/** {@inheritDoc} */
public void logrb(final Level level, final String sourceClass, final String sourceMethod, final String bundleName, final String msg) {
- final int effectiveLevel = this.effectiveLevel;
+ final int effectiveLevel = loggerNode.getEffectiveLevel();
if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) {
return;
}
@@ -697,7 +533,7 @@
/** {@inheritDoc} */
public void logrb(final Level level, final String sourceClass, final String sourceMethod, final String bundleName, final String msg, final Object param1) {
- final int effectiveLevel = this.effectiveLevel;
+ final int effectiveLevel = loggerNode.getEffectiveLevel();
if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) {
return;
}
@@ -711,7 +547,7 @@
/** {@inheritDoc} */
public void logrb(final Level level, final String sourceClass, final String sourceMethod, final String bundleName, final String msg, final Object[] params) {
- final int effectiveLevel = this.effectiveLevel;
+ final int effectiveLevel = loggerNode.getEffectiveLevel();
if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) {
return;
}
@@ -725,7 +561,7 @@
/** {@inheritDoc} */
public void logrb(final Level level, final String sourceClass, final String sourceMethod, final String bundleName, final String msg, final Throwable thrown) {
- final int effectiveLevel = this.effectiveLevel;
+ final int effectiveLevel = loggerNode.getEffectiveLevel();
if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) {
return;
}
@@ -767,7 +603,7 @@
* @param t the throwable, if any
*/
public void log(final String fqcn, final Level level, final String message, final String bundleName, final ExtLogRecord.FormatStyle style, final Object[] params, final Throwable t) {
- final int effectiveLevel = this.effectiveLevel;
+ final int effectiveLevel = loggerNode.getEffectiveLevel();
if (level == null || fqcn == null || message == null || level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) {
return;
}
@@ -789,7 +625,7 @@
* @param t the throwable, if any
*/
public void log(final String fqcn, final Level level, final String message, final ExtLogRecord.FormatStyle style, final Object[] params, final Throwable t) {
- final int effectiveLevel = this.effectiveLevel;
+ final int effectiveLevel = loggerNode.getEffectiveLevel();
if (level == null || fqcn == null || message == null || level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) {
return;
}
@@ -831,7 +667,7 @@
record.setResourceBundleName(bundleName);
record.setResourceBundle(bundle);
}
- final Filter filter = this.filter;
+ final Filter filter = loggerNode.getFilter();
try {
if (filter != null && ! filter.isLoggable(record)) {
return;
@@ -842,21 +678,7 @@
// todo - error handler
// treat an errored filter as "pass" (I guess?)
}
- for (Logger current = this; current != null; current = current.getParent()) {
- final Handler[] handlers = current.handlers;
- if (handlers != null) {
- for (Handler handler : handlers) try {
- handler.publish(record);
- } catch (VirtualMachineError e) {
- throw e;
- } catch (Throwable t) {
- // todo - error handler
- }
- }
- if (! current.useParentHandlers) {
- break;
- }
- }
+ loggerNode.publish(record);
}
/**
Modified: jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/LoggerNode.java
===================================================================
--- jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/LoggerNode.java 2010-07-29 20:58:23 UTC (rev 4811)
+++ jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/LoggerNode.java 2010-07-29 21:41:19 UTC (rev 4812)
@@ -22,13 +22,21 @@
package org.jboss.logmanager;
-import java.lang.ref.WeakReference;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+import java.util.concurrent.locks.Lock;
+import java.util.logging.Filter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+
/**
* A node in the tree of logger names. Maintains weak references to children and a strong reference to its parent.
*/
@@ -48,21 +56,54 @@
private final String fullName;
/**
- * A weak reference to the logger instance. Only update using {@link #loggerRefUpdater}.
+ * The map of names to child nodes. The child node references are weak.
*/
- private volatile LoggerRef loggerRef = null;
+ private final ConcurrentMap<String, LoggerNode> children = new CopyOnWriteWeakMap<String, LoggerNode>();
/**
- * The atomic updater for {@link #loggerRef}.
+ * The handlers for this logger. May only be updated using the {@link #handlersUpdater} atomic updater. The array
+ * instance should not be modified (treat as immutable).
*/
- private static final AtomicReferenceFieldUpdater<LoggerNode, LoggerRef> loggerRefUpdater = AtomicReferenceFieldUpdater.newUpdater(LoggerNode.class, LoggerRef.class, "loggerRef");
+ @SuppressWarnings({ "UnusedDeclaration" })
+ private volatile Handler[] handlers;
/**
- * The map of names to child nodes. The child node references are weak.
+ * Flag to specify whether parent handlers are used.
*/
- private final ConcurrentMap<String, LoggerNode> children = new CopyOnWriteWeakMap<String, LoggerNode>();
+ private volatile boolean useParentHandlers = true;
/**
+ * The filter for this logger instance.
+ */
+ private volatile Filter filter;
+
+ /**
+ * The attachments map.
+ */
+ private volatile Map<Logger.AttachmentKey, Object> attachments = Collections.emptyMap();
+
+ /**
+ * The atomic updater for the {@link #handlers} field.
+ */
+ private static final AtomicArray<LoggerNode, Handler> handlersUpdater = AtomicArray.create(AtomicReferenceFieldUpdater.newUpdater(LoggerNode.class, Handler[].class, "handlers"), Handler.class);
+
+ /**
+ * The atomic updater for the {@link #attachments} field.
+ */
+ private static final AtomicReferenceFieldUpdater<LoggerNode, Map> attachmentsUpdater = AtomicReferenceFieldUpdater.newUpdater(LoggerNode.class, Map.class, "attachments");
+
+ /**
+ * The actual level. May only be modified when the context's level change lock is held; in addition, changing
+ * this field must be followed immediately by recursively updating the effective loglevel of the child tree.
+ */
+ private volatile java.util.logging.Level level;
+ /**
+ * The effective level. May only be modified when the context's level change lock is held; in addition, changing
+ * this field must be followed immediately by recursively updating the effective loglevel of the child tree.
+ */
+ private volatile int effectiveLevel = Logger.INFO_INT;
+
+ /**
* Construct a new root instance.
*
* @param context the logmanager
@@ -70,6 +111,7 @@
LoggerNode(final LogContext context) {
parent = null;
fullName = "";
+ handlersUpdater.clear(this);
this.context = context;
}
@@ -86,6 +128,7 @@
throw new IllegalArgumentException("nodeName is empty, or just whitespace");
}
this.parent = parent;
+ handlersUpdater.clear(this);
if (parent.parent == null) {
fullName = nodeName;
} else {
@@ -146,30 +189,7 @@
}
}
- /**
- * Get or create a logger instance for this node.
- *
- * @return a logger instance
- */
- Logger getOrCreateLogger() {
- final String fullName = this.fullName;
- final LoggerNode parent = this.parent;
- for (;;) {
- final LoggerRef loggerRef = this.loggerRef;
- if (loggerRef != null) {
- final Logger logger = loggerRef.get();
- if (logger != null) {
- return logger;
- }
- }
- final Logger logger = createLogger(fullName);
- if (loggerRefUpdater.compareAndSet(this, loggerRef, parent == null ? new StrongLoggerRef(logger) : new WeakLoggerRef(logger))) {
- return logger;
- }
- }
- }
-
- private Logger createLogger(final String fullName) {
+ Logger createLogger() {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
return AccessController.doPrivileged(new PrivilegedAction<Logger>() {
@@ -189,16 +209,6 @@
}
/**
- * Get a logger instance for this node.
- *
- * @return a logger instance
- */
- Logger getLogger() {
- final LoggerRef loggerRef = this.loggerRef;
- return loggerRef == null ? null : loggerRef.get();
- }
-
- /**
* Get the children of this logger.
*
* @return the children
@@ -208,23 +218,6 @@
}
/**
- * Return the logger instance of the parent logger node, or {@code null} if this is the root logger node.
- *
- * @return the parent logger instance, or {@code null} for none
- */
- Logger getParentLogger() {
- LoggerNode node = parent;
- while (node != null) {
- final Logger instance = node.getLogger();
- if (instance != null) {
- return instance;
- }
- node = node.parent;
- }
- return null;
- }
-
- /**
* Get the log context.
*
* @return the log context
@@ -234,44 +227,211 @@
}
/**
- * Recursively update the effective log level of all log instances on all children. The recursion depth will be proportionate to the
- * log node nesting depth so stack use should not be an issue. Must only be called while the log context's level
+ * Update the effective level if it is inherited from a parent. Must only be called while the logmanager's level
* change lock is held.
*
* @param newLevel the new effective level
*/
- void updateChildEffectiveLevel(int newLevel) {
- for (LoggerNode node : children.values()) {
- if (node != null) {
- final Logger instance = node.getLogger();
- if (instance != null) {
- instance.setEffectiveLevel(newLevel);
+ void setEffectiveLevel(int newLevel) {
+ if (level == null) {
+ effectiveLevel = newLevel;
+ for (LoggerNode node : children.values()) {
+ if (node != null) {
+ node.setEffectiveLevel(newLevel);
+ }
+ }
+ }
+ }
+
+ void setFilter(final Filter filter) {
+ this.filter = filter;
+ }
+
+ Filter getFilter() {
+ return filter;
+ }
+
+ int getEffectiveLevel() {
+ return effectiveLevel;
+ }
+
+ Handler[] getHandlers() {
+ return handlers;
+ }
+
+ Handler[] clearHandlers() {
+ final Handler[] handlers = this.handlers;
+ handlersUpdater.clear(this);
+ return handlers.length > 0 ? handlers.clone() : handlers;
+ }
+
+ void removeHandler(final Handler handler) {
+ handlersUpdater.remove(this, handler, true);
+ }
+
+ void addHandler(final Handler handler) {
+ handlersUpdater.add(this, handler);
+ }
+
+ boolean getUseParentHandlers() {
+ return useParentHandlers;
+ }
+
+ void setUseParentHandlers(final boolean useParentHandlers) {
+ this.useParentHandlers = useParentHandlers;
+ }
+
+ void publish(final ExtLogRecord record) {
+ for (Handler handler : handlers) try {
+ handler.publish(record);
+ } catch (VirtualMachineError e) {
+ throw e;
+ } catch (Throwable t) {
+ // todo - error handler
+ }
+ if (useParentHandlers) {
+ final LoggerNode parent = this.parent;
+ if (parent != null) parent.publish(record);
+ }
+ }
+
+ void setLevel(final Level newLevel) {
+ final LogContext context = this.context;
+ final Lock lock = context.treeLock;
+ lock.lock();
+ try {
+ final int oldEffectiveLevel = effectiveLevel;
+ final int newEffectiveLevel;
+ if (newLevel != null) {
+ level = newLevel;
+ newEffectiveLevel = newLevel.intValue();
+ } else {
+ final LoggerNode parent = this.parent;
+ if (parent == null) {
+ level = Level.INFO;
+ newEffectiveLevel = Logger.INFO_INT;
} else {
- node.updateChildEffectiveLevel(newLevel);
+ level = null;
+ newEffectiveLevel = parent.effectiveLevel;
}
}
+ effectiveLevel = newEffectiveLevel;
+ if (oldEffectiveLevel != newEffectiveLevel) {
+ // our level changed, recurse down to children
+ for (LoggerNode node : children.values()) {
+ if (node != null) {
+ node.setEffectiveLevel(newEffectiveLevel);
+ }
+ }
+ }
+ } finally {
+ lock.unlock();
}
+
}
- private interface LoggerRef {
- Logger get();
+ Level getLevel() {
+ return level;
}
- private static final class WeakLoggerRef extends WeakReference<Logger> implements LoggerRef {
- private WeakLoggerRef(Logger referent) {
- super(referent);
+ @SuppressWarnings({ "unchecked" })
+ <V> V getAttachment(final Logger.AttachmentKey<V> key) {
+ if (key == null) {
+ throw new NullPointerException("key is null");
}
+ final Map<Logger.AttachmentKey, Object> attachments = this.attachments;
+ return (V) attachments.get(key);
}
- private static final class StrongLoggerRef implements LoggerRef {
- private final Logger logger;
+ @SuppressWarnings({ "unchecked" })
+ <V> V attach(final Logger.AttachmentKey<V> key, final V value) {
+ if (key == null) {
+ throw new NullPointerException("key is null");
+ }
+ if (value == null) {
+ throw new NullPointerException("value is null");
+ }
+ Map<Logger.AttachmentKey, Object> oldAttachments;
+ Map<Logger.AttachmentKey, Object> newAttachments;
+ V old;
+ do {
+ oldAttachments = attachments;
+ if (oldAttachments.isEmpty() || oldAttachments.size() == 1 && oldAttachments.containsKey(key)) {
+ old = (V) oldAttachments.get(key);
+ newAttachments = Collections.<Logger.AttachmentKey, Object>singletonMap(key, value);
+ } else {
+ newAttachments = new HashMap<Logger.AttachmentKey, Object>(oldAttachments);
+ old = (V) newAttachments.put(key, value);
+ }
+ } while (! attachmentsUpdater.compareAndSet(this, oldAttachments, newAttachments));
+ return old;
+ }
- private StrongLoggerRef(final Logger logger) {
- this.logger = logger;
+ @SuppressWarnings({ "unchecked" })
+ <V> V attachIfAbsent(final Logger.AttachmentKey<V> key, final V value) {
+ if (key == null) {
+ throw new NullPointerException("key is null");
}
+ if (value == null) {
+ throw new NullPointerException("value is null");
+ }
+ Map<Logger.AttachmentKey, Object> oldAttachments;
+ Map<Logger.AttachmentKey, Object> newAttachments;
+ do {
+ oldAttachments = attachments;
+ if (oldAttachments.isEmpty()) {
+ newAttachments = Collections.<Logger.AttachmentKey, Object>singletonMap(key, value);
+ } else {
+ if (oldAttachments.containsKey(key)) {
+ return (V) oldAttachments.get(key);
+ }
+ newAttachments = new HashMap<Logger.AttachmentKey, Object>(oldAttachments);
+ newAttachments.put(key, value);
+ }
+ } while (! attachmentsUpdater.compareAndSet(this, oldAttachments, newAttachments));
+ return null;
+ }
- public Logger get() {
- return logger;
+ @SuppressWarnings({ "unchecked" })
+ public <V> V detach(final Logger.AttachmentKey<V> key) {
+ if (key == null) {
+ throw new NullPointerException("key is null");
}
+ Map<Logger.AttachmentKey, Object> oldAttachments;
+ Map<Logger.AttachmentKey, Object> newAttachments;
+ V result;
+ do {
+ oldAttachments = attachments;
+ result = (V) oldAttachments.get(key);
+ if (result == null) {
+ return null;
+ }
+ final int size = oldAttachments.size();
+ if (size == 1) {
+ // special case - the new map is empty
+ newAttachments = Collections.emptyMap();
+ } else if (size == 2) {
+ // special case - the new map is a singleton
+ final Iterator<Map.Entry<Logger.AttachmentKey,Object>> it = oldAttachments.entrySet().iterator();
+ // find the entry that we are not removing
+ Map.Entry<Logger.AttachmentKey, Object> entry = it.next();
+ if (entry.getKey() == key) {
+ // must be the next one
+ entry = it.next();
+ }
+ newAttachments = Collections.singletonMap(entry.getKey(), entry.getValue());
+ } else {
+ newAttachments = new HashMap<Logger.AttachmentKey, Object>(oldAttachments);
+ }
+ } while (! attachmentsUpdater.compareAndSet(this, oldAttachments, newAttachments));
+ return result;
}
+
+ String getFullName() {
+ return fullName;
+ }
+
+ LoggerNode getParent() {
+ return parent;
+ }
}
Modified: jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/LoggingMXBeanImpl.java
===================================================================
--- jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/LoggingMXBeanImpl.java 2010-07-29 20:58:23 UTC (rev 4811)
+++ jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/LoggingMXBeanImpl.java 2010-07-29 21:41:19 UTC (rev 4812)
@@ -36,12 +36,9 @@
}
private void getAllNames(List<String> names, LoggerNode node) {
- final Logger logger = node.getLogger();
- if (logger != null) {
- names.add(logger.getName());
- }
+ names.add(node.getFullName());
for (LoggerNode loggerNode : node.getChildren()) {
- getAllNames(names, loggerNode);
+ if (loggerNode != null) getAllNames(names, loggerNode);
}
}
@@ -53,25 +50,25 @@
}
public String getLoggerLevel(final String loggerName) {
- final Logger logger = context.getLoggerIfExists(loggerName);
- final Level level = logger == null ? null : logger.getLevel();
+ final LoggerNode loggerNode = context.getRootLoggerNode().getIfExists(loggerName);
+ final Level level = loggerNode == null ? null : loggerNode.getLevel();
return level == null ? "" : level.getName();
}
public void setLoggerLevel(final String loggerName, final String levelName) {
- final Logger logger = context.getLoggerIfExists(loggerName);
- if (logger == null) {
+ final LoggerNode loggerNode = context.getRootLoggerNode().getIfExists(loggerName);
+ if (loggerNode == null) {
throw new IllegalArgumentException("logger \"" + loggerName + "\" does not exist");
}
- logger.setLevel(levelName == null ? null : context.getLevelForName(levelName));
+ loggerNode.setLevel(levelName == null ? null : context.getLevelForName(levelName));
}
public String getParentLoggerName(final String loggerName) {
- final Logger logger = context.getLoggerIfExists(loggerName);
- if (logger == null) {
- return null;
+ final int dotIdx = loggerName.lastIndexOf('.');
+ if (dotIdx == -1) {
+ return "";
+ } else {
+ return loggerName.substring(0, dotIdx);
}
- final Logger parent = logger.getParent();
- return parent == null ? "" : parent.getName();
}
}
More information about the jboss-svn-commits
mailing list