Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LOGMGR-79] Allow isLoggable() to be skipped so that handlers can publish records to their child handlers. #35

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 32 additions & 4 deletions src/main/java/org/jboss/logmanager/ExtHandler.java
Expand Up @@ -60,6 +60,16 @@ public abstract class ExtHandler extends Handler implements FlushableCloseable,
@SuppressWarnings({ "UnusedDeclaration" })
protected volatile Handler[] handlers;

/**
* A value of {@code true} indicates the subclass is responsible for checking whether the {@link
* #publish(java.util.logging.LogRecord) published} record is {@link #isLoggable(java.util.logging.LogRecord)
* loggable}. A record is said to be loggable if the record is not {@code null} and {@link
* #isLoggable(java.util.logging.LogRecord)} returns {@code true}.
* <p/>
* Note the {@link #isEnabled() enabled flag} and a {@code null} check is done for you.
*/
protected final boolean skipLevelFilterCheck;

/**
* The atomic updater for the {@link #handlers} field.
*/
Expand All @@ -69,14 +79,30 @@ public abstract class ExtHandler extends Handler implements FlushableCloseable,
* Construct a new instance.
*/
protected ExtHandler() {
this(false);
}

/**
* Construct a new instance.
* <p/>
* If the {@code skipLevelFilterCheck} is set to {@code true} it's the responsibility of the subclass to check
* whether the record is {@link #isLoggable(java.util.logging.LogRecord) loggable} or not.
*
* @param skipLevelFilterCheck {@code true} if the {@link #isLoggable(java.util.logging.LogRecord)} should be
* skipped, otherwise {@code false}
*/
protected ExtHandler(final boolean skipLevelFilterCheck) {
handlersUpdater.clear(this);
super.setErrorManager(DEFAULT_ERROR_MANAGER);
this.skipLevelFilterCheck = skipLevelFilterCheck;
}

/** {@inheritDoc} */
public final void publish(final LogRecord record) {
if (enabled && record != null && isLoggable(record)) {
doPublish(ExtLogRecord.wrap(record));
if (enabled && record != null) {
if (skipLevelFilterCheck || isLoggable(record)) {
doPublish(ExtLogRecord.wrap(record));
}
}
}

Expand All @@ -91,8 +117,10 @@ public final void publish(final LogRecord record) {
* @param record the log record to publish
*/
public final void publish(final ExtLogRecord record) {
if (enabled && record != null && isLoggable(record)) {
doPublish(record);
if (enabled && record != null) {
if (skipLevelFilterCheck || isLoggable(record)) {
doPublish(record);
}
}
}

Expand Down
10 changes: 8 additions & 2 deletions src/main/java/org/jboss/logmanager/handlers/QueueHandler.java
Expand Up @@ -46,6 +46,7 @@ public class QueueHandler extends ExtHandler {
* Construct a new instance with a default queue length.
*/
public QueueHandler() {
super(true);
}

/**
Expand All @@ -54,6 +55,7 @@ public QueueHandler() {
* @param limit the queue length to use
*/
public QueueHandler(final int limit) {
super(true);
if (limit < 1) {
throw badQueueLength();
}
Expand All @@ -63,8 +65,12 @@ public QueueHandler(final int limit) {
protected void doPublish(final ExtLogRecord record) {
record.copyAll();
synchronized (buffer) {
if (buffer.size() == limit) { buffer.removeFirst(); }
buffer.addLast(record);
if (isLoggable(record)) {
if (buffer.size() == limit) {
buffer.removeFirst();
}
buffer.addLast(record);
}
for (Handler handler : getHandlers()) {
handler.publish(record);
}
Expand Down
70 changes: 69 additions & 1 deletion src/test/java/org/jboss/logmanager/HandlerTests.java
Expand Up @@ -37,6 +37,7 @@
import java.io.File;
import java.io.FileInputStream;
import java.io.UnsupportedEncodingException;
import java.util.logging.Handler;

public final class HandlerTests {

Expand All @@ -57,7 +58,11 @@ private void initHandler(ExtHandler handler) throws UnsupportedEncodingException
}

private void testPublish(ExtHandler handler) {
handler.publish(new ExtLogRecord(Level.INFO, "Test message", null));
testPublish(handler, Level.INFO);
}

private void testPublish(ExtHandler handler, Level level) {
handler.publish(new ExtLogRecord(level, "Test message", null));
}

@Test
Expand Down Expand Up @@ -126,4 +131,67 @@ public void testEnableDisableHandler() throws Throwable {
testPublish(handler);
assertEquals(2, handler.size());
}

@Test
public void testHandlerDelegation() throws Throwable {
final StringListHandler debugHandler = new StringListHandler();
debugHandler.setLevel(Level.DEBUG);

final StringListHandler infoHandler = new StringListHandler();
infoHandler.setLevel(Level.INFO);

final StringListHandler errorHandler = new StringListHandler();
errorHandler.setLevel(Level.ERROR);

final MultiHandler handler = MultiHandler.of(debugHandler, infoHandler, errorHandler);
// Turn off the level for the handler
handler.setLevel(Level.OFF);

// Log a debug message
testPublish(handler, Level.DEBUG);
assertEquals(1, debugHandler.size());
assertEquals(0, infoHandler.size());
assertEquals(0, errorHandler.size());

// Log an info message
testPublish(handler, Level.INFO);
assertEquals(2, debugHandler.size());
assertEquals(1, infoHandler.size());
assertEquals(0, errorHandler.size());

// Log a warn message
testPublish(handler, Level.WARN);
assertEquals(3, debugHandler.size());
assertEquals(2, infoHandler.size());
assertEquals(0, errorHandler.size());

// Log an error message
testPublish(handler, Level.ERROR);
assertEquals(4, debugHandler.size());
assertEquals(3, infoHandler.size());
assertEquals(1, errorHandler.size());
}

static class MultiHandler extends ExtHandler {
protected MultiHandler() {
super(true);
}

static MultiHandler of(final ExtHandler... handlers) {
final MultiHandler result = new MultiHandler();
result.setHandlers(handlers);
return result;
}

@Override
protected void doPublish(final ExtLogRecord record) {
// Process child handlers
for (Handler handler : getHandlers()) {
if (handler.isLoggable(record)) {
handler.publish(record);
}
}
super.doPublish(record);
}
}
}
Expand Up @@ -95,11 +95,19 @@ protected static void configureHandlerDefaults(final ExtHandler handler) {
handler.setFormatter(FORMATTER);
}

protected static ExtLogRecord createLogRecord(final String msg) {
return new ExtLogRecord(org.jboss.logmanager.Level.INFO, msg, null);
protected ExtLogRecord createLogRecord(final String msg) {
return createLogRecord(org.jboss.logmanager.Level.INFO, msg);
}

protected static ExtLogRecord createLogRecord(final String format, final Object... args) {
return new ExtLogRecord(org.jboss.logmanager.Level.INFO, String.format(format, args), null);
protected ExtLogRecord createLogRecord(final String format, final Object... args) {
return createLogRecord(org.jboss.logmanager.Level.INFO, format, args);
}

protected ExtLogRecord createLogRecord(final org.jboss.logmanager.Level level, final String msg) {
return new ExtLogRecord(level, msg, getClass().getName());
}

protected ExtLogRecord createLogRecord(final org.jboss.logmanager.Level level, final String format, final Object... args) {
return new ExtLogRecord(level, String.format(format, args), getClass().getName());
}
}
100 changes: 100 additions & 0 deletions src/test/java/org/jboss/logmanager/handlers/QueueHandlerTests.java
@@ -0,0 +1,100 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2013, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.logmanager.handlers;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.jboss.logmanager.ExtHandler;
import org.jboss.logmanager.ExtLogRecord;
import org.jboss.logmanager.Level;
import org.junit.Assert;
import org.junit.Test;

/**
* @author <a href="mailto:jperkins@redhat.com">James R. Perkins</a>
*/
public class QueueHandlerTests extends AbstractHandlerTest {

@Test
public void testQueueSize() throws Exception {
final QueueHandler handler = new QueueHandler(5);

// Log 6 records and ensure only 5 are available
for (int i = 0; i < 6; i++) {
handler.publish(createLogRecord("Test message %d", i));
}
final ExtLogRecord[] records = handler.getQueue();

Assert.assertEquals("QueueHandler held onto more records than allowed", 5, records.length);

// Check each message, the last should be the sixth
Assert.assertEquals("Test message 1", records[0].getMessage());
Assert.assertEquals("Test message 2", records[1].getMessage());
Assert.assertEquals("Test message 3", records[2].getMessage());
Assert.assertEquals("Test message 4", records[3].getMessage());
Assert.assertEquals("Test message 5", records[4].getMessage());
}

@Test
public void testNestedHandlers() throws Exception {
// Create a nested a handler
final NestedHandler nestedHandler = new NestedHandler();
nestedHandler.setLevel(Level.INFO);

final QueueHandler handler = new QueueHandler(10);
handler.setLevel(Level.ERROR);
handler.addHandler(nestedHandler);

// Log an info messages
handler.publish(createLogRecord(Level.INFO, "Test message"));
Assert.assertEquals(1, nestedHandler.getRecords().size());
Assert.assertEquals(0, handler.getQueue().length);

// Log a warn messages
handler.publish(createLogRecord(Level.WARN, "Test message"));
Assert.assertEquals(2, nestedHandler.getRecords().size());
Assert.assertEquals(0, handler.getQueue().length);

// Log an error messages
handler.publish(createLogRecord(Level.ERROR, "Test message"));
Assert.assertEquals(3, nestedHandler.getRecords().size());
Assert.assertEquals(1, handler.getQueue().length);
}

static class NestedHandler extends ExtHandler {
private final List<ExtLogRecord> records = new ArrayList<ExtLogRecord>();

@Override
protected void doPublish(final ExtLogRecord record) {
records.add(record);
super.doPublish(record);
}

Collection<ExtLogRecord> getRecords() {
return Collections.unmodifiableCollection(records);
}
}
}