Index: ../../jboss-logmanager/src/main/java/org/jboss/logmanager/ForcingLogChecker.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../../jboss-logmanager/src/main/java/org/jboss/logmanager/ForcingLogChecker.java (revision ) +++ ../../jboss-logmanager/src/main/java/org/jboss/logmanager/ForcingLogChecker.java (revision ) @@ -0,0 +1,36 @@ +/* + * JBoss, Home of Professional Open Source. + * + * Copyright 2014 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jboss.logmanager; + +public class ForcingLogChecker { + private Boolean value; + + /** + * @return Returns defined by the forceLoggingFeatureEnabled system property. + */ + public boolean isForcingLogFeatureEnabled() { + if (value == null) { + // need to check system property every time because at class load time + // (from -Djava.util.logging.manager="org.jboss.logmanager.LogManager") the "forceLoggingFeatureEnabled" + // parameter is still not available. + value = "true".equalsIgnoreCase(System.getProperty("forceLoggingFeatureEnabled", "false")); + } + return value; + } +} Index: ../../jboss-logmanager/src/main/java/org/jboss/logmanager/ExtLogRecord.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../../jboss-logmanager/src/main/java/org/jboss/logmanager/ExtLogRecord.java (revision b3ce9607f91bbd5686a60a29e4c07bfef23e277e) +++ ../../jboss-logmanager/src/main/java/org/jboss/logmanager/ExtLogRecord.java (revision ) @@ -141,6 +141,7 @@ private String resourceKey; private String formattedMessage; private String threadName; + private boolean forcingLog; private void writeObject(ObjectOutputStream oos) throws IOException { copyAll(); @@ -449,6 +450,20 @@ } // should be unreachable return msg; + } + + /** + * @return true if the creation of this record was forced by the forced log feature. + */ + public boolean isForcingLog() { + return forcingLog; + } + + /** + * @param forcingLog is true if the creation of this record was forced by the forced log feature. + */ + public void setForcingLog(boolean forcingLog) { + this.forcingLog = forcingLog; } /** Index: ../../jboss-logmanager/src/main/java/org/jboss/logmanager/CheckForceLogCallback.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../../jboss-logmanager/src/main/java/org/jboss/logmanager/CheckForceLogCallback.java (revision ) +++ ../../jboss-logmanager/src/main/java/org/jboss/logmanager/CheckForceLogCallback.java (revision ) @@ -0,0 +1,27 @@ +/* + * JBoss, Home of Professional Open Source. + * + * Copyright 2014 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jboss.logmanager; + +/** + * Defines the logic that will calculate whether a log should be forced to the log handlers or not. + */ +public interface CheckForceLogCallback { + boolean isForcingLog(); +} Index: ../../jboss-logmanager/src/test/java/org/jboss/logmanager/ForceLogTests.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../../jboss-logmanager/src/test/java/org/jboss/logmanager/ForceLogTests.java (revision ) +++ ../../jboss-logmanager/src/test/java/org/jboss/logmanager/ForceLogTests.java (revision ) @@ -0,0 +1,221 @@ +/* + * JBoss, Home of Professional Open Source. + * + * Copyright 2014 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jboss.logmanager; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.logging.Filter; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +public class ForceLogTests extends AbstractTest { + + private static final String FILTERED = "FILTERED"; + private static final List LOG_MESSAGES; + + static { + LOG_MESSAGES = Collections.unmodifiableList(Arrays.asList( + "FILTERED", + "a", + "ENTRY", + "ENTRY {0}", + "ENTRY {0} {1}", + "RETURN", + "RETURN {0}", + "THROW", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p {0}", + "q {0} {1}", + "r", + "s", + "t {0}", + "u {0} {1}", + "v", + "x", + "y {0}", + "z {0} {1}", + "a1", + "b1 {0}", + "c1 {0}", + "d1" + )); + } + + // it calls all the logging methods. + private void callLog(Logger logger) { + logger.log(Level.SEVERE, FILTERED); + logger.log(new LogRecord(Level.SEVERE, "a")); + logger.entering(ForceLogTests.class.getName(), "b"); + logger.entering(ForceLogTests.class.getName(), "c {0}", "C"); + logger.entering(ForceLogTests.class.getName(), "d {0} {1}", new Object[]{"D", "DD"}); + logger.exiting(ForceLogTests.class.getName(), "e"); + logger.exiting(ForceLogTests.class.getName(), "f", "F"); + logger.throwing(ForceLogTests.class.getName(), "g", new Exception("G")); + logger.severe("h"); + logger.warning("i"); + logger.info("j"); + logger.config("k"); + logger.fine("l"); + logger.finer("m"); + logger.finest("n"); + logger.log(Level.SEVERE, "o"); + logger.log(Level.SEVERE, "p {0}", "P"); + logger.log(Level.SEVERE, "q {0} {1}", new Object[]{"Q", "QQ"}); + logger.log(Level.SEVERE, "r", new Exception("R")); + logger.logp(Level.SEVERE, ForceLogTests.class.getName(), "sourceMethod_s", "s"); + logger.logp(Level.SEVERE, ForceLogTests.class.getName(), "sourceMethod_t", "t {0}", "T"); + logger.logp(Level.SEVERE, ForceLogTests.class.getName(), "sourceMethod_u", "u {0} {1}", new Object[]{"U", "UU"}); + logger.logp(Level.SEVERE, ForceLogTests.class.getName(), "sourceMethod_v", "v", new Exception("v")); + logger.logrb(Level.SEVERE, ForceLogTests.class.getName(), "sourceMethod_x", "bundleName_x", "x"); + logger.logrb(Level.SEVERE, ForceLogTests.class.getName(), "sourceMethod_y", "bundleName_y", "y {0}", "Y"); + logger.logrb(Level.SEVERE, ForceLogTests.class.getName(), "sourceMethod_z", "bundleName_z", "z {0} {1}", new Object[]{"Z", "ZZ"}); + logger.logrb(Level.SEVERE, ForceLogTests.class.getName(), "sourceMethod__a1", "bundleName_a1", "a1", new Exception("a1")); + logger.log("fqcn_b1", Level.SEVERE, "b1 {0}", "bundleName_b1", ExtLogRecord.FormatStyle.MESSAGE_FORMAT, new Object[]{"B1"}, new Exception("b1")); + logger.log("fqcn_c1", Level.SEVERE, "c1 {0}", ExtLogRecord.FormatStyle.MESSAGE_FORMAT, new Object[]{"C1"}, new Exception("c1")); + logger.log("fqcn_d1", Level.SEVERE, "d1", new Exception("d1")); + } + + @Test + public void testForcedLog() throws InterruptedException { + final Logger logger = Logger.getLogger("a"); + final List loggedMessages = new ArrayList<>(); + logger.setLevel(Level.OFF); + logger.addHandler(new Handler() { + @Override + public void publish(LogRecord record) { + loggedMessages.add(record.getMessage()); + } + + @Override + public void flush() { + // no-op + } + + @Override + public void close() throws SecurityException { + // no-op + } + }); + logger.setFilter(new Filter() { + @Override + public boolean isLoggable(LogRecord record) { + return false; + } + }); + logger.setCheckForceLogCallback(new CheckForceLogCallback() { + @Override + public boolean isForcingLog() { + return true; + } + }); + // All log messages should be handled; Even those filtered by our filter. + callLog(logger); + Assert.assertEquals("Bad log messages", LOG_MESSAGES, loggedMessages); + loggedMessages.clear(); + + // calling child + callLog(Logger.getLogger("a.b")); + Assert.assertEquals("Bad log messages", LOG_MESSAGES, loggedMessages); + loggedMessages.clear(); + + // calling unrelated logger + callLog(Logger.getLogger("c")); + Assert.assertEquals("Bad log messages", Collections.emptyList(), loggedMessages); + + logger.setCheckForceLogCallback(null); + + callLog(logger); + Assert.assertEquals("Bad log messages", Collections.emptyList(), loggedMessages); + loggedMessages.clear(); + + logger.setCheckForceLogCallback(new CheckForceLogCallback() { + @Override + public boolean isForcingLog() { + return true; + } + }); + callLog(logger); + Assert.assertEquals("Bad log messages", LOG_MESSAGES, loggedMessages); + loggedMessages.clear(); + logger.setCheckForceLogCallback(null); + } + + @Test + public void testForcedLogDiffThreads() throws InterruptedException { + final Logger logger = Logger.getLogger("a"); + final List loggedMessages = new ArrayList<>(); + logger.setLevel(Level.OFF); + logger.addHandler(new Handler() { + @Override + public void publish(LogRecord record) { + loggedMessages.add(record.getMessage()); + } + + @Override + public void flush() { + // no-op + } + + @Override + public void close() throws SecurityException { + // no-op + } + }); + logger.setFilter(new Filter() { + @Override + public boolean isLoggable(LogRecord record) { + return false; + } + }); + final Thread thread = new Thread(new Runnable() { + @Override + public void run() { + logger.setCheckForceLogCallback(new CheckForceLogCallback() { + @Override + public boolean isForcingLog() { + return true; + } + }); + logger.finest("a"); + } + }); + thread.start(); + thread.join(); + Assert.assertEquals(1, loggedMessages.size()); + Assert.assertEquals("a", loggedMessages.get(0)); + logger.finest("b"); + Assert.assertEquals(1, loggedMessages.size()); + Assert.assertEquals("a", loggedMessages.get(0)); + } + +} Index: ../../jboss-logmanager/src/main/java/org/jboss/logmanager/ExtHandler.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../../jboss-logmanager/src/main/java/org/jboss/logmanager/ExtHandler.java (revision b3ce9607f91bbd5686a60a29e4c07bfef23e277e) +++ ../../jboss-logmanager/src/main/java/org/jboss/logmanager/ExtHandler.java (revision ) @@ -50,6 +50,8 @@ private static final AtomicReferenceFieldUpdater protectKeyUpdater = AtomicReferenceFieldUpdater.newUpdater(ExtHandler.class, Object.class, "protectKey"); + private static final ForcingLogChecker FORCING_LOG_CHECKER = new ForcingLogChecker(); + /** * The sub-handlers for this handler. May only be updated using the {@link #handlersUpdater} atomic updater. The array * instance should not be modified (treat as immutable). @@ -75,6 +77,16 @@ if (enabled && record != null && isLoggable(record)) { doPublish(ExtLogRecord.wrap(record)); } + } + + @Override + public boolean isLoggable(LogRecord record) { + if (FORCING_LOG_CHECKER.isForcingLogFeatureEnabled() + && ExtLogRecord.class.isInstance(record) + && ExtLogRecord.class.cast(record).isForcingLog()) { + return true; + } + return super.isLoggable(record); } /** Index: ../../jboss-logmanager/pom.xml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../../jboss-logmanager/pom.xml (revision b3ce9607f91bbd5686a60a29e4c07bfef23e277e) +++ ../../jboss-logmanager/pom.xml (revision ) @@ -84,6 +84,7 @@ org.jboss.logmanager.LogManager + true ${project.build.directory}${file.separator}logs${file.separator} Index: ../../jboss-logmanager/src/main/java/org/jboss/logmanager/Logger.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../../jboss-logmanager/src/main/java/org/jboss/logmanager/Logger.java (revision b3ce9607f91bbd5686a60a29e4c07bfef23e277e) +++ ../../jboss-logmanager/src/main/java/org/jboss/logmanager/Logger.java (revision ) @@ -44,6 +44,8 @@ private static final String LOGGER_CLASS_NAME = Logger.class.getName(); + private static final ForcingLogChecker FORCING_LOG_CHECKER = new ForcingLogChecker(); + /** * Static logger factory method which returns a JBoss LogManager logger. * @@ -89,6 +91,28 @@ this.loggerNode = loggerNode; } + public synchronized CheckForceLogCallback getCheckForceLogCallback() { + return loggerNode.getCheckForceLogCallback(); + } + + public synchronized CheckForceLogCallback setCheckForceLogCallback(CheckForceLogCallback callback) { + final CheckForceLogCallback old = loggerNode.getCheckForceLogCallback(); + loggerNode.setCheckForceLogCallback(callback); + return old; + } + + private boolean forceLogging() { + if (!FORCING_LOG_CHECKER.isForcingLogFeatureEnabled()) { + return false; + } + final CheckForceLogCallback result = loggerNode.getCheckForceLogCallback(); + if (result != null) { + return result.isForcingLog(); + } + final Logger parent = getParent(); + return parent != null && parent.forceLogging(); + } + // Serialization protected final Object writeReplace() throws ObjectStreamException { @@ -147,6 +171,9 @@ /** {@inheritDoc} */ public boolean isLoggable(Level level) { + if (forceLogging()) { + return true; + } final int effectiveLevel = loggerNode.getEffectiveLevel(); return level.intValue() >= effectiveLevel && effectiveLevel != OFF_INT; } @@ -359,7 +386,7 @@ /** {@inheritDoc} */ public void log(LogRecord record) { final int effectiveLevel = loggerNode.getEffectiveLevel(); - if (record.getLevel().intValue() < effectiveLevel || effectiveLevel == OFF_INT) { + if ((record.getLevel().intValue() < effectiveLevel || effectiveLevel == OFF_INT) && !forceLogging()) { return; } logRaw(record); @@ -367,7 +394,7 @@ /** {@inheritDoc} */ public void entering(final String sourceClass, final String sourceMethod) { - if (FINER_INT < loggerNode.getEffectiveLevel()) { + if (FINER_INT < loggerNode.getEffectiveLevel() && !forceLogging()) { return; } final ExtLogRecord rec = new ExtLogRecord(Level.FINER, "ENTRY", LOGGER_CLASS_NAME); @@ -378,7 +405,7 @@ /** {@inheritDoc} */ public void entering(final String sourceClass, final String sourceMethod, final Object param1) { - if (FINER_INT < loggerNode.getEffectiveLevel()) { + if (FINER_INT < loggerNode.getEffectiveLevel() && !forceLogging()) { return; } final ExtLogRecord rec = new ExtLogRecord(Level.FINER, "ENTRY {0}", LOGGER_CLASS_NAME); @@ -390,7 +417,7 @@ /** {@inheritDoc} */ public void entering(final String sourceClass, final String sourceMethod, final Object[] params) { - if (FINER_INT < loggerNode.getEffectiveLevel()) { + if (FINER_INT < loggerNode.getEffectiveLevel() && !forceLogging()) { return; } final StringBuilder builder = new StringBuilder("ENTRY"); @@ -406,7 +433,7 @@ /** {@inheritDoc} */ public void exiting(final String sourceClass, final String sourceMethod) { - if (FINER_INT < loggerNode.getEffectiveLevel()) { + if (FINER_INT < loggerNode.getEffectiveLevel() && !forceLogging()) { return; } final ExtLogRecord rec = new ExtLogRecord(Level.FINER, "RETURN", LOGGER_CLASS_NAME); @@ -417,7 +444,7 @@ /** {@inheritDoc} */ public void exiting(final String sourceClass, final String sourceMethod, final Object result) { - if (FINER_INT < loggerNode.getEffectiveLevel()) { + if (FINER_INT < loggerNode.getEffectiveLevel() && !forceLogging()) { return; } final ExtLogRecord rec = new ExtLogRecord(Level.FINER, "RETURN {0}", LOGGER_CLASS_NAME); @@ -429,7 +456,7 @@ /** {@inheritDoc} */ public void throwing(final String sourceClass, final String sourceMethod, final Throwable thrown) { - if (FINER_INT < loggerNode.getEffectiveLevel()) { + if (FINER_INT < loggerNode.getEffectiveLevel() && !forceLogging()) { return; } final ExtLogRecord rec = new ExtLogRecord(Level.FINER, "THROW", LOGGER_CLASS_NAME); @@ -441,7 +468,7 @@ /** {@inheritDoc} */ public void severe(final String msg) { - if (SEVERE_INT < loggerNode.getEffectiveLevel()) { + if (SEVERE_INT < loggerNode.getEffectiveLevel() && !forceLogging()) { return; } logRaw(new ExtLogRecord(Level.SEVERE, msg, LOGGER_CLASS_NAME)); @@ -449,7 +476,7 @@ /** {@inheritDoc} */ public void warning(final String msg) { - if (WARNING_INT < loggerNode.getEffectiveLevel()) { + if (WARNING_INT < loggerNode.getEffectiveLevel() && !forceLogging()) { return; } logRaw(new ExtLogRecord(Level.WARNING, msg, LOGGER_CLASS_NAME)); @@ -457,7 +484,7 @@ /** {@inheritDoc} */ public void info(final String msg) { - if (INFO_INT < loggerNode.getEffectiveLevel()) { + if (INFO_INT < loggerNode.getEffectiveLevel() && !forceLogging()) { return; } logRaw(new ExtLogRecord(Level.INFO, msg, LOGGER_CLASS_NAME)); @@ -465,7 +492,7 @@ /** {@inheritDoc} */ public void config(final String msg) { - if (CONFIG_INT < loggerNode.getEffectiveLevel()) { + if (CONFIG_INT < loggerNode.getEffectiveLevel() && !forceLogging()) { return; } logRaw(new ExtLogRecord(Level.CONFIG, msg, LOGGER_CLASS_NAME)); @@ -473,7 +500,7 @@ /** {@inheritDoc} */ public void fine(final String msg) { - if (FINE_INT < loggerNode.getEffectiveLevel()) { + if (FINE_INT < loggerNode.getEffectiveLevel() && !forceLogging()) { return; } logRaw(new ExtLogRecord(Level.FINE, msg, LOGGER_CLASS_NAME)); @@ -481,7 +508,7 @@ /** {@inheritDoc} */ public void finer(final String msg) { - if (FINER_INT < loggerNode.getEffectiveLevel()) { + if (FINER_INT < loggerNode.getEffectiveLevel() && !forceLogging()) { return; } logRaw(new ExtLogRecord(Level.FINER, msg, LOGGER_CLASS_NAME)); @@ -489,7 +516,7 @@ /** {@inheritDoc} */ public void finest(final String msg) { - if (FINEST_INT < loggerNode.getEffectiveLevel()) { + if (FINEST_INT < loggerNode.getEffectiveLevel() && !forceLogging()) { return; } logRaw(new ExtLogRecord(Level.FINEST, msg, LOGGER_CLASS_NAME)); @@ -498,7 +525,7 @@ /** {@inheritDoc} */ public void log(final Level level, final String msg) { final int effectiveLevel = loggerNode.getEffectiveLevel(); - if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) { + if ((level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) && !forceLogging()) { return; } logRaw(new ExtLogRecord(level, msg, LOGGER_CLASS_NAME)); @@ -507,18 +534,18 @@ /** {@inheritDoc} */ public void log(final Level level, final String msg, final Object param1) { final int effectiveLevel = loggerNode.getEffectiveLevel(); - if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) { + if ((level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) && !forceLogging()) { return; } final ExtLogRecord rec = new ExtLogRecord(level, msg, LOGGER_CLASS_NAME); - rec.setParameters(new Object[] { param1 }); + rec.setParameters(new Object[]{param1}); logRaw(rec); } /** {@inheritDoc} */ public void log(final Level level, final String msg, final Object[] params) { final int effectiveLevel = loggerNode.getEffectiveLevel(); - if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) { + if ((level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) && !forceLogging()) { return; } final ExtLogRecord rec = new ExtLogRecord(level, msg, LOGGER_CLASS_NAME); @@ -529,7 +556,7 @@ /** {@inheritDoc} */ public void log(final Level level, final String msg, final Throwable thrown) { final int effectiveLevel = loggerNode.getEffectiveLevel(); - if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) { + if ((level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) && !forceLogging()) { return; } final ExtLogRecord rec = new ExtLogRecord(level, msg, LOGGER_CLASS_NAME); @@ -540,7 +567,7 @@ /** {@inheritDoc} */ public void logp(final Level level, final String sourceClass, final String sourceMethod, final String msg) { final int effectiveLevel = loggerNode.getEffectiveLevel(); - if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) { + if ((level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) && !forceLogging()) { return; } final ExtLogRecord rec = new ExtLogRecord(level, msg, LOGGER_CLASS_NAME); @@ -552,7 +579,7 @@ /** {@inheritDoc} */ public void logp(final Level level, final String sourceClass, final String sourceMethod, final String msg, final Object param1) { final int effectiveLevel = loggerNode.getEffectiveLevel(); - if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) { + if ((level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) && !forceLogging()) { return; } final ExtLogRecord rec = new ExtLogRecord(level, msg, LOGGER_CLASS_NAME); @@ -565,7 +592,7 @@ /** {@inheritDoc} */ public void logp(final Level level, final String sourceClass, final String sourceMethod, final String msg, final Object[] params) { final int effectiveLevel = loggerNode.getEffectiveLevel(); - if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) { + if ((level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) && !forceLogging()) { return; } final ExtLogRecord rec = new ExtLogRecord(level, msg, LOGGER_CLASS_NAME); @@ -578,7 +605,7 @@ /** {@inheritDoc} */ public void logp(final Level level, final String sourceClass, final String sourceMethod, final String msg, final Throwable thrown) { final int effectiveLevel = loggerNode.getEffectiveLevel(); - if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) { + if ((level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) && !forceLogging()) { return; } final ExtLogRecord rec = new ExtLogRecord(level, msg, LOGGER_CLASS_NAME); @@ -591,7 +618,7 @@ /** {@inheritDoc} */ public void logrb(final Level level, final String sourceClass, final String sourceMethod, final String bundleName, final String msg) { final int effectiveLevel = loggerNode.getEffectiveLevel(); - if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) { + if ((level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) && !forceLogging()) { return; } super.logrb(level, sourceClass, sourceMethod, bundleName, msg); @@ -600,7 +627,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 = loggerNode.getEffectiveLevel(); - if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) { + if ((level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) && !forceLogging()) { return; } super.logrb(level, sourceClass, sourceMethod, bundleName, msg, param1); @@ -609,7 +636,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 = loggerNode.getEffectiveLevel(); - if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) { + if ((level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) && !forceLogging()) { return; } super.logrb(level, sourceClass, sourceMethod, bundleName, msg, params); @@ -618,7 +645,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 = loggerNode.getEffectiveLevel(); - if (level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) { + if ((level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) && !forceLogging()) { return; } super.logrb(level, sourceClass, sourceMethod, bundleName, msg, thrown); @@ -639,7 +666,7 @@ */ 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 = loggerNode.getEffectiveLevel(); - if (level == null || fqcn == null || message == null || level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) { + if (level == null || fqcn == null || message == null || ((level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) && !forceLogging())) { return; } final ExtLogRecord rec = new ExtLogRecord(level, message, style, fqcn); @@ -661,7 +688,7 @@ */ 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 = loggerNode.getEffectiveLevel(); - if (level == null || fqcn == null || message == null || level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) { + if (level == null || fqcn == null || message == null || ((level.intValue() < effectiveLevel || effectiveLevel == OFF_INT) && !forceLogging())) { return; } final ExtLogRecord rec = new ExtLogRecord(level, message, style, fqcn); @@ -707,7 +734,7 @@ } final Filter filter = loggerNode.getFilter(); try { - if (filter != null && ! filter.isLoggable(record)) { + if (filter != null && !filter.isLoggable(record) && !forceLogging()) { return; } } catch (VirtualMachineError e) { @@ -716,6 +743,7 @@ // todo - error handler // treat an errored filter as "pass" (I guess?) } + record.setForcingLog(forceLogging()); loggerNode.publish(record); } Index: ../../jboss-logmanager/src/main/java/org/jboss/logmanager/LoggerNode.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../../jboss-logmanager/src/main/java/org/jboss/logmanager/LoggerNode.java (revision b3ce9607f91bbd5686a60a29e4c07bfef23e277e) +++ ../../jboss-logmanager/src/main/java/org/jboss/logmanager/LoggerNode.java (revision ) @@ -99,6 +99,16 @@ */ private volatile int effectiveLevel = Logger.INFO_INT; + private ThreadLocal forcingLog = new InheritableThreadLocal(); + + public void setCheckForceLogCallback(CheckForceLogCallback checkForceLogCallback) { + this.forcingLog.set(checkForceLogCallback); + } + + public CheckForceLogCallback getCheckForceLogCallback() { + return this.forcingLog.get(); + } + /** * Construct a new root instance. *