001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache license, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the license for the specific language governing permissions and 015 * limitations under the license. 016 */ 017 package org.apache.logging.log4j.core.appender; 018 019 import java.io.Serializable; 020 021 import org.apache.logging.log4j.core.Appender; 022 import org.apache.logging.log4j.core.ErrorHandler; 023 import org.apache.logging.log4j.core.Filter; 024 import org.apache.logging.log4j.core.LifeCycle; 025 import org.apache.logging.log4j.core.LogEvent; 026 import org.apache.logging.log4j.core.Layout; 027 import org.apache.logging.log4j.core.filter.AbstractFilterable; 028 import org.apache.logging.log4j.status.StatusLogger; 029 import org.apache.logging.log4j.Logger; 030 031 /** 032 * Abstract base class for Appenders. Although Appenders do not have to extend this class, doing so 033 * will simplify their implementation. 034 */ 035 public abstract class AbstractAppender<T extends Serializable> extends AbstractFilterable implements Appender<T>, LifeCycle { 036 /** 037 * Allow subclasses access to the status logger without creating another instance. 038 */ 039 protected static final Logger LOGGER = StatusLogger.getLogger(); 040 041 /** 042 * Appenders set this by calling super.start(). 043 */ 044 private boolean started = false; 045 046 private final Layout<T> layout; 047 048 private final String name; 049 050 private final boolean handleException; 051 052 private ErrorHandler handler = new DefaultErrorHandler(this); 053 054 /** 055 * Constructor that defaults to suppressing exceptions. 056 * @param name The Appender name. 057 * @param filter The Filter to associate with the Appender. 058 * @param layout The layout to use to format the event. 059 */ 060 protected AbstractAppender(String name, Filter filter, Layout<T> layout) { 061 this(name, filter, layout, true); 062 } 063 064 /** 065 * Constructor. 066 * @param name The Appender name. 067 * @param filter The Filter to associate with the Appender. 068 * @param layout The layout to use to format the event. 069 * @param handleException If true, exceptions will be logged and suppressed. If false errors will be 070 * logged and then passed to the application. 071 */ 072 protected AbstractAppender(String name, Filter filter, Layout<T> layout, boolean handleException) { 073 super(filter); 074 this.name = name; 075 this.layout = layout; 076 this.handleException = handleException; 077 } 078 079 /** 080 * Returns the ErrorHandler, if any. 081 * @return The ErrorHandler. 082 */ 083 public ErrorHandler getHandler() { 084 return handler; 085 } 086 087 /** 088 * The handler must be set before the appender is started. 089 * @param handler The ErrorHandler to use. 090 */ 091 public void setHandler(ErrorHandler handler) { 092 if (handler == null) { 093 LOGGER.error("The handler cannot be set to null"); 094 } 095 if (isStarted()) { 096 LOGGER.error("The handler cannot be changed once the appender is started"); 097 return; 098 } 099 this.handler = handler; 100 } 101 102 /** 103 * Close the stream associated with the Appender. 104 */ 105 public void close() { 106 107 } 108 109 /** 110 * Returns the name of the Appender. 111 * @return The name of the Appender. 112 */ 113 public String getName() { 114 return name; 115 } 116 117 /** 118 * Returns the Layout for the appender. 119 * @return The Layout used to format the event. 120 */ 121 public Layout<T> getLayout() { 122 return layout; 123 } 124 125 /** 126 * Some appenders need to propogate exceptions back to the application. When suppressException is false the 127 * AppenderControl will allow the exception to percolate. 128 * @return true if exceptions will be supressed, false otherwise. 129 */ 130 public boolean isExceptionSuppressed() { 131 return handleException; 132 } 133 134 /** 135 * Start the Appender. 136 */ 137 public void start() { 138 startFilter(); 139 this.started = true; 140 } 141 142 /** 143 * Stop the Appender. 144 */ 145 public void stop() { 146 this.started = false; 147 stopFilter(); 148 } 149 150 /** 151 * Returns true if the Appender is started, false otherwise. 152 * @return true if the Appender is started, false otherwise. 153 */ 154 public boolean isStarted() { 155 return started; 156 } 157 158 @Override 159 public String toString() { 160 return name; 161 } 162 163 /** 164 * Handle an error with a message. 165 * @param msg The message. 166 */ 167 public void error(String msg) { 168 handler.error(msg); 169 } 170 171 /** 172 * Handle an error with a message and an exception. 173 * @param msg The message. 174 * @param t The Throwable. 175 */ 176 public void error(String msg, Throwable t) { 177 handler.error(msg, t); 178 } 179 180 /** 181 * Handle an error with a message, and exception and a logging event. 182 * @param msg The message. 183 * @param event The LogEvent. 184 * @param t The Throwable. 185 */ 186 public void error(String msg, LogEvent event, Throwable t) { 187 handler.error(msg, event, t); 188 } 189 190 }