The version of Apache log4j used by SoundHelix.
Clone
HTTPS:
git clone https://vervis.peers.community/repos/aEp6o
SSH:
git clone USERNAME@vervis.peers.community:aEp6o
Branches
Tags
- 1.3alpha-7
- CHAINSAW_2_SANDBOX_MERGE
- CORE_VERSION
- LEVEL_REPLACES_PRIORITY
- PREALPHA_1_3_AS_OF_2004_05_12
- PRE_CHAINSAW_MODEL_CONVERSION
- PRE_UGLI_MOVE
- TAG_CHAINSAW2_MOVE
- log4j-1.2.17
- log4j-1.2.17-rc1
- v1.3alpha8
- v1.3alpha8-temp
- v1_2_1
- v1_2_10-recalled
- v1_2_11
- v1_2_11_rc1
- v1_2_11rc3
- v1_2_12
- v1_2_12_rc1
- v1_2_12_rc2
- v1_2_12_rc3
- v1_2_12_rc4
- v1_2_12_rc5
- v1_2_12_rc6
- v1_2_13
- v1_2_13_rc1
- v1_2_13_rc2
- v1_2_13_site_update
- v1_2_14
- v1_2_14_maven
- v1_2_14_rc1
- v1_2_14_site_update
- v1_2_15
- v1_2_15_rc1
- v1_2_15_rc2
- v1_2_15_rc3
- v1_2_15_rc4
- v1_2_15_rc5
- v1_2_15_rc6
- v1_2_16
- v1_2_16_rc1
- v1_2_16_rc2
- v1_2_17
- v1_2_17-rc1
- v1_2_17_rc1
- v1_2_17_rc2
- v1_2_17_rc3
- v1_2_2
- v1_2_3
- v1_2_4
- v1_2_6
- v1_2_7
- v1_2_9
- v1_2_alpha0
- v1_2_alpha7
- v1_2beta1
- v1_2final
- v1_3alpha_1
- v1_3alpha_6
- v_1_0
- v_1_0_1
- v_1_0_4
- v_1_1
- v_1_1_1
- v_1_1_2
- v_1_1_3
- v_1_1_b1
- v_1_1b2
- v_1_1b3
- v_1_1b5
- v_1_1b6
- v_1_1b7
- v_1_2beta3
SMTPAppender.java
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software
* License version 1.1, a copy of which has been included with this
* distribution in the LICENSE.APL file. */
package org.apache.log4j.net;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Layout;
import org.apache.log4j.Priority;
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.ErrorHandler;
import org.apache.log4j.spi.TriggeringEventEvaluator;
import java.util.Properties;
import java.util.Date;
import javax.mail.Session;
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;
import javax.mail.internet.MimeUtility;
/**
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.
@author Ceki Gülcü
@since 1.0 */
public class SMTPAppender extends AppenderSkeleton {
String to;
String from;
String subject;
String smtpHost;
int bufferSize = 512;
CyclicBuffer cb = new CyclicBuffer(bufferSize);
Session session;
Message msg;
boolean locationInfo = false;
/**
A string constant used in naming the <em>To</em> field of
outgoing e-mail output file. Current value of this string
constant is <b>To</b>.
<p>Note that all option keys are case sensitive.
@deprecated Options are now handled using the JavaBeans paradigm.
This constant will be removed in the <em>near</em> term.
*/
public static final String TO_OPTION = "To";
/**
A string constant used in naming the <em>From</em> field of
outgoing e-mail output file. Current value of this string
constant is <b>From</b>.
<p>Note that all option keys are case sensitive.
@deprecated Options are now handled using the JavaBeans paradigm.
This constant will be removed in the <em>near</em> term.
*/
public static final String FROM_OPTION = "From";
/**
A string constant used in naming the <em>Subject</em> field of
outgoing e-mail output file. Current value of this string
constant is <b>Subject</b>.
<p>Note that all option keys are case sensitive.
@deprecated Options are now handled using the JavaBeans paradigm.
This constant will be removed in the <em>near</em> term.
*/
public static final String SUBJECT_OPTION = "Subject";
/**
A string constant used in naming the SMTP host that will be
contacted to send the e-mail. Current value of this string
constant is <b>SMTPHost</b>.
<p>Note that all option keys are case sensitive.
@deprecated Options are now handled using the JavaBeans paradigm.
This constant will be removed in the <em>near</em> term.
*/
public static final String SMTP_HOST_OPTION = "SMTPHost";
/**
A string constant used in naming the cyclic buffer size option.
Current value of this string constant is <b>BufferSize</b>.
<p>Note that all option keys are case sensitive.
@deprecated Options are now handled using the JavaBeans paradigm.
This constant will be removed in the <em>near</em> term.
*/
public static final String BUFFER_SIZE_OPTION = "BufferSize";
/**
A string constant used in naming the class of the
TriggeringEventEvaluator that this SMTPApepdner wll use. Current
value of this string constant is <b>EvaluatorClass</b>.
<p>Note that all option keys are case sensitive.
@deprecated Options are now handled using the JavaBeans paradigm.
This constant will be removed in the <em>near</em> term.
*/
public static final String EVALUATOR_CLASS_OPTION = "EvaluatorClass";
/**
A string constant used in naming the option for setting the the
location information flag. Current value of this string
constant is <b>LocationInfo</b>.
<p>Note that all option keys are case sensitive.
@deprecated Options are now handled using the JavaBeans paradigm.
This constant will be removed in the <em>near</em> term.
*/
public static final String LOCATION_INFO_OPTION = "LocationInfo";
protected TriggeringEventEvaluator evaluator;
/**
The default constructor will instantiate the appender with a
{@link TriggeringEventEvaluator} that will tirgger on events with
priority 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;
}
/**
Retuns the option names for this component in addition in
addition to the options of its super class {@link
AppenderSkeleton}.
@deprecated We now use JavaBeans introspection to configure
components. Options strings are no longer needed.
*/
public
String[] getOptionStrings() {
return OptionConverter.concatanateArrays(super.getOptionStrings(),
new String[] {TO_OPTION, FROM_OPTION, SUBJECT_OPTION,
SMTP_HOST_OPTION, BUFFER_SIZE_OPTION,
EVALUATOR_CLASS_OPTION, LOCATION_INFO_OPTION });
}
/**
Activate the specified options, such as the smtp host, the
recipient, from, etc. */
public
void activateOptions() {
Properties props = System.getProperties();
if (smtpHost != null)
props.put("mail.smtp.host", smtpHost);
session = Session.getDefaultInstance(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 SMTPAppender options.", e );
}
}
/**
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();
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 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]);
}
}
}
}
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);
}
}
/**
Returns value of the <b>EvaluatorClass</b> option.
*/
public
String getEvaluatorClass() {
return evaluator == null ? null : evaluator.getClass().getName();
}
/**
Returns value of the <b>From</b> option.
*/
public
String getFrom() {
return from;
}
/**
Returns value of the <b>Subject</b> option.
*/
public
String getSubject() {
return subject;
}
/**
@deprecated Use the setter method for the option directly, instead
of the generic <code>setOption</code> method. */
public
void setOption(String option, String value) {
if(value == null) return;
super.setOption(option, value);
if(option.equals(TO_OPTION))
to = value;
else if (option.equals(FROM_OPTION))
from = value;
else if (option.equals(SMTP_HOST_OPTION))
smtpHost = value;
else if (option.equals(SUBJECT_OPTION))
subject = value;
else if (option.equals(EVALUATOR_CLASS_OPTION)) {
evaluator = (TriggeringEventEvaluator)
OptionConverter.instantiateByClassName(value,
TriggeringEventEvaluator.class,
evaluator);
} else if (option.equals(BUFFER_SIZE_OPTION)) {
bufferSize = OptionConverter.toInt(value, bufferSize);
cb.resize(bufferSize);
} else if (option.equals(LOCATION_INFO_OPTION))
locationInfo = OptionConverter.toBoolean(value, locationInfo);
}
/**
The <b>From</b> option takes a string value which should be a
e-mail address of the sender.
*/
public
void setFrom(String from) {
this.from = from;
}
/**
The <b>Subject</b> option takes a string value which should be a
the subject of the e-mail message.
*/
public
void setSubject(String subject) {
this.subject = subject;
}
/**
The <b>BufferSize</b>option takes a positive integer
representing the maximum number of logging events to collect in a
cyclic buffer. When the <code>BufferSize</code> is reached,
oldest events are deleted as new events are added to the
buffer. By default the size of the cyclic buffer is 512 events.
*/
public
void setBufferSize(int bufferSize) {
this.bufferSize = bufferSize;
cb.resize(bufferSize);
}
/**
The <b>SMTPHost</b> option takes a string value which should be a
the host name of the SMTP server that will send the e-mail message.
*/
public
void setSMTPHost(String smtpHost) {
this.smtpHost = smtpHost;
}
/**
Returns value of the <b>SMTPHost</b> option.
*/
public
String getSMTPHost() {
return smtpHost;
}
/**
The <b>To</b> option takes a string value which should be a
comma separated list of e-mail address of the recipients.
*/
public
void setTo(String to) {
this.to = to;
}
/**
Returns value of the <b>BufferSize</b> option.
*/
public
int getBufferSize() {
return bufferSize;
}
/**
The <b>EvaluatorClass</b> option takes a string value
repsenting the name of the class implementing the {@link
TriggeringEventEvaluator} interface. A corresponding object will
be instantiated and assigned as the triggering event evaluator
for the SMTPAppender.
*/
public
void setEvaluatorClass(String value) {
evaluator = (TriggeringEventEvaluator)
OptionConverter.instantiateByClassName(value,
TriggeringEventEvaluator.class,
evaluator);
}
/**
The <b>LocationInfo</b> option takes a boolean value. By
default, it is set to false which means there will be no effort
to extract the location information related to the event. As a
result, the layout that formats the events as they are sent out
in an e-mail is likely to place the wrong location information
(if present in the format).
<p>Location information extraction is comparatively very slow and
should be avoided unless performance is not a concern.
*/
public
void setLocationInfo(boolean locationInfo) {
this.locationInfo = locationInfo;
}
/**
Returns value of the <b>LocationInfo</b> option.
*/
public
boolean getLocationInfo() {
return locationInfo;
}
}
class DefaultEvaluator implements TriggeringEventEvaluator {
/**
Is this <code>event</code> the e-mail triggering event?
<p>This method returns <code>true</code>, if the event priority
has ERROR priority or higher. Otherwisem it returns
<code>false</code>. */
public
boolean isTriggeringEvent(LoggingEvent event) {
return event.priority.isGreaterOrEqual(Priority.ERROR);
}
}