bb.util.logging
Class HandlerEmail

java.lang.Object
  extended by java.util.logging.Handler
      extended by bb.util.logging.HandlerAbstract
          extended by bb.util.logging.HandlerEmail

public class HandlerEmail
extends HandlerAbstract

Logs to an email account.

One feature of this class is that it dynamically adjusts a capture window time. The first LogRecord to be published will be emailed with very small delay (1 second), but if many more LogRecords arrive soon thereafter, the delay will be exponentially increased (up to 1 minute) in order to batch as many LogRecords as possible into a single email. See getLogRecords for details.

It can be useful to attach an instance to the root Logger, and have it publish serious logs.

It is unclear whether or not this class is multithread safe. There may be issues with its superclass; see HandlerAbstract for more discussion. Concerning the state added by this class, every method is synchronized (in the case of getLogRecords, it is internally synchronized in multiple places; see code).

Author:
Brent Boyer

Nested Class Summary
private static class HandlerEmail.EmailSender
           
static class HandlerEmail.UnitTest
          See the Overview page of the project's javadocs for a general description of this unit test class.
 
Field Summary
private  BufferFixed<LogRecord> bufferFixed
          Accumulates the next snapshot of LogRecords that is to be emailed.
private  File emailConfigFile
          Is the property File that configures threadEmailer's emailer.
private  String emailDestAddr
          Is the email destination address field used by threadEmailer's emailer.
private  String subjectPrefix
          Is the email subject field's prefix used by threadEmailer's emailer.
private  Thread threadEmailer
          Executes a HandlerEmail.EmailSender instance.
private  long timeSleep
          Is used by getLogRecords to implement email rate throttling.
 
Constructor Summary
HandlerEmail()
          Convenience constructor.
HandlerEmail(int sizeMax, File emailConfigFile, String subjectPrefix, String emailDestAddr)
          Fundamental constructor.
 
Method Summary
 void close()
          First call releases all resources used by this instance.
 void flush()
          Implementation here does nothing, since the notify done by publish effectively acts as an auto-flush if threadEmailer is waiting inside getLogRecords.
protected  Level getLevelDefault()
          Implementation here returns Level.WARNING.
private  String getLogRecords()
           
 void publish(LogRecord record)
          If isAlive or isLoggable(record) returns false, then immediately returns.
 
Methods inherited from class bb.util.logging.HandlerAbstract
configure, getEncodingDefault, getFilterDefault, getFilterProperty, getFormatterDefault, getFormatterProperty, getIntProperty, getLevelProperty, getStringProperty, isAlive, isLoggable, setAlive
 
Methods inherited from class java.util.logging.Handler
getEncoding, getErrorManager, getFilter, getFormatter, getLevel, reportError, setEncoding, setErrorManager, setFilter, setFormatter, setLevel
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

bufferFixed

private BufferFixed<LogRecord> bufferFixed
Accumulates the next snapshot of LogRecords that is to be emailed.

Contract: is never null after construction, but is nulled out once and for all when close is first called.


emailConfigFile

private File emailConfigFile
Is the property File that configures threadEmailer's emailer.

Contract: is never null after construction, but is nulled out once and for all when close is first called.


subjectPrefix

private String subjectPrefix
Is the email subject field's prefix used by threadEmailer's emailer. The complete subject field will end in a timestamp that is added by the EmailSender.

Contract: is never blank after construction, but is nulled out once and for all when close is first called.


emailDestAddr

private String emailDestAddr
Is the email destination address field used by threadEmailer's emailer.

Contract: is never blank after construction, but is nulled out once and for all when close is first called.


threadEmailer

private Thread threadEmailer
Executes a HandlerEmail.EmailSender instance.

Contract: is null until lazy initialized by publish, then is nulled out once and for all when close is first called.


timeSleep

private long timeSleep
Is used by getLogRecords to implement email rate throttling.

Contract: is > 0.

Constructor Detail

HandlerEmail

public HandlerEmail()
Convenience constructor.

Some of this instance's initial configuration comes from the LogManager properties described in HandlerAbstract.configure. However, the BufferFixed.sizeMax field is assigned from calling getIntProperty(getClass().getName() + ".sizeMax", 1000). In other words, BufferFixed.sizeMax is set to whatever is defined for it in the logging properties file, else it defaults to 1000 if not defined there. Similarly, the emailConfigFile, subjectPrefix, and emailDestAddr fields are assigned from .emailConfigFile, .subjectPrefix, and .emailDestAddr properties respectively.


HandlerEmail

public HandlerEmail(int sizeMax,
                    File emailConfigFile,
                    String subjectPrefix,
                    String emailDestAddr)
             throws IllegalArgumentException
Fundamental constructor.

Some of this instance's initial configuration comes from the LogManager properties described in HandlerAbstract.configure. However, the BufferFixed.sizeMax, emailConfigFile, subjectPrefix, and emailDestAddr fields are assigned from the corresponding params.

Throws:
IllegalArgumentException - if sizeMax <= 0; emailConfigFile is not valid; subjectPrefix or emailDestAddr is blank
Method Detail

close

public void close()
First call releases all resources used by this instance. All future calls to publish will be silently ignored.

Overrides:
close in class HandlerAbstract

flush

public void flush()
Implementation here does nothing, since the notify done by publish effectively acts as an auto-flush if threadEmailer is waiting inside getLogRecords.

Specified by:
flush in class Handler

publish

public void publish(LogRecord record)
If isAlive or isLoggable(record) returns false, then immediately returns. Else adds record to bufferFixed and notifies threadEmailer if is waiting inside getLogRecords.

Specified by:
publish in class Handler

getLevelDefault

protected Level getLevelDefault()
Implementation here returns Level.WARNING.

Overrides:
getLevelDefault in class HandlerAbstract

getLogRecords

private String getLogRecords()
                      throws InterruptedException
Throws:
InterruptedException