/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.googlecode.perftrace.log4j.rewrite;
import org.googlecode.perftrace.log4j.Appender;
import org.googlecode.perftrace.log4j.AppenderSkeleton;
import org.googlecode.perftrace.log4j.helpers.AppenderAttachableImpl;
import org.googlecode.perftrace.log4j.spi.AppenderAttachable;
import org.googlecode.perftrace.log4j.spi.LoggingEvent;
import org.googlecode.perftrace.log4j.spi.OptionHandler;
import org.googlecode.perftrace.log4j.xml.UnrecognizedElementHandler;
import org.w3c.dom.Element;
import java.util.Enumeration;
import java.util.Properties;
/**
* This appender forwards a logging request to another
* appender after possibly rewriting the logging event.
*
* This appender (with the appropriate policy)
* replaces the MapFilter, PropertyFilter and ReflectionFilter
* from log4j 1.3.
*/
public class RewriteAppender extends AppenderSkeleton
implements AppenderAttachable, UnrecognizedElementHandler {
/**
* Rewrite policy.
*/
private RewritePolicy policy;
/**
* Nested appenders.
*/
private final AppenderAttachableImpl appenders;
public RewriteAppender() {
appenders = new AppenderAttachableImpl();
}
/**
* {@inheritDoc}
*/
protected void append(final LoggingEvent event) {
LoggingEvent rewritten = event;
if (policy != null) {
rewritten = policy.rewrite(event);
}
if (rewritten != null) {
synchronized (appenders) {
appenders.appendLoopOnAppenders(rewritten);
}
}
}
/**
* Add appender.
*
* @param newAppender appender to add, may not be null.
*/
public void addAppender(final Appender newAppender) {
synchronized (appenders) {
appenders.addAppender(newAppender);
}
}
/**
* Get iterator over attached appenders.
* @return iterator or null if no attached appenders.
*/
public Enumeration getAllAppenders() {
synchronized (appenders) {
return appenders.getAllAppenders();
}
}
/**
* Get appender by name.
*
* @param name name, may not be null.
* @return matching appender or null.
*/
public Appender getAppender(final String name) {
synchronized (appenders) {
return appenders.getAppender(name);
}
}
/**
* Close this <code>AsyncAppender</code> by interrupting the dispatcher
* thread which will process all pending events before exiting.
*/
public void close() {
closed = true;
//
// close all attached appenders.
//
synchronized (appenders) {
Enumeration iter = appenders.getAllAppenders();
if (iter != null) {
while (iter.hasMoreElements()) {
Object next = iter.nextElement();
if (next instanceof Appender) {
((Appender) next).close();
}
}
}
}
}
/**
* Determines if specified appender is attached.
* @param appender appender.
* @return true if attached.
*/
public boolean isAttached(final Appender appender) {
synchronized (appenders) {
return appenders.isAttached(appender);
}
}
/**
* {@inheritDoc}
*/
public boolean requiresLayout() {
return false;
}
/**
* Removes and closes all attached appenders.
*/
public void removeAllAppenders() {
synchronized (appenders) {
appenders.removeAllAppenders();
}
}
/**
* Removes an appender.
* @param appender appender to remove.
*/
public void removeAppender(final Appender appender) {
synchronized (appenders) {
appenders.removeAppender(appender);
}
}
/**
* Remove appender by name.
* @param name name.
*/
public void removeAppender(final String name) {
synchronized (appenders) {
appenders.removeAppender(name);
}
}
public void setRewritePolicy(final RewritePolicy rewritePolicy) {
policy = rewritePolicy;
}
/**
* {@inheritDoc}
*/
public boolean parseUnrecognizedElement(final Element element,
final Properties props) throws Exception {
final String nodeName = element.getNodeName();
if ("rewritePolicy".equals(nodeName)) {
Object rewritePolicy =
org.googlecode.perftrace.log4j.xml.DOMConfigurator.parseElement(
element, props, RewritePolicy.class);
if (rewritePolicy != null) {
if (rewritePolicy instanceof OptionHandler) {
((OptionHandler) rewritePolicy).activateOptions();
}
this.setRewritePolicy((RewritePolicy) rewritePolicy);
}
return true;
}
return false;
}
}