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.util.Integers; 028 029/** 030 * Abstract base class for Appenders. Although Appenders do not have to extend this class, doing so will simplify their 031 * implementation. 032 */ 033public abstract class AbstractAppender extends AbstractFilterable implements Appender { 034 035 private static final long serialVersionUID = 1L; 036 037 private final String name; 038 private final boolean ignoreExceptions; 039 private final Layout<? extends Serializable> layout; 040 private ErrorHandler handler = new DefaultErrorHandler(this); 041 042 /** 043 * Constructor that defaults to suppressing exceptions. 044 * 045 * @param name The Appender name. 046 * @param filter The Filter to associate with the Appender. 047 * @param layout The layout to use to format the event. 048 */ 049 protected AbstractAppender(final String name, final Filter filter, final Layout<? extends Serializable> layout) { 050 this(name, filter, layout, true); 051 } 052 053 /** 054 * Constructor. 055 * 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 * @param ignoreExceptions If true, exceptions will be logged and suppressed. If false errors will be logged and 060 * then passed to the application. 061 */ 062 protected AbstractAppender(final String name, final Filter filter, final Layout<? extends Serializable> layout, 063 final boolean ignoreExceptions) { 064 super(filter); 065 this.name = name; 066 this.layout = layout; 067 this.ignoreExceptions = ignoreExceptions; 068 } 069 070 public static int parseInt(final String s, final int defaultValue) { 071 try { 072 return Integers.parseInt(s, defaultValue); 073 } catch (final NumberFormatException e) { 074 LOGGER.error("Could not parse \"{}\" as an integer, using default value {}: {}", s, defaultValue, e); 075 return defaultValue; 076 } 077 } 078 079 /** 080 * Handle an error with a message using the {@link ErrorHandler} configured for this Appender. 081 * 082 * @param msg The message. 083 */ 084 public void error(final String msg) { 085 handler.error(msg); 086 } 087 088 /** 089 * Handle an error with a message, exception, and a logging event, using the {@link ErrorHandler} configured for 090 * this Appender. 091 * 092 * @param msg The message. 093 * @param event The LogEvent. 094 * @param t The Throwable. 095 */ 096 public void error(final String msg, final LogEvent event, final Throwable t) { 097 handler.error(msg, event, t); 098 } 099 100 /** 101 * Handle an error with a message and an exception using the {@link ErrorHandler} configured for this Appender. 102 * 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 * 113 * @return The ErrorHandler. 114 */ 115 @Override 116 public ErrorHandler getHandler() { 117 return handler; 118 } 119 120 /** 121 * Returns the Layout for the appender. 122 * 123 * @return The Layout used to format the event. 124 */ 125 @Override 126 public Layout<? extends Serializable> getLayout() { 127 return layout; 128 } 129 130 /** 131 * Returns the name of the Appender. 132 * 133 * @return The name of the Appender. 134 */ 135 @Override 136 public String getName() { 137 return name; 138 } 139 140 /** 141 * Some appenders need to propagate exceptions back to the application. When {@code ignoreExceptions} is 142 * {@code false} the AppenderControl will allow the exception to percolate. 143 * 144 * @return {@code true} if exceptions will be logged but now thrown, {@code false} otherwise. 145 */ 146 @Override 147 public boolean ignoreExceptions() { 148 return ignoreExceptions; 149 } 150 151 /** 152 * The handler must be set before the appender is started. 153 * 154 * @param handler The ErrorHandler to use. 155 */ 156 @Override 157 public void setHandler(final ErrorHandler handler) { 158 if (handler == null) { 159 LOGGER.error("The handler cannot be set to null"); 160 } 161 if (isStarted()) { 162 LOGGER.error("The handler cannot be changed once the appender is started"); 163 return; 164 } 165 this.handler = handler; 166 } 167 168 @Override 169 public String toString() { 170 return name; 171 } 172 173}