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&uuml;lc&uuml;
   @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]

Reply via email to