📄 smtpappender.java
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.log4j.net;import org.apache.log4j.AppenderSkeleton;import org.apache.log4j.Level;import org.apache.log4j.Layout;import org.apache.log4j.xml.UnrecognizedElementHandler;import org.apache.log4j.helpers.CyclicBuffer;import org.apache.log4j.helpers.OptionConverter;import org.apache.log4j.helpers.LogLog;import org.apache.log4j.spi.LoggingEvent;import org.apache.log4j.spi.ErrorCode;import org.apache.log4j.spi.TriggeringEventEvaluator;import org.apache.log4j.spi.OptionHandler;import org.w3c.dom.Element;import java.util.Properties;import java.util.Date;import javax.mail.Session;import javax.mail.Authenticator;import javax.mail.PasswordAuthentication;import javax.mail.Transport;import javax.mail.Message;import javax.mail.MessagingException;import javax.mail.internet.MimeMessage;import javax.mail.Multipart;import javax.mail.internet.MimeMultipart;import javax.mail.internet.MimeBodyPart;import javax.mail.internet.InternetAddress;import javax.mail.internet.AddressException;/** Send an e-mail when a specific logging event occurs, typically on errors or fatal errors. <p>The number of logging events delivered in this e-mail depend on the value of <b>BufferSize</b> option. The <code>SMTPAppender</code> keeps only the last <code>BufferSize</code> logging events in its cyclic buffer. This keeps memory requirements at a reasonable level while still delivering useful application context. By default, an email message will be sent when an ERROR or higher severity message is appended. The triggering criteria can be modified by setting the evaluatorClass property with the name of a class implementing TriggeringEventEvaluator, setting the evaluator property with an instance of TriggeringEventEvaluator or nesting a triggeringPolicy element where the specified class implements TriggeringEventEvaluator. @author Ceki Gülcü @since 1.0 */public class SMTPAppender extends AppenderSkeleton implements UnrecognizedElementHandler { private String to; /** * Comma separated list of cc recipients. */ private String cc; /** * Comma separated list of bcc recipients. */ private String bcc; private String from; private String subject; private String smtpHost; private String smtpUsername; private String smtpPassword; private boolean smtpDebug = false; private int bufferSize = 512; private boolean locationInfo = false; protected CyclicBuffer cb = new CyclicBuffer(bufferSize); protected Message msg; protected TriggeringEventEvaluator evaluator; /** The default constructor will instantiate the appender with a {@link TriggeringEventEvaluator} that will trigger on events with level ERROR or higher.*/ public SMTPAppender() { this(new DefaultEvaluator()); } /** Use <code>evaluator</code> passed as parameter as the {@link TriggeringEventEvaluator} for this SMTPAppender. */ public SMTPAppender(TriggeringEventEvaluator evaluator) { this.evaluator = evaluator; } /** Activate the specified options, such as the smtp host, the recipient, from, etc. */ public void activateOptions() { Session session = createSession(); msg = new MimeMessage(session); try { addressMessage(msg); if(subject != null) { msg.setSubject(subject); } } catch(MessagingException e) { LogLog.error("Could not activate SMTPAppender options.", e ); } if (evaluator instanceof OptionHandler) { ((OptionHandler) evaluator).activateOptions(); } } /** * Address message. * @param msg message, may not be null. * @throws MessagingException thrown if error addressing message. */ protected void addressMessage(final Message msg) throws MessagingException { if (from != null) { msg.setFrom(getAddress(from)); } else { msg.setFrom(); } if (to != null && to.length() > 0) { msg.setRecipients(Message.RecipientType.TO, parseAddress(to)); } //Add CC receipients if defined. if (cc != null && cc.length() > 0) { msg.setRecipients(Message.RecipientType.CC, parseAddress(cc)); } //Add BCC receipients if defined. if (bcc != null && bcc.length() > 0) { msg.setRecipients(Message.RecipientType.BCC, parseAddress(bcc)); } } /** * Create mail session. * @return mail session, may not be null. */ protected Session createSession() { Properties props = null; try { props = new Properties (System.getProperties()); } catch(SecurityException ex) { props = new Properties(); } if (smtpHost != null) { props.put("mail.smtp.host", smtpHost); } Authenticator auth = null; if(smtpPassword != null && smtpUsername != null) { props.put("mail.smtp.auth", "true"); auth = new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(smtpUsername, smtpPassword); } }; } Session session = Session.getInstance(props, auth); if (smtpDebug) { session.setDebug(smtpDebug); } return session; } /** Perform SMTPAppender specific appending actions, mainly adding the event to a cyclic buffer and checking if the event triggers an e-mail to be sent. */ public void append(LoggingEvent event) { if(!checkEntryConditions()) { return; } event.getThreadName(); event.getNDC(); event.getMDCCopy(); if(locationInfo) { event.getLocationInformation(); } cb.add(event); if(evaluator.isTriggeringEvent(event)) { sendBuffer(); } } /** This method determines if there is a sense in attempting to append. <p>It checks whether there is a set output target and also if there is a set layout. If these checks fail, then the boolean value <code>false</code> is returned. */ protected boolean checkEntryConditions() { if(this.msg == null) { errorHandler.error("Message object not configured."); return false; } if(this.evaluator == null) { errorHandler.error("No TriggeringEventEvaluator is set for appender ["+ name+"]."); return false; } if(this.layout == null) { errorHandler.error("No layout set for appender named ["+name+"]."); return false; } return true; } synchronized public void close() { this.closed = true; } InternetAddress getAddress(String addressStr) { try { return new InternetAddress(addressStr); } catch(AddressException e) { errorHandler.error("Could not parse address ["+addressStr+"].", e, ErrorCode.ADDRESS_PARSE_FAILURE); return null; } } InternetAddress[] parseAddress(String addressStr) { try { return InternetAddress.parse(addressStr, true); } catch(AddressException e) { errorHandler.error("Could not parse address ["+addressStr+"].", e, ErrorCode.ADDRESS_PARSE_FAILURE); return null; } } /** Returns value of the <b>To</b> option. */ public String getTo() { return to; } /** The <code>SMTPAppender</code> requires a {@link org.apache.log4j.Layout layout}. */ public boolean requiresLayout() { return true; } /** Send the contents of the cyclic buffer as an e-mail message. */ protected void sendBuffer() { // Note: this code already owns the monitor for this // appender. This frees us from needing to synchronize on 'cb'. try { MimeBodyPart part = new MimeBodyPart(); StringBuffer sbuf = new StringBuffer(); String t = layout.getHeader(); if(t != null)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -