1. 程式人生 > >比較全面的log4j配置

比較全面的log4j配置

話不多說先來個properties版本的 我以前一直使用的是properties來配置的

#定義根級別
log4j.rootLogger=info,warn,error,console,mail

#定義專案輸出日誌級別
log4j.logger.org.system=debug
log4j.logger.org.main=info
log4j.logger.org.tools=info
log4j.logger.org.springframework=warn

#控制檯輸出生成階段註釋
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%-d{MM-ddHH:mm:ss}-[%p][%c{3}]%m%n

###info級別輸出
log4j.appender.info=org.apache.log4j.DailyRollingFileAppender
#輸出到Tomcat的logs目錄下
log4j.appender.info.File=${catalina.home}/logs/${webapp.root}/infrastructure/info.log
log4j.appender.info.Append=true
log4j.appender.info.Threshold=info
log4j.appender.info.layout=org.apache.log4j.PatternLayout
log4j.appender.info.layout.ConversionPattern=%-d{MM-ddHH:mm:ss}-[%p][%c{3}]%m%n
log4j.appender.info.datePattern='.'yyyy-MM-dd
log4j.appender.info.BufferedIO=true
#Buffer單位為位元組,預設是8K,IOBLOCK大小預設也是8K 這樣配置就可以不每一條都寫入檔案 注意得結合上一句使用 但是效能提高了也會有其他問題到時候就知道了
log4j.appender.info.BufferSize=8192
#定製過濾器只過濾info級別
log4j.appender.info.filter.infoFilter=org.apache.log4j.varia.LevelRangeFilter
log4j.appender.info.filter.infoFilter.LevelMin=info
log4j.appender.info.filter.infoFilter.LevelMax=info

###warn級別輸出
log4j.appender.warn=org.apache.log4j.DailyRollingFileAppender
log4j.appender.warn.File=${catalina.home}/logs/${webapp.root}/infrastructure/warn.log
log4j.appender.warn.Append=true
log4j.appender.warn.Threshold=warn
log4j.appender.warn.layout=org.apache.log4j.PatternLayout
log4j.appender.warn.layout.ConversionPattern=%-d{MM-ddHH:mm:ss}-[%p][%c]%m%n
log4j.appender.warn.datePattern='.'yyyy-MM-dd
log4j.appender.warn.BufferedIO=true
#Buffer單位為位元組,預設是8K,IOBLOCK大小預設也是8K
log4j.appender.warn.BufferSize=8192
#定製過濾器只過濾warn級別
log4j.appender.warn.filter.warnFilter=org.apache.log4j.varia.LevelRangeFilter
log4j.appender.warn.filter.warnFilter.LevelMin=WARN
log4j.appender.warn.filter.warnFilter.LevelMax=WARN

###error級別輸出
log4j.appender.error=org.apache.log4j.DailyRollingFileAppender
log4j.appender.error.File=${catalina.home}/logs/${webapp.root}/infrastructure/error.log
log4j.appender.error.Append=true
log4j.appender.error.Threshold=error
log4j.appender.error.layout=org.apache.log4j.PatternLayout
log4j.appender.error.layout.ConversionPattern=%-d{MM-ddHH:mm:ss}-[%p][%c]%m%n
log4j.appender.error.datePattern='.'yyyy-MM-dd
#設定使用緩衝
log4j.appender.error.BufferedIO=true
#Buffer單位為位元組,預設是8K,IOBLOCK大小預設也是8K
log4j.appender.error.BufferSize=8192
#定製過濾器只過濾error級別
log4j.appender.error.filter.errorFilter=org.apache.log4j.varia.LevelRangeFilter
log4j.appender.error.filter.errorFilter.LevelMin=error
log4j.appender.error.filter.errorFilter.LevelMax=error

#異常郵件傳送配置
#log4j的郵件傳送appender,如果有必要你可以寫自己的appender
log4j.appender.mail=org.apache.log4j.net.SMTPAppender
#傳送郵件的門檻,僅當等於或高於ERROR(比如FATAL)時,郵件才被髮送
log4j.appender.mail.Threshold=error
#設定使用緩衝
log4j.appender.mail.BufferedIO=true
#Buffer單位為位元組,預設是8K,IOBLOCK大小預設也是8K
log4j.appender.mail.BufferSize=8192
log4j.appender.mail.layout=org.apache.log4j.PatternLayout
log4j.appender.mail.layout.ConversionPattern=%-d{MM-ddHH:mm:ss}-[%p][%c]%m%n
#傳送郵件的郵箱帳號
[email protected]
#SMTP郵件傳送伺服器地址 log4j.appender.mail.SMTPHost=smtp.163.com #SMTP傳送認證的帳號名 [email protected] #SMTP傳送認證帳號的密碼 log4j.appender.mail.SMTPPassword=**************** #是否列印除錯資訊,如果選true,則會輸出和SMTP之間的握手等詳細資訊 log4j.appender.mail.SMTPDebug=false #郵件主題 log4j.appender.mail.Subject=服務異常日誌 #傳送到什麼郵箱,如果要傳送給多個郵箱,則用逗號分隔; #如果需要發副本給某人,則加入下列行 #log4j.appender.mail.Bcc=*********@qq.com log4j.appender.mail.To=**********@qq.com

這就是properties版本的 很多已經打了註釋 但是遇上幾個問題

1.傳送郵件是採用同步傳送的,這樣將會遇到有錯誤日誌傳送時可能會很慢 實際上確實很慢

2.傳送郵件是發現每次報ERROR及以上的錯誤日誌時都會觸發傳送郵件的事件 好多帖子都說可以通過下面配置來緩衝資料 當達到這個資料量時才會傳送

log4j.appender.mail.BufferedIO=true
#Buffer單位為位元組,預設是8K,IOBLOCK大小預設也是8K
log4j.appender.mail.BufferSize=8192

然後測試並沒有什麼卵用(也隨便吐槽下好多都是複製人家的部落格,複製也罷你好歹也測試測試吧,真禍害人)不過也多虧了這些人才逼得自己去看了原始碼 然後在這裡糾正一下  

BufferedIO=true這個沒卵用自己也對應把之前發出來的配置修改一下 畢竟還是要知道問什麼

BufferSize=8192這個的意思是log4j會幫你保持的日誌Event的個數 預設是512並不是上面8192  拿預設的舉個例子 你要是日誌event超過512那麼513就會覆蓋之前的就是這個意思而已

然後看了網路上的好多文章真的是個字不差 說什麼加下面配置就可以非同步傳送且是當內容大小達到某值時才傳送(哎,害人不淺 非同步倒是可以 擺脫看看原始碼 原始碼中的append中這一句)

	if (evaluator.isTriggeringEvent(event) ) {
			sendBuffer();
		}

然後跟蹤evaluator.isTriggeringEvent(event)方法
  /**
     Is this <code>event</code> the e-mail triggering event?

     <p>This method returns <code>true</code>, if the event level
     has ERROR level or higher. Otherwise it returns
     <code>false</code>. */
  public
  boolean isTriggeringEvent(LoggingEvent event) {
    return event.getLevel().isGreaterOrEqual(Level.ERROR);
  }

這尼瑪分明是說只有日誌級別達到了error及以上就返回true 所以你不管同步非同步都是報錯就來個郵件 

算了直接上解決方案 重寫下面這個類 多加了errorSize引數 當錯誤日誌數達到多少個在傳送

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.main.log4j;

import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Layout;
import org.apache.log4j.Level;
import org.apache.log4j.helpers.CyclicBuffer;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.helpers.OptionConverter;
import org.apache.log4j.spi.ErrorCode;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.OptionHandler;
import org.apache.log4j.spi.TriggeringEventEvaluator;
import org.apache.log4j.xml.UnrecognizedElementHandler;
import org.w3c.dom.Element;

import javax.mail.Authenticator;
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.InternetHeaders;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.Date;
import java.util.Properties;

/**
 * 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.
 * 
 * By default, an email message will be sent when an ERROR or higher severity
 * message is appended. The triggering criteria can be modified by setting the
 * evaluatorClass property with the name of a class implementing
 * TriggeringEventEvaluator, setting the evaluator property with an instance of
 * TriggeringEventEvaluator or nesting a triggeringPolicy element where the
 * specified class implements TriggeringEventEvaluator.
 * 
 * This class has implemented UnrecognizedElementHandler since 1.2.15.
 * 
 * Since 1.2.16, SMTP over SSL is supported by setting SMTPProtocol to "smpts".
 * 
 * @author Ceki Gülcü
 * @since 1.0
 */
public class SMTPAppender extends AppenderSkeleton implements UnrecognizedElementHandler {
	private String to;
	/**
	 * Comma separated list of cc recipients.
	 */
	private String cc;
	/**
	 * Comma separated list of bcc recipients.
	 */
	private String bcc;
	private String from;
	/**
	 * Comma separated list of replyTo addresses.
	 */
	private String replyTo;
	private String subject;
	private String smtpHost;
	private String smtpUsername;
	private String smtpPassword;
	private String smtpProtocol;
	private int smtpPort = -1;
	private boolean smtpDebug = false;
	private int bufferSize = 512;
	private int errorSize = 512;
	private boolean locationInfo = false;
	private boolean sendOnClose = false;

	protected CyclicBuffer cb = new CyclicBuffer(bufferSize);
	protected Message msg;

	protected TriggeringEventEvaluator evaluator;

	/**
	 * The default constructor will instantiate the appender with a
	 * {@link TriggeringEventEvaluator} that will trigger on events with level
	 * 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;
	}

	public int getErrorSize() {
		return errorSize;
	}

	public void setErrorSize(int errorSize) {
		this.errorSize = errorSize;
	}

	/**
	 * Activate the specified options, such as the smtp host, the recipient,
	 * from, etc.
	 */
	public void activateOptions() {
		Session session = createSession();
		msg = new MimeMessage(session);

		try {
			addressMessage(msg);
			if (subject != null) {
				try {
					msg.setSubject(MimeUtility.encodeText(subject, "UTF-8", null));
				} catch (UnsupportedEncodingException ex) {
					LogLog.error("Unable to encode SMTP subject", ex);
				}
			}
		} catch (MessagingException e) {
			LogLog.error("Could not activate SMTPAppender options.", e);
		}

		if (evaluator instanceof OptionHandler) {
			((OptionHandler) evaluator).activateOptions();
		}
	}

	/**
	 * Address message.
	 * 
	 * @param msg
	 *            message, may not be null.
	 * @throws MessagingException
	 *             thrown if error addressing message.
	 * @since 1.2.14
	 */
	protected void addressMessage(final Message msg) throws MessagingException {
		if (from != null) {
			msg.setFrom(getAddress(from));
		} else {
			msg.setFrom();
		}

		// Add ReplyTo addresses if defined.
		if (replyTo != null && replyTo.length() > 0) {
			msg.setReplyTo(parseAddress(replyTo));
		}

		if (to != null && to.length() > 0) {
			msg.setRecipients(Message.RecipientType.TO, parseAddress(to));
		}

		// Add CC receipients if defined.
		if (cc != null && cc.length() > 0) {
			msg.setRecipients(Message.RecipientType.CC, parseAddress(cc));
		}

		// Add BCC receipients if defined.
		if (bcc != null && bcc.length() > 0) {
			msg.setRecipients(Message.RecipientType.BCC, parseAddress(bcc));
		}
	}

	/**
	 * Create mail session.
	 * 
	 * @return mail session, may not be null.
	 * @since 1.2.14
	 */
	protected Session createSession() {
		Properties props = null;
		try {
			props = new Properties(System.getProperties());
		} catch (SecurityException ex) {
			props = new Properties();
		}

		String prefix = "mail.smtp";
		if (smtpProtocol != null) {
			props.put("mail.transport.protocol", smtpProtocol);
			prefix = "mail." + smtpProtocol;
		}
		if (smtpHost != null) {
			props.put(prefix + ".host", smtpHost);
		}
		if (smtpPort > 0) {
			props.put(prefix + ".port", String.valueOf(smtpPort));
		}

		Authenticator auth = null;
		if (smtpPassword != null && smtpUsername != null) {
			props.put(prefix + ".auth", "true");
			auth = new Authenticator() {
				protected PasswordAuthentication getPasswordAuthentication() {
					return new PasswordAuthentication(smtpUsername, smtpPassword);
				}
			};
		}
		Session session = Session.getInstance(props, auth);
		if (smtpProtocol != null) {
			session.setProtocolForAddress("rfc822", smtpProtocol);
		}
		if (smtpDebug) {
			session.setDebug(smtpDebug);
		}
		return session;
	}

	/**
	 * 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();
		event.getMDCCopy();
		if (locationInfo) {
			event.getLocationInformation();
		}
		event.getRenderedMessage();
		event.getThrowableStrRep();
		cb.add(event);
		if (evaluator.isTriggeringEvent(event) && cb.length() >= errorSize) {
			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;
		if (sendOnClose && cb.length() > 0) {
			sendBuffer();
		}
	}

	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 org.apache.log4j.Layout
	 * layout}.
	 */
	public boolean requiresLayout() {
		return true;
	}

	/**
	 * Layout body of email message.
	 * 
	 * @since 1.2.16
	 */
	protected String formatBody() {

		// Note: this code already owns the monitor for this
		// appender. This frees us from needing to synchronize on 'cb'.

		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);
		}

		return sbuf.toString();
	}

	/**
	 * Send the contents of the cyclic buffer as an e-mail message.
	 */
	protected void sendBuffer() {

		try {
			String s = formatBody();
			boolean allAscii = true;
			for (int i = 0; i < s.length() && allAscii; i++) {
				allAscii = s.charAt(i) <= 0x7F;
			}
			MimeBodyPart part;
			if (allAscii) {
				part = new MimeBodyPart();
				part.setContent(s, layout.getContentType());
			} else {
				try {
					ByteArrayOutputStream os = new ByteArrayOutputStream();
					Writer writer = new OutputStreamWriter(MimeUtility.encode(os, "quoted-printable"), "UTF-8");
					writer.write(s);
					writer.close();
					InternetHeaders headers = new InternetHeaders();
					headers.setHeader("Content-Type", layout.getContentType() + "; charset=UTF-8");
					headers.setHeader("Content-Transfer-Encoding", "quoted-printable");
					part = new MimeBodyPart(headers, os.toByteArray());
				} catch (Exception ex) {
					StringBuffer sbuf = new StringBuffer(s);
					for (int i = 0; i < sbuf.length(); i++) {
						if (sbuf.charAt(i) >= 0x80) {
							sbuf.setCharAt(i, '?');
						}
					}
					part = new MimeBodyPart();
					part.setContent(sbuf.toString(), layout.getContentType());
				}
			}

			Multipart mp = new MimeMultipart();
			mp.addBodyPart(part);
			msg.setContent(mp);

			msg.setSentDate(new Date());
			Transport.send(msg);
		} catch (MessagingException e) {
			LogLog.error("Error occured while sending e-mail notification.", e);
		} catch (RuntimeException 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;
	}

	/**
	 * Get the reply addresses.
	 * 
	 * @return reply addresses as comma separated string, may be null.
	 * @since 1.2.16
	 */
	public String getReplyTo() {
		return replyTo;
	}

	/**
	 * Returns value of the <b>Subject</b> option.
	 */
	public String getSubject() {
		return subject;
	}

	/**
	 * 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;
	}

	/**
	 * Set the e-mail addresses to which replies should be directed.
	 * 
	 * @param addresses
	 *            reply addresses as comma separated string, may be null.
	 * @since 1.2.16
	 */
	public void setReplyTo(final String addresses) {
		this.replyTo = addresses;
	}

	/**
	 * 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 representing 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;
	}

	/**
	 * Set the cc recipient addresses.
	 * 
	 * @param addresses
	 *            recipient addresses as comma separated string, may be null.
	 * @since 1.2.14
	 */
	public void setCc(final String addresses) {
		this.cc = addresses;
	}

	/**
	 * Get the cc recipient addresses.
	 * 
	 * @return recipient addresses as comma separated string, may be null.
	 * @since 1.2.14
	 */
	public String getCc() {
		return cc;
	}

	/**
	 * Set the bcc recipient addresses.
	 * 
	 * @param addresses
	 *            recipient addresses as comma separated string, may be null.
	 * @since 1.2.14
	 */
	public void setBcc(final String addresses) {
		this.bcc = addresses;
	}

	/**
	 * Get the bcc recipient addresses.
	 * 
	 * @return recipient addresses as comma separated string, may be null.
	 * @since 1.2.14
	 */
	public String getBcc() {
		return bcc;
	}

	/**
	 * The <b>SmtpPassword</b> option takes a string value which should be the
	 * password required to authenticate against the mail server.
	 * 
	 * @param password
	 *            password, may be null.
	 * @since 1.2.14
	 */
	public void setSMTPPassword(final String password) {
		this.smtpPassword = password;
	}

	/**
	 * The <b>SmtpUsername</b> option takes a string value which should be the
	 * username required to authenticate against the mail server.
	 * 
	 * @param username
	 *            user name, may be null.
	 * @since 1.2.14
	 */
	public void setSMTPUsername(final String username) {
		this.smtpUsername = username;
	}

	/**
	 * Setting the <b>SmtpDebug</b> option to true will cause the mail session
	 * to log its server interaction to stdout. This can be useful when debuging
	 * the appender but should not be used during production because username
	 * and password information is included in the output.
	 * 
	 * @param debug
	 *            debug flag.
	 * @since 1.2.14
	 */
	public void setSMTPDebug(final boolean debug) {
		this.smtpDebug = debug;
	}

	/**
	 * Get SMTP password.
	 * 
	 * @return SMTP password, may be null.
	 * @since 1.2.14
	 */
	public String getSMTPPassword() {
		return smtpPassword;
	}

	/**
	 * Get SMTP user name.
	 * 
	 * @return SMTP user name, may be null.
	 * @since 1.2.14
	 */
	public String getSMTPUsername() {
		return smtpUsername;
	}

	/**
	 * Get SMTP debug.
	 * 
	 * @return SMTP debug flag.
	 * @since 1.2.14
	 */
	public boolean getSMTPDebug() {
		return smtpDebug;
	}

	/**
	 * Sets triggering evaluator.
	 * 
	 * @param trigger
	 *            triggering event evaluator.
	 * @since 1.2.15
	 */
	public final void setEvaluator(final TriggeringEventEvaluator trigger) {
		if (trigger == null) {
			throw new NullPointerException("trigger");
		}
		this.evaluator = trigger;
	}

	/**
	 * Get triggering evaluator.
	 * 
	 * @return triggering event evaluator.
	 * @since 1.2.15
	 */
	public final TriggeringEventEvaluator getEvaluator() {
		return evaluator;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @since 1.2.15
	 */
	public boolean parseUnrecognizedElement(final Element element, final Properties props) throws Exception {
		if ("triggeringPolicy".equals(element.getNodeName())) {
			Object triggerPolicy = org.apache.log4j.xml.DOMConfigurator.parseElement(element, props,
					TriggeringEventEvaluator.class);
			if (triggerPolicy instanceof TriggeringEventEvaluator) {
				setEvaluator((TriggeringEventEvaluator) triggerPolicy);
			}
			return true;
		}

		return false;
	}

	/**
	 * Get transport protocol. Typically null or "smtps".
	 *
	 * @return transport protocol, may be null.
	 * @since 1.2.16
	 */
	public final String getSMTPProtocol() {
		return smtpProtocol;
	}

	/**
	 * Set transport protocol. Typically null or "smtps".
	 *
	 * @param val
	 *            transport protocol, may be null.
	 * @since 1.2.16
	 */
	public final void setSMTPProtocol(final String val) {
		smtpProtocol = val;
	}

	/**
	 * Get port.
	 *
	 * @return port, negative values indicate use of default ports for protocol.
	 * @since 1.2.16
	 */
	public final int getSMTPPort() {
		return smtpPort;
	}

	/**
	 * Set port.
	 *
	 * @param val
	 *            port, negative values indicate use of default ports for
	 *            protocol.
	 * @since 1.2.16
	 */
	public final void setSMTPPort(final int val) {
		smtpPort = val;
	}

	/**
	 * Get sendOnClose.
	 *
	 * @return if true all buffered logging events will be sent when the
	 *         appender is closed.
	 * @since 1.2.16
	 */
	public final boolean getSendOnClose() {
		return sendOnClose;
	}

	/**
	 * Set sendOnClose.
	 *
	 * @param val
	 *            if true all buffered logging events will be sent when appender
	 *            is closed.
	 * @since 1.2.16
	 */
	public final void setSendOnClose(final boolean val) {
		sendOnClose = val;
	}
}

class DefaultEvaluator implements TriggeringEventEvaluator {
	/**
	 * Is this <code>event</code> the e-mail triggering event?
	 * 
	 * <p>
	 * This method returns <code>true</code>, if the event level has ERROR level
	 * or higher. Otherwise it returns <code>false</code>.
	 */
	public boolean isTriggeringEvent(LoggingEvent event) {
		return event.getLevel().isGreaterOrEqual(Level.ERROR);
	}
}

然後非同步用xml方式配置

配置如下 這樣你就能愉快的玩耍了

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration
    xmlns:log4j='http://jakarta.apache.org/log4j/' >
    
    <!-- 控制檯日誌配置 -->
    <appender name="console" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-d{MM-ddHH:mm:ss}-[%p][%c{3}]%m%n" />
        </layout>
    </appender>
    
    <!-- info級別日誌控制 -->
    <appender name="info" class="org.apache.log4j.DailyRollingFileAppender">
        <!-- 檔案路徑 -->
        <param name="File" value="${catalina.home}/logs/${webapp.root}/infrastructure/info.log"/>
        <!-- 是否追加 -->
        <param name="Append" value="true"/>
        <!-- 最低日誌級別 -->
        <param name="Threshold" value="INFO"/>
        <!-- 回滾日誌字尾 -->
        <param name="datePattern" value="'.'yyyy-MM-dd"/>
        <!-- 是否啟用緩衝 當緩衝區資料達到一定大小再寫入檔案 預設8K -->
      <!--   <param name="BufferedIO" value="true"/>
        <param name="BufferSize" value="8192"/> -->
        <!-- 日誌輸出佈局 -->
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"  value="%-d{MM-dd HH:mm:ss}-[%p][%c{3}]%m%n" />
        </layout>
        <!--限制輸出級別-->
        <filter class="org.apache.log4j.varia.LevelRangeFilter">
            <!-- 最小級別 -->
            <param name="LevelMax" value="INFO"/>
            <!-- 最大級別 -->
            <param name="LevelMin" value="INFO"/>
        </filter>
    </appender>
    
    <!-- warn級別日誌控制 -->
    <appender name="warn" class="org.apache.log4j.DailyRollingFileAppender">
        <!-- 檔案路徑 -->
        <param name="File" value="${catalina.home}/logs/${webapp.root}/infrastructure/warn.log"/>
        <!-- 是否追加 -->
        <param name="Append" value="true"/>
        <!-- 最低日誌級別 -->
        <param name="Threshold" value="WARN"/>
        <!-- 回滾日誌字尾 -->
        <param name="datePattern" value="'.'yyyy-MM-dd"/>
        <!-- 是否啟用緩衝 當緩衝區資料達到一定大小再寫入檔案 預設8K -->
        <!-- <param name="BufferedIO" value="true"/>
        <param name="BufferSize" value="8192"/> -->
        <!-- 日誌輸出佈局 -->
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"  value="%-d{MM-dd HH:mm:ss}-[%p][%c]%m%n" />
        </layout>
        <!--限制輸出級別-->
        <filter class="org.apache.log4j.varia.LevelRangeFilter">
            <!-- 最小級別 -->
            <param name="LevelMax" value="WARN"/>
            <!-- 最大級別 -->
            <param name="LevelMin" value="WARN"/>
        </filter>
    </appender>
    
    <!-- error級別日誌控制 -->
    <appender name="error" class="org.apache.log4j.DailyRollingFileAppender">
        <!-- 檔案路徑 -->
        <param name="File" value="${catalina.home}/logs/${webapp.root}/infrastructure/error.log"/>
        <!-- 是否追加 -->
        <param name="Append" value="true"/>
        <!-- 最低日誌級別 -->
        <param name="Threshold" value="ERROR"/>
        <!-- 回滾日誌字尾 -->
        <param name="datePattern" value="'.'yyyy-MM-dd"/>
        <!-- 是否啟用緩衝 當緩衝區資料達到一定大小再寫入檔案 預設8K -->
        <!-- <param name="BufferedIO" value="true"/>
        <param name="BufferSize" value="8192"/> -->
        <!-- 日誌輸出佈局 -->
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"  value="%-d{MM-dd HH:mm:ss}-[%p][%c]%m%n" />
        </layout>
        <!--限制輸出級別-->
        <filter class="org.apache.log4j.varia.LevelRangeFilter">
            <!-- 最小級別 -->
            <param name="LevelMax" value="ERROR"/>
            <!-- 最大級別 -->
            <param name="LevelMin" value="ERROR"/>
        </filter>
    </appender>
    
    <!-- 傳送日誌檔案到郵件 -->
	<appender name="email" class="org.main.log4j.SMTPAppender">
		<!-- 最小輸出日誌級別 -->
		<param name="Threshold" value="ERROR"/>
		<!-- 緩衝Event個數預設512 當達到了多少個就覆蓋以前的Event 而非網路上所說的緩衝資料大小 不看原始碼坑出血 -->
		<param name="BufferedIO" value="true"/>
		 <param name="BufferSize" value="512"/>
		 <!-- 錯誤個數預設一個 即出現錯誤就傳送郵件 -->
		 <param name="ErrorSize" value="5"/>
		<!-- 傳送日誌的郵箱 -->
		<param name="From" value="***@163.com"/>
		<!-- 傳送日誌郵箱SMTP -->
		<param name="SMTPHost" value="smtp.163.com"/>
		<!-- 傳送日誌的郵箱使用者名稱  -->
		<param name="SMTPUsername" value="***@163.com"/>
		<!-- 傳送日誌的郵箱密碼 -->
		<param name="SMTPPassword" value="***"/>
		<!-- 日誌郵件主題 -->
		<param name="Subject" value="後臺系統框架異常提醒,請儘快處理"/>
		<!-- 日誌郵件接收者 -->
		<param name="To" value="***@qq.com"/>
		<!-- 抄送郵件接受者 -->
		 <param name="Bcc" value="***@qq.com"/>
		<!-- 日誌輸出佈局 -->
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"  value="%-d{MM-dd HH:mm:ss}-[%p][%c]%m%n" />
        </layout>
	</appender>

	<!-- 非同步傳送郵件設定 -->
	<appender name="asyncout" class="org.apache.log4j.AsyncAppender">
		<appender-ref ref="email" />
	</appender>  
 
 	<!-- 需要特殊處理的日誌級別 -->
  	<logger name="org.springframework" >
        <level value="WARN"/>
    </logger>
  	<logger name="org.system" >
        <level value="DEBUG"/>
    </logger>

	<!-- 根路徑設定 -->
    <root>
        <level value="INFO"/>
        <appender-ref ref="console" />
        <appender-ref ref="info" />
        <appender-ref ref="warn" />
        <appender-ref ref="error" />
        <appender-ref ref="asyncout" />
    </root>
    
</log4j:configuration>
順帶一提 結合slf4j效率更好

相關推薦

比較全面的log4j配置

話不多說先來個properties版本的 我以前一直使用的是properties來配置的 #定義根級別 log4j.rootLogger=info,warn,error,console,mail #定義專案輸出日誌級別 log4j.logger.org.system=de

Log4j配置發郵件功能

郵件功能 smtp eve gin java apach bsp ole message # 發送日誌到指定郵件log4j.appender.mail=org.apache.log4j.net.SMTPAppenderlog4j.appender.mail.Threshol

Java 異常處理和 Log4j 配置文件

images orm 信息 not bound img source jar 下標 一、 程序錯誤 警告:黃線:Warning 錯誤:資源類:系統級(線程)/ 環境級(繪圖) 異常:編譯級:Exception 運行級:Exception -> RuntimeExc

springmvc log4j 配置

context get img nal imp type 技術 XML %d web.xml 增加 <context-param> <param-name>log4jConfigLocation</param-name>

druid log4j配置

log4j druid1. druid配置中必須加上以下filter<property name="filters" value="log4j" />druid已封裝好的filterdruid.filters.default=com.alibaba.druid.filter.stat.StatFi

日誌slf4j+log4j配置問題

root -- output onf 類名.class 新的 是否 cati ring 簡介slf4j 相當於抽象類log4j 相當於實現,當然還有其他的實現,如logback,jdk自帶的logging等 具體配置maven 配置 pom.xml加入 <

log4j 配置使用

inf per eve main start test class oid pre 使用log4j來管理日誌信息,非常方便,下面簡單介紹一下整個使用流程:   1.創建簡單java項目   2.在類路徑下新建log4j.properties文件   3.配置log4j.

log4j配置輸出到多個日誌文件

基準 方式 ref err logfile otl sni targe file 通常我們項目裏,有一些重要的日誌想單獨的輸出到指定的文件,而不是全總輸出到系統的日誌文件中。那麽我們log4j為我們提供了這種功能,以下我們來一步一步看是怎麽做的。這裏以pro

log4j 配置詳解

一個 處理 介紹 bsp hive .net ftl ref http 參考如下兩個網址,講的很詳細,先看第一個再看第二個: log4j使用介紹:http://swiftlet.net/archives/683 java日誌處理組件log4j--log4j.xml配置詳

Log4j配置詳解

images 修飾符 ger light 通過命令 sock his boa 種類 來自: http://www.blogjava.net/zJun/archive/2006/06/28/55511.html Log4J的配置文件(Configuration File)就是

簡明log4j配置教程

開發 and led eap string ref str spa 級別 先準備好log4j需要對應的開發包: apache-log4j-extras-1.2.17.jar slf4j-api-1.6.1.jar slf4j-log4j12-1.6.1.jar 然後

Appuim項目實戰—log4j配置

otl gtest nco 新建 cor err args odin void 1. 在maven中配置log4j的依賴 <!-- 配置log4j依賴 --> <dependency>

spring集成Log4j以及log4j配置簡要說明

src line console fault 默認 fig encoding size 編碼 Spring集成: web.xml中配置log4j <context-param> <param-name>log4jConfigLocation&

比較全面的概述。

copy 布爾 指定 開始 number from 兼容 作文件 mutable 1 Python的函數參數傳遞 看兩個例子: a = 1def fun(a): a = 2fun(a)print a # 1 a = []def fun(a): a.append(1)fun(

Log4j配置文件詳解及實例

res 同時 生日 level iter printf %d ron inux    1 ) . 配置根 Logger ,其語法為:    log4j.rootLogger = [ level ] , appenderName, appenderName, …  其中, l

Log4j配置記錄

key 目的 apach window 調試 lin 功能 表格形式 all log4j的配置文件就是用來設置記錄器的級別、存放器和布局的,它可接key=value格式的設置或xml格式的設置信息。通過配置,可以創建出Log4J的運行環境。 1、配置文件 log4j配置文件

log4j配置參數詳解——按日誌文件大小、日期切分日誌文件

日誌文件 個數 位置 -h rac windows 基本配置 src index 項目中盡管對log4j有基本的配置,例如按天生成日誌文件以作區分,但如果系統日誌文件過大,則就需要考慮以更小的單位切分或者其他切分方式。下面就總結一下log4j常用的配置參數以及切分

Log4j配置詳情

apache file warn 0kb p s 多文件 date erro err 一、基本配置 // 指定日誌級別和輸出配置別名,別名可有多個   log4j.rootLogger = [ level ] , alis_1, alis_2, …      //輸

log4j配置問題

src .html .com roo get tom pac configure end 啟動項目發現了一個Warn 看看項目的目錄結構,沒有發現log4j.properties 參考了這位大神的帖子: https://www.cnblogs.com/asderx/p/6

log4j配置輸出到多個日誌文件(轉)

兩種模式 簡單 mylog 效果 evel ast mar 輸出 rop 參考資料:http://logging.apache.org/log4j/1.2/manual.html 通常我們項目裏,有一些重要的日誌想單獨的輸出到指定的文件,而不是全總輸出到系統的日誌文件中。那