View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  
18  package org.apache.logging.log4j.core.appender;
19  
20  import java.io.Serializable;
21  
22  import org.apache.logging.log4j.core.Filter;
23  import org.apache.logging.log4j.core.Layout;
24  import org.apache.logging.log4j.core.LogEvent;
25  import org.apache.logging.log4j.core.config.plugins.Plugin;
26  import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
27  import org.apache.logging.log4j.core.config.plugins.PluginElement;
28  import org.apache.logging.log4j.core.config.plugins.PluginFactory;
29  import org.apache.logging.log4j.core.filter.ThresholdFilter;
30  import org.apache.logging.log4j.core.helpers.Booleans;
31  import org.apache.logging.log4j.core.layout.HTMLLayout;
32  import org.apache.logging.log4j.core.net.SMTPManager;
33  
34  /**
35   * Send an e-mail when a specific logging event occurs, typically on errors or
36   * fatal errors.
37   *
38   * <p>
39   * The number of logging events delivered in this e-mail depend on the value of
40   * <b>BufferSize</b> option. The <code>SMTPAppender</code> keeps only the last
41   * <code>BufferSize</code> logging events in its cyclic buffer. This keeps
42   * memory requirements at a reasonable level while still delivering useful
43   * application context.
44   *
45   * By default, an email message will formatted as HTML. This can be modified by
46   * setting a layout for the appender.
47   *
48   * By default, an email message will be sent when an ERROR or higher severity
49   * message is appended. This can be modified by setting a filter for the
50   * appender.
51   */
52  @Plugin(name = "SMTP", category = "Core", elementType = "appender", printObject = true)
53  public final class SMTPAppender extends AbstractAppender {
54  
55      private static final int DEFAULT_BUFFER_SIZE = 512;
56  
57      /** The SMTP Manager */
58      protected final SMTPManager manager;
59  
60      private SMTPAppender(final String name, final Filter filter, final Layout<? extends Serializable> layout, final SMTPManager manager,
61                           final boolean ignoreExceptions) {
62          super(name, filter, layout, ignoreExceptions);
63          this.manager = manager;
64      }
65  
66      /**
67       * Create a SMTPAppender.
68       *
69       * @param name
70       *            The name of the Appender.
71       * @param to
72       *            The comma-separated list of recipient email addresses.
73       * @param cc
74       *            The comma-separated list of CC email addresses.
75       * @param bcc
76       *            The comma-separated list of BCC email addresses.
77       * @param from
78       *            The email address of the sender.
79       * @param replyTo
80       *            The comma-separated list of reply-to email addresses.
81       * @param subject The subject of the email message.
82       * @param smtpProtocol The SMTP transport protocol (such as "smtps", defaults to "smtp").
83       * @param smtpHost
84       *            The SMTP hostname to send to.
85       * @param smtpPortStr
86       *            The SMTP port to send to.
87       * @param smtpUsername
88       *            The username required to authenticate against the SMTP server.
89       * @param smtpPassword
90       *            The password required to authenticate against the SMTP server.
91       * @param smtpDebug
92       *            Enable mail session debuging on STDOUT.
93       * @param bufferSizeStr
94       *            How many log events should be buffered for inclusion in the
95       *            message?
96       * @param layout
97       *            The layout to use (defaults to HTMLLayout).
98       * @param filter
99       *            The Filter or null (defaults to ThresholdFilter, level of
100      *            ERROR).
101      * @param ignore If {@code "true"} (default) exceptions encountered when appending events are logged; otherwise
102      *               they are propagated to the caller.
103      * @return The SMTPAppender.
104      */
105     @PluginFactory
106     public static SMTPAppender createAppender(
107             @PluginAttribute("name") final String name,
108             @PluginAttribute("to") final String to,
109             @PluginAttribute("cc") final String cc,
110             @PluginAttribute("bcc") final String bcc,
111             @PluginAttribute("from") final String from,
112             @PluginAttribute("replyTo") final String replyTo,
113             @PluginAttribute("subject") final String subject,
114             @PluginAttribute("smtpProtocol") final String smtpProtocol,
115             @PluginAttribute("smtpHost") final String smtpHost,
116             @PluginAttribute("smtpPort") final String smtpPortStr,
117             @PluginAttribute("smtpUsername") final String smtpUsername,
118             @PluginAttribute("smtpPassword") final String smtpPassword,
119             @PluginAttribute("smtpDebug") final String smtpDebug,
120             @PluginAttribute("bufferSize") final String bufferSizeStr,
121             @PluginElement("Layout") Layout<? extends Serializable> layout,
122             @PluginElement("Filter") Filter filter,
123             @PluginAttribute("ignoreExceptions") final String ignore) {
124         if (name == null) {
125             LOGGER.error("No name provided for SMTPAppender");
126             return null;
127         }
128 
129         final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
130         final int smtpPort = AbstractAppender.parseInt(smtpPortStr, 0);
131         final boolean isSmtpDebug = Boolean.parseBoolean(smtpDebug);
132         final int bufferSize = bufferSizeStr == null ? DEFAULT_BUFFER_SIZE : Integer.parseInt(bufferSizeStr);
133 
134         if (layout == null) {
135             layout = HTMLLayout.createLayout(null, null, null, null, null, null);
136         }
137         if (filter == null) {
138             filter = ThresholdFilter.createFilter(null, null, null);
139         }
140 
141         final SMTPManager manager = SMTPManager.getSMTPManager(to, cc, bcc, from, replyTo, subject, smtpProtocol,
142             smtpHost, smtpPort, smtpUsername, smtpPassword, isSmtpDebug, filter.toString(),  bufferSize);
143         if (manager == null) {
144             return null;
145         }
146 
147         return new SMTPAppender(name, filter, layout, manager, ignoreExceptions);
148     }
149 
150     /**
151      * Capture all events in CyclicBuffer.
152      * @param event The Log event.
153      * @return true if the event should be filtered.
154      */
155     @Override
156     public boolean isFiltered(final LogEvent event) {
157         final boolean filtered = super.isFiltered(event);
158         if (filtered) {
159             manager.add(event);
160         }
161         return filtered;
162     }
163 
164     /**
165      * Perform SMTPAppender specific appending actions, mainly adding the event
166      * to a cyclic buffer and checking if the event triggers an e-mail to be
167      * sent.
168      * @param event The Log event.
169      */
170     @Override
171     public void append(final LogEvent event) {
172         manager.sendEvents(getLayout(), event);
173     }
174 }