Version 2

    Since it seemed almost impossible to get log4j's SMTPAppender to work with jboss 7 i decided to create a logging handler of my own.

     

    A custom handler must inherit java.util.logging.Handler

     

     

    So without further due, here's the code for the custom email handler.

     

    package com.company.logging;
    
    import java.io.BufferedWriter;
    import java.io.FileWriter;
    import java.io.IOException;
    
    import java.util.Date;
    import java.util.Hashtable;
    import java.util.logging.ErrorManager;
    import java.util.logging.Handler;
    import java.util.logging.LogRecord;
    
    import javax.mail.Address;
    import javax.mail.Message;
    import javax.mail.MessagingException;
    import javax.mail.Session;
    import javax.mail.Transport;
    import javax.mail.internet.AddressException;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeMessage;
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
    
    public class EmailHandler extends Handler {
    
         private Session mailSession;
         
         private String subject;
         private String senderAddress;
         private String recieverAddress;
         private String logFile;
         private String jndiLookup;
         private Boolean debugMode;
    
         public BufferedWriter out = null;
         
         
         public EmailHandler() {
              super();
              jndiLookup = "java:jboss/mail/Default";
              debugMode = false;
              logFile = "";
         }
         
         @Override
         public void publish(LogRecord record) {
              if (!initialize()) {
                   return;
              }
              if(isLoggable(record)) {
                   process(record);
              }
         }
    
         private synchronized boolean initialize() {
              if (out==null && logFile!=null && !logFile.equals("")) {
                   FileWriter fstream = null;
                   try {
                        fstream = new FileWriter(logFile,true);
                        out = new BufferedWriter(fstream);
                   } catch (IOException e) {
                        reportError(e.getMessage(), e, ErrorManager.OPEN_FAILURE);
                   }
                   logToFile("Log file initialized. Logging to: " + logFile);
              }
              if(mailSession==null) {
                   final Hashtable jndiProperties = new Hashtable();  
                   jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
                   Context context;
                   String jndiNamespace = jndiLookup;
                   if(debugMode) logToFile("Trying to initialize the mail session from jndi");
                   try {
                        context = new InitialContext(jndiProperties);
                        if(debugMode) logToFile("Initial context was "+(context==null?"not found":"found"));
                        mailSession = (Session) context.lookup(jndiNamespace);
                        if(debugMode) logToFile("Mail session was "+(mailSession==null?"not found":"found"));
                   } catch (NamingException e) {
                        String message = "There was an error initializing the mail session";
                        if(debugMode) logToFile(message + ": "+ e.getMessage());
                        reportError(message, e, ErrorManager.GENERIC_FAILURE);
                        return false;
                   }  
              }
              return true;
         }
    
         private void process(LogRecord logRecord) {
    
              if(debugMode) logToFile("New mail should be sent");
              MimeMessage m = new MimeMessage(mailSession);
              if(debugMode) logToFile("New mail created");
              Address from;
              try {
                   from = new InternetAddress(senderAddress);
                   if(debugMode) logToFile("Sender address: " + senderAddress);
                   Address[] to = new InternetAddress[] {new InternetAddress(recieverAddress) };
                   if(debugMode) logToFile("Reciepient address: " + recieverAddress);
                   m.setFrom(from);  
                   m.setRecipients(Message.RecipientType.TO, to);  
                   m.setSubject(subject);
                   if(debugMode) logToFile("Subject: "+ subject);
                   m.setSentDate(new java.util.Date());  
                   m.setContent(getFormatter().format(logRecord),"text/plain");
                   Transport.send(m);  
                   if(debugMode) {
                        logToFile("Mail successfully sent");
                   } else {
                        logToFile("Mail successfully sent to: "+ senderAddress);
                   }
              } catch (AddressException e) {
                   String message = "Could not resolve address";
                   if(debugMode) logToFile(message + ": "+ e.getMessage());
                   reportError(message, e, ErrorManager.GENERIC_FAILURE);
              } catch (MessagingException e) {
                   String message = "Mail could not be sent due to";
                   if(debugMode) logToFile(message + ": "+ e.getMessage());
                   reportError(message, e, ErrorManager.GENERIC_FAILURE);
              }  
         }
    
         private void logToFile(String text) {
              try {
                   if (out!=null) {
                        out.write((new Date()).toString() + "\t" + text+"\n");
                        out.flush();
                   }
              } catch (IOException e) {
                   reportError(e.getMessage(), e, ErrorManager.WRITE_FAILURE);
              }
              
         }
    
    
    
         @Override
         public void flush() {
              try {
                   if (out!=null) {
                        out.flush();
                   }
              } catch (IOException e) {
                   reportError(e.getMessage(), e, ErrorManager.FLUSH_FAILURE);
              }
         }
    
    
         @Override
         public void close()     {
              if(out!=null) {
                   try {
                        out.close();
                   } catch (IOException e) {
                        reportError(e.getMessage(), e, ErrorManager.CLOSE_FAILURE);
                   }
    
              }
         }
    
    
         public void setSubject(String subject) {
              this.subject = subject;
         }
    
         public void setSenderAddress(String senderAddress) {
              this.senderAddress = senderAddress;
         }
    
         public void setRecieverAddress(String recieverAddress) {
              this.recieverAddress = recieverAddress;
         }
    
         public void setLogFile(String logFile) {
              this.logFile = logFile;
         }
    
         public void setJndiLookup(String jndiLookup) {
              this.jndiLookup = jndiLookup;
         }
         
         public void setDebugMode(String debugMode) {
              this.debugMode = false;
              try {
                   this.debugMode = Boolean.parseBoolean(debugMode);
              } catch (Exception e) {
              }
         }
    }
    

     

     

    The file is then packaged into a jar and placed in the modules directory. i.e. Jboss-as-7.1.0.Final/modules/com/company/loggers/main

    together with a module.xml file. The contents of the module.xml should look like this.

     

      

    <?xml version="1.0" encoding="UTF-8"?> 
    <module xmlns="urn:jboss:module:1.0" name="com.company.loggers">
         <resources>    
               <resource-root path="EmailHandler.jar"/>
              <!-- Insert resources here --> 
         </resources>  
         <dependencies>    
              <module name="org.jboss.logging"/>
              <module name="javax.api"/> 
              <module name="javax.mail.api"/> 
         </dependencies>
    </module> 
    

     

     

    Then modify the standalone.xml to support logging to the custom logger

     

     

                <custom-handler name="EmailAppender" class="com.company.logging.EmailHandler" module="com.company.loggers">
                    <level name="ERROR"/>
                    <formatter>
                        <pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
                    </formatter>
                    <properties>
                        <property name="jndiLookup" value="java:jboss/mail/Default"/>
                        <property name="subject" value="[SMTPAppender] Application message"/>
                        <property name="senderAddress" value="sender@server" />
                        <property name="recieverAddress" value="reciepient@domain.com"/>
                        <property name="logFile" value="c:\\temp\\logfile.txt"/>
                        <property name="debugMode" value="true"/>
                    </properties>
                </custom-handler>
    

     

    And also set up the mail subsystem and modify the remote-destination host accordingly

     

     

        <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
            <socket-binding name="http" port="8080"/>
            <socket-binding name="https" port="8443"/>
            <socket-binding name="management-native" interface="management" port="${jboss.management.native.port:9999}"/>
            <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
            <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9443}"/>
            <socket-binding name="osgi-http" interface="management" port="8090"/>
            <socket-binding name="remoting" port="4447"/>
            <socket-binding name="txn-recovery-environment" port="4712"/>
            <socket-binding name="txn-status-manager" port="4713"/>
            <outbound-socket-binding name="mail-smtp">
                <remote-destination host="smtp.yourserver.com" port="25"/>
            </outbound-socket-binding>
        </socket-binding-group>
    

     

    Don't forget to add the EmailAppender to the root logger as well.

     

     

    Kind Regards

    /Danjel Nyberg