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 */ 017package org.apache.logging.log4j.core.appender; 018 019import java.io.Serializable; 020 021import org.apache.logging.log4j.core.Appender; 022import org.apache.logging.log4j.core.ErrorHandler; 023import org.apache.logging.log4j.core.Filter; 024import org.apache.logging.log4j.core.Layout; 025import org.apache.logging.log4j.core.LogEvent; 026import org.apache.logging.log4j.core.filter.AbstractFilterable; 027import org.apache.logging.log4j.core.helpers.Integers; 028 029/** 030 * Abstract base class for Appenders. Although Appenders do not have to extend this class, doing so 031 * will simplify their implementation. 032 */ 033public abstract class AbstractAppender extends AbstractFilterable 034 implements Appender { 035 private final boolean ignoreExceptions; 036 037 private ErrorHandler handler = new DefaultErrorHandler(this); 038 039 private final Layout<? extends Serializable> layout; 040 041 private final String name; 042 043 /** 044 * Appenders set this by calling super.start(). 045 */ 046 private boolean started = false; 047 048 public static int parseInt(String s, int defaultValue) { 049 try { 050 return Integers.parseInt(s, defaultValue); 051 } catch (NumberFormatException e) { 052 LOGGER.error("Could not parse \"{}\" as an integer, using default value {}: {}", s, defaultValue, e); 053 return defaultValue; 054 } 055 } 056 057 /** 058 * Constructor that defaults to suppressing exceptions. 059 * @param name The Appender name. 060 * @param filter The Filter to associate with the Appender. 061 * @param layout The layout to use to format the event. 062 */ 063 protected AbstractAppender(final String name, final Filter filter, final Layout<? extends Serializable> layout) { 064 this(name, filter, layout, true); 065 } 066 067 /** 068 * Constructor. 069 * @param name The Appender name. 070 * @param filter The Filter to associate with the Appender. 071 * @param layout The layout to use to format the event. 072 * @param ignoreExceptions If true, exceptions will be logged and suppressed. If false errors will be 073 * logged and then passed to the application. 074 */ 075 protected AbstractAppender(final String name, final Filter filter, final Layout<? extends Serializable> layout, 076 final boolean ignoreExceptions) { 077 super(filter); 078 this.name = name; 079 this.layout = layout; 080 this.ignoreExceptions = ignoreExceptions; 081 } 082 083 /** 084 * Handle an error with a message. 085 * @param msg The message. 086 */ 087 public void error(final String msg) { 088 handler.error(msg); 089 } 090 091 /** 092 * Handle an error with a message, and exception and a logging event. 093 * @param msg The message. 094 * @param event The LogEvent. 095 * @param t The Throwable. 096 */ 097 public void error(final String msg, final LogEvent event, final Throwable t) { 098 handler.error(msg, event, t); 099 } 100 101 /** 102 * Handle an error with a message and an exception. 103 * @param msg The message. 104 * @param t The Throwable. 105 */ 106 public void error(final String msg, final Throwable t) { 107 handler.error(msg, t); 108 } 109 110 /** 111 * Returns the ErrorHandler, if any. 112 * @return The ErrorHandler. 113 */ 114 @Override 115 public ErrorHandler getHandler() { 116 return handler; 117 } 118 119 /** 120 * Returns the Layout for the appender. 121 * @return The Layout used to format the event. 122 */ 123 @Override 124 public Layout<? extends Serializable> getLayout() { 125 return layout; 126 } 127 128 /** 129 * Returns the name of the Appender. 130 * @return The name of the Appender. 131 */ 132 @Override 133 public String getName() { 134 return name; 135 } 136 137 /** 138 * Some appenders need to propagate exceptions back to the application. When {@code ignoreExceptions} is 139 * {@code false} the AppenderControl will allow the exception to percolate. 140 * 141 * @return {@code true} if exceptions will be logged but now thrown, {@code false} otherwise. 142 */ 143 @Override 144 public boolean ignoreExceptions() { 145 return ignoreExceptions; 146 } 147 148 /** 149 * Returns true if the Appender is started, false otherwise. 150 * @return true if the Appender is started, false otherwise. 151 */ 152 @Override 153 public boolean isStarted() { 154 return started; 155 } 156 157 /** 158 * The handler must be set before the appender is started. 159 * @param handler The ErrorHandler to use. 160 */ 161 @Override 162 public void setHandler(final ErrorHandler handler) { 163 if (handler == null) { 164 LOGGER.error("The handler cannot be set to null"); 165 } 166 if (isStarted()) { 167 LOGGER.error("The handler cannot be changed once the appender is started"); 168 return; 169 } 170 this.handler = handler; 171 } 172 173 /** 174 * Start the Appender. 175 */ 176 @Override 177 public void start() { 178 startFilter(); 179 this.started = true; 180 } 181 182 /** 183 * Stop the Appender. 184 */ 185 @Override 186 public void stop() { 187 this.started = false; 188 stopFilter(); 189 } 190 191 @Override 192 public String toString() { 193 return name; 194 } 195 196}