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
018 package org.apache.logging.log4j.core.appender;
019
020 import org.apache.logging.log4j.core.config.plugins.Plugin;
021 import org.apache.logging.log4j.core.config.plugins.PluginAttr;
022 import org.apache.logging.log4j.core.config.plugins.PluginElement;
023 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
024 import org.apache.logging.log4j.core.filter.ThresholdFilter;
025 import org.apache.logging.log4j.core.layout.HTMLLayout;
026 import org.apache.logging.log4j.core.net.SMTPManager;
027 import org.apache.logging.log4j.core.Filter;
028 import org.apache.logging.log4j.core.Layout;
029 import org.apache.logging.log4j.core.LogEvent;
030
031 import java.io.Serializable;
032
033 /**
034 * Send an e-mail when a specific logging event occurs, typically on errors or
035 * fatal errors.
036 *
037 * <p>
038 * The number of logging events delivered in this e-mail depend on the value of
039 * <b>BufferSize</b> option. The <code>SMTPAppender</code> keeps only the last
040 * <code>BufferSize</code> logging events in its cyclic buffer. This keeps
041 * memory requirements at a reasonable level while still delivering useful
042 * application context.
043 *
044 * By default, an email message will formatted as HTML. This can be modified by
045 * setting a layout for the appender.
046 *
047 * By default, an email message will be sent when an ERROR or higher severity
048 * message is appended. This can be modified by setting a filter for the
049 * appender.
050 */
051 @Plugin(name = "SMTP", category = "Core", elementType = "appender", printObject = true)
052 public final class SMTPAppender<T extends Serializable> extends AbstractAppender<T> {
053
054 private static final int DEFAULT_BUFFER_SIZE = 512;
055
056 /** The SMTP Manager */
057 protected final SMTPManager manager;
058
059 private SMTPAppender(final String name, final Filter filter, final Layout<T> layout, final SMTPManager manager,
060 final boolean handleExceptions) {
061 super(name, filter, layout, handleExceptions);
062 this.manager = manager;
063 }
064
065 /**
066 * Create a SMTPAppender.
067 *
068 * @param name
069 * The name of the Appender.
070 * @param to
071 * The comma-separated list of recipient email addresses.
072 * @param cc
073 * The comma-separated list of CC email addresses.
074 * @param bcc
075 * The comma-separated list of BCC email addresses.
076 * @param from
077 * The email address of the sender.
078 * @param replyTo
079 * The comma-separated list of reply-to email addresses.
080 * @param subject The subject of the email message.
081 * @param smtpProtocol The SMTP transport protocol (such as "smtps", defaults to "smtp").
082 * @param smtpHost
083 * The SMTP hostname to send to.
084 * @param smtpPortNum
085 * The SMTP port to send to.
086 * @param smtpUsername
087 * The username required to authenticate against the SMTP server.
088 * @param smtpPassword
089 * The password required to authenticate against the SMTP server.
090 * @param smtpDebug
091 * Enable mail session debuging on STDOUT.
092 * @param bufferSizeNum
093 * How many log events should be buffered for inclusion in the
094 * message?
095 * @param layout
096 * The layout to use (defaults to HTMLLayout).
097 * @param filter
098 * The Filter or null (defaults to ThresholdFilter, level of
099 * ERROR).
100 * @param suppressExceptions
101 * "true" if exceptions should be hidden from the application,
102 * "false" otherwise (defaults to "true").
103 * @return The SMTPAppender.
104 */
105 @PluginFactory
106 public static <S extends Serializable> SMTPAppender<S> createAppender(@PluginAttr("name") final String name,
107 @PluginAttr("to") final String to,
108 @PluginAttr("cc") final String cc,
109 @PluginAttr("bcc") final String bcc,
110 @PluginAttr("from") final String from,
111 @PluginAttr("replyTo") final String replyTo,
112 @PluginAttr("subject") final String subject,
113 @PluginAttr("smtpProtocol") final String smtpProtocol,
114 @PluginAttr("smtpHost") final String smtpHost,
115 @PluginAttr("smtpPort") final String smtpPortNum,
116 @PluginAttr("smtpUsername") final String smtpUsername,
117 @PluginAttr("smtpPassword") final String smtpPassword,
118 @PluginAttr("smtpDebug") final String smtpDebug,
119 @PluginAttr("bufferSize") final String bufferSizeNum,
120 @PluginElement("layout") Layout<S> layout,
121 @PluginElement("filter") Filter filter,
122 @PluginAttr("suppressExceptions") final String suppressExceptions) {
123 if (name == null) {
124 LOGGER.error("No name provided for SMTPAppender");
125 return null;
126 }
127
128 final boolean isHandleExceptions = suppressExceptions == null ? true : Boolean.valueOf(suppressExceptions);
129 final int smtpPort = smtpPortNum == null ? 0 : Integer.parseInt(smtpPortNum);
130 final boolean isSmtpDebug = smtpDebug == null ? false : Boolean.valueOf(smtpDebug);
131 final int bufferSize = bufferSizeNum == null ? DEFAULT_BUFFER_SIZE : Integer.valueOf(bufferSizeNum);
132
133 if (layout == null) {
134 @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"})
135 Layout<S> l = (Layout<S>)HTMLLayout.createLayout(null, null, null, null, null, null);
136 layout = l;
137 }
138 if (filter == null) {
139 filter = ThresholdFilter.createFilter(null, null, null);
140 }
141
142 final SMTPManager manager = SMTPManager.getSMTPManager(to, cc, bcc, from, replyTo, subject, smtpProtocol,
143 smtpHost, smtpPort, smtpUsername, smtpPassword, isSmtpDebug, filter.toString(), bufferSize);
144 if (manager == null) {
145 return null;
146 }
147
148 return new SMTPAppender<S>(name, filter, layout, manager, isHandleExceptions);
149 }
150
151 /**
152 * Capture all events in CyclicBuffer.
153 * @param event The Log event.
154 * @return true if the event should be filtered.
155 */
156 @Override
157 public boolean isFiltered(final LogEvent event) {
158 final boolean filtered = super.isFiltered(event);
159 if (filtered) {
160 manager.add(event);
161 }
162 return filtered;
163 }
164
165 /**
166 * Perform SMTPAppender specific appending actions, mainly adding the event
167 * to a cyclic buffer and checking if the event triggers an e-mail to be
168 * sent.
169 * @param event The Log event.
170 */
171 @Override
172 public void append(final LogEvent event) {
173 manager.sendEvents(getLayout(), event);
174 }
175 }