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.layout.HtmlLayout;
    31  import org.apache.logging.log4j.core.net.SmtpManager;
    32  import org.apache.logging.log4j.core.util.Booleans;
    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 long serialVersionUID = 1L;
    56      private static final int DEFAULT_BUFFER_SIZE = 512;
    57
    58      /** The SMTP Manager */
    59      private final SmtpManager manager;
    60
    61      private SmtpAppender(final String name, final Filter filter, final Layout<? extends Serializable> layout, final SmtpManager manager,
    62                           final boolean ignoreExceptions) {
    63          super(name, filter, layout, ignoreExceptions);
    64          this.manager = manager;
    65      }
    66
    67      /**
    68       * Create a SmtpAppender.
    69       *
    70       * @param name
    71       *            The name of the Appender.
    72       * @param to
    73       *            The comma-separated list of recipient email addresses.
    74       * @param cc
    75       *            The comma-separated list of CC email addresses.
    76       * @param bcc
    77       *            The comma-separated list of BCC email addresses.
    78       * @param from
    79       *            The email address of the sender.
    80       * @param replyTo
    81       *            The comma-separated list of reply-to email addresses.
    82       * @param subject The subject of the email message.
    83       * @param smtpProtocol The SMTP transport protocol (such as "smtps", defaults to "smtp").
    84       * @param smtpHost
    85       *            The SMTP hostname to send to.
    86       * @param smtpPortStr
    87       *            The SMTP port to send to.
    88       * @param smtpUsername
    89       *            The username required to authenticate against the SMTP server.
    90       * @param smtpPassword
    91       *            The password required to authenticate against the SMTP server.
    92       * @param smtpDebug
    93       *            Enable mail session debuging on STDOUT.
    94       * @param bufferSizeStr
    95       *            How many log events should be buffered for inclusion in the
    96       *            message?
    97       * @param layout
    98       *            The layout to use (defaults to HtmlLayout).
    99       * @param filter
    100      *            The Filter or null (defaults to ThresholdFilter, level of
    101      *            ERROR).
    102      * @param ignore If {@code "true"} (default) exceptions encountered when appending events are logged; otherwise
    103      *               they are propagated to the caller.
    104      * @return The SmtpAppender.
    105      */
    106     @PluginFactory
    107     public static SmtpAppender createAppender(
    108             @PluginAttribute("name") final String name,
    109             @PluginAttribute("to") final String to,
    110             @PluginAttribute("cc") final String cc,
    111             @PluginAttribute("bcc") final String bcc,
    112             @PluginAttribute("from") final String from,
    113             @PluginAttribute("replyTo") final String replyTo,
    114             @PluginAttribute("subject") final String subject,
    115             @PluginAttribute("smtpProtocol") final String smtpProtocol,
    116             @PluginAttribute("smtpHost") final String smtpHost,
    117             @PluginAttribute("smtpPort") final String smtpPortStr,
    118             @PluginAttribute("smtpUsername") final String smtpUsername,
    119             @PluginAttribute("smtpPassword") final String smtpPassword,
    120             @PluginAttribute("smtpDebug") final String smtpDebug,
    121             @PluginAttribute("bufferSize") final String bufferSizeStr,
    122             @PluginElement("Layout") Layout<? extends Serializable> layout,
    123             @PluginElement("Filter") Filter filter,
    124             @PluginAttribute("ignoreExceptions") final String ignore) {
    125         if (name == null) {
    126             LOGGER.error("No name provided for SmtpAppender");
    127             return null;
    128         }
    129
    130         final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
    131         final int smtpPort = AbstractAppender.parseInt(smtpPortStr, 0);
    132         final boolean isSmtpDebug = Boolean.parseBoolean(smtpDebug);
    133         final int bufferSize = bufferSizeStr == null ? DEFAULT_BUFFER_SIZE : Integer.parseInt(bufferSizeStr);
    134
    135         if (layout == null) {
    136             layout = HtmlLayout.createDefaultLayout();
    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(name, filter, layout, manager, ignoreExceptions);
    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 }