/* Copyright 2011-2014 Red Hat, Inc This file is part of PressGang CCMS. PressGang CCMS 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 3 of the License, or (at your option) any later version. PressGang CCMS 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 PressGang CCMS. If not, see <http://www.gnu.org/licenses/>. */ package org.jboss.pressgang.ccms.server.async.process.task; import java.io.StringWriter; import org.apache.log4j.Level; import org.apache.log4j.NDC; import org.apache.log4j.SimpleLayout; import org.apache.log4j.WriterAppender; import org.apache.log4j.spi.Filter; import org.apache.log4j.spi.LoggingEvent; import org.jppf.node.protocol.AbstractTask; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A task that provides the ability to capture logs using a {@link WriterAppender} and {@link NDC} to only capture logs from its * executing thread.. * * @param <T> */ public abstract class ProcessTask<T> extends AbstractTask<T> { private transient Logger log; private String logs = ""; private boolean successful = true; @Override public final void run() { // Set the system property for jboss logging to use log4j for this thread System.setProperty("org.jboss.logging.provider", "log4j"); // Create the logger final String name = getClass().getPackage().getName() + "-" + getId(); log = LoggerFactory.getLogger(name); // Add the appender to capture the output final StringWriter writer = new StringWriter(); final WriterAppender appender = createAppender(writer); org.apache.log4j.Logger.getRootLogger().addAppender(appender); org.apache.log4j.Logger log4jLogger = org.apache.log4j.Logger.getLogger(name); log4jLogger.setLevel(Level.INFO); try { // Execute the task NDC.push(getId()); execute(); } catch (Throwable e) { log.error("Unexpected error", e); setSuccessful(false); } finally { NDC.pop(); // Remove the appender from the log and get the logs org.apache.log4j.Logger.getRootLogger().removeAppender(appender); logs = writer.toString(); } NDC.remove(); // Reset the system property for jboss logging System.clearProperty("org.jboss.logging.provider"); } public abstract void execute(); public String getLogs() { return logs; } protected Logger getLogger() { return log; } public boolean wasSuccessful() { return successful; } protected void setSuccessful(boolean successful) { this.successful = successful; } private WriterAppender createAppender(final StringWriter writer) { final WriterAppender appender = new WriterAppender(); appender.setWriter(writer); appender.setLayout(new SimpleLayout()); appender.setThreshold(Level.INFO); // Add a filter that checks that the NDC of the logging event matches this threads NDC value. If it doesn't then it is a log from // another thread so just ignore it. appender.addFilter(new Filter() { @Override public int decide(final LoggingEvent event) { if (event.getNDC() != null && event.getNDC().startsWith(getId())) { return Filter.ACCEPT; } else { return Filter.DENY; } } }); return appender; } }