Hi,
I needed an appender which could log into the smtp server because most
smtp servers do not allow sending email to other domains;relaying(
they should do so anyway). I created an appender which is the same as
SMTPAppenderexcept for the authentication part.
For configuration, just add the additional parameters
##
log4j.appender.email = org.apache.log4j.net.SMTPAuthenticateAppender
log4j.appender.email.BufferSize = 1024
log4j.appender.email.From = <from email>
log4j.appender.email.To = <to email>
log4j.appender.email.SMTPHost = <mail server>
log4j.appender.email.Subject = <subject>
###### Additional ######
log4j.appender.email.UserName = <mail server username>
log4j.appender.email.Password = <mail server password>
log4j.appender.email.Authenticate = <true> ignore case, if something
else than true, no authentication will be done>
###### End Additional ######
log4j.appender.email.layout = org.apache.log4j.PatternLayout
log4j.appender.email.layout.conversionPattern = %d %-5p [%-10t] %c{2} - %m%n
Hope this is helpful
Amin
/*
* Copyright 1999,2004 The Apache Software Foundation.
*
* Licensed 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 java.util.Date;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Layout;
import org.apache.log4j.helpers.CyclicBuffer;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.spi.ErrorCode;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.TriggeringEventEvaluator;
/**
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>SMTPAuthenticateAppender</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.
@author Ceki Gülcü
@since 1.0 */
public class SMTPAuthenticateAppender extends AppenderSkeleton {
private String to;
private String from;
private String subject;
private String SMTPHost;
private Session session;
/**
* Added
* @author Mohd Amin
*/
private String userName;
private String password;
private String authenticate;
private int bufferSize = 512;
private boolean locationInfo = false;
protected CyclicBuffer cb = new CyclicBuffer(bufferSize);
protected Message msg;
protected TriggeringEventEvaluator evaluator;
/**
* @return Returns the bufferSize.
*/
public int getBufferSize() {
return bufferSize;
}
/**
* @param bufferSize The bufferSize to set.
*/
public void setBufferSize(int bufferSize) {
this.bufferSize = bufferSize;
}
/**
* @return Returns the sMTPHost.
*/
public String getSMTPHost() {
return SMTPHost;
}
/**
* @param host The sMTPHost to set.
*/
public void setSMTPHost(String host) {
SMTPHost = host;
}
/**
* @return Returns the authenticate.
*/
public String getAuthenticate() {
return authenticate;
}
/**
* @param authenticate The authenticate to set.
*/
public void setAuthenticate(String authenticate) {
this.authenticate = authenticate;
}
/**
* @return Returns the from.
*/
public String getFrom() {
return from;
}
/**
* @param from The from to set.
*/
public void setFrom(String from) {
this.from = from;
}
/**
* @return Returns the password.
*/
public String getPassword() {
return password;
}
/**
* @param password The password to set.
*/
public void setPassword(String password) {
this.password = password;
}
/**
* @return Returns the subject.
*/
public String getSubject() {
return subject;
}
/**
* @param subject The subject to set.
*/
public void setSubject(String subject) {
this.subject = subject;
}
/**
* @return Returns the userName.
*/
public String getUserName() {
return userName;
}
/**
* @param userName The userName to set.
*/
public void setUserName(String userName) {
this.userName = userName;
}
/**
* @param to The to to set.
*/
public void setTo(String to) {
this.to = to;
}
/**
The default constructor will instantiate the appender with a
[EMAIL PROTECTED] TriggeringEventEvaluator} that will trigger on events with
level ERROR or higher.*/
public SMTPAuthenticateAppender() {
this(new DefaultEvaluator());
}
/**
Use <code>evaluator</code> passed as parameter as the [EMAIL PROTECTED]
TriggeringEventEvaluator} for this SMTPAuthenticateAppender. */
public SMTPAuthenticateAppender(TriggeringEventEvaluator evaluator) {
this.evaluator = evaluator;
}
/**
Activate the specified options, such as the smtp host, the
recipient, from, etc. */
public void activateOptions() {
Properties props = new Properties(System.getProperties());
if (SMTPHost != null) {
props.put("mail.smtp.host", SMTPHost);
if(authenticate != null && authenticate.equalsIgnoreCase("true")) {
props.put("mail.smtp.auth", authenticate);
session = Session.getInstance(props, new SMTPAuthenticator());
} else {
// Remove the need to authenticate. Most developers
will not set the auth to false
props.put("mail.smtp.auth", "false");
session = Session.getInstance(props, null);
}
}
// session.setDebug(true);
msg = new MimeMessage(session);
try {
if (from != null) {
msg.setFrom(getAddress(from));
} else {
msg.setFrom();
}
msg.setRecipients(Message.RecipientType.TO, parseAddress(to));
if (subject != null) {
msg.setSubject(subject);
}
} catch (MessagingException e) {
LogLog.error("Could not activate SMTPAuthenticateAppender options.", e);
}
}
/**
Perform SMTPAuthenticateAppender 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();
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;
}
public synchronized 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>SMTPAuthenticateAppender</code> requires a [EMAIL PROTECTED]
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) {
sbuf.append(t);
}
int len = cb.length();
for (int i = 0; i < len; i++) {
//sbuf.append(MimeUtility.encodeText(layout.format(cb.get())));
LoggingEvent event = cb.get();
sbuf.append(layout.format(event));
if (layout.ignoresThrowable()) {
String[] s = event.getThrowableStrRep();
if (s != null) {
for (int j = 0; j < s.length; j++) {
sbuf.append(s[j]);
sbuf.append(Layout.LINE_SEP);
}
}
}
}
t = layout.getFooter();
if (t != null) {
sbuf.append(t);
}
part.setContent(sbuf.toString(), layout.getContentType());
Multipart mp = new MimeMultipart();
mp.addBodyPart(part);
msg.setContent(mp);
msg.setSentDate(new Date());
Transport.send(msg);
} catch (Exception e) {
LogLog.error("Error occured while sending e-mail notification.", e);
}
}
private class SMTPAuthenticator extends javax.mail.Authenticator
{
public PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(userName, password);
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]