appender

Appender实现了Appender
类定义如下
package org.apache.log4j;
public interface Appender {
void addFilter(Filter newFilter);
void clearFilters();
void close();
void doAppend(LoggingEvent event);
boolean requiresLayout();
void setErrorHandler(ErrorHandler errorHandler);
void setLayout(Layout layout);
void setName(String name);
}

AppenderSkeleton类是一个抽象类,它实现了Appender,并提供了log4j的基础核心。

public synchronized void doAppend(LoggingEvent event) {
if(closed) {
LogLog.error("Attempted to append to closed appender ["
+name+"].");
return;
}
if(!isAsSevereAsThreshold(event.level)) {
return;
}
Filter f = this.headFilter;
FILTER_LOOP:
while(f != null) {
switch(f.decide(event)) {
case Filter.DENY: return;
case Filter.ACCEPT: break FILTER_LOOP;
case Filter.NEUTRAL: f = f.next;
}

}
this.append(event);
}

appender的uml图如下
[img]http://dl.iteye.com/upload/attachment/512980/dd5cc9fa-c05b-3120-8299-7f4e14c87179.png[/img]

WriterAppender,将events追加到java.io.Writer。这个类提供了基础的写入服务。一般不会直接使用这个类。

具有属性
Encoding,默认使用当前环境中的encoding。
ImmediateFlush boolean值,默认true。每次写入LoggingEvent,如果设置为true,就会写入完毕后就调用flush()方法,刷新。false则由log4j决定什么时候刷新。false可能会造成信息丢失。
Threshold Level类型。设置一个等级。

例子

/**
*

* @author liyixing liyixing1@yahoo.com.cn
* @version 1.0
* @since 2011-7-10 下午03:38:18
*/

package com.cgodo.log4j.test;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;
import org.apache.log4j.WriterAppender;

/**
*
* @author liyixing liyixing1@yahoo.com.cn
* @version 1.0
* @since 2011-7-10 下午03:38:18
*/

public class XmlTest {
final static Logger logger = Logger.getLogger(XmlTest.class);

/**
* 描述:
*
* @param args
* @author liyixing 2011-7-10
* @throws FileNotFoundException
*/

public static void main(String[] args) throws FileNotFoundException {
WriterAppender writerAppender = new WriterAppender();
writerAppender.setLayout(new SimpleLayout());
OutputStream os = new FileOutputStream("exitWoes1.log");
writerAppender.setWriter(new OutputStreamWriter(os));
writerAppender.setImmediateFlush(false);
writerAppender.activateOptions();
Logger logger = Logger.getLogger(XmlTest.class);
logger.setLevel(Level.DEBUG);
logger.addAppender(writerAppender);
logger.debug("Hello world.");
}
}
如上,不会刷新到文件。我们可以调用LogManager.getLoggerRepository().shutdown();来造成刷新。但这依然是不安全的,因为进程可能会被强制结束。


如果是WriterAppender 类关系图。

[img]http://dl.iteye.com/upload/attachment/512986/ac446460-9a37-3e9d-bc7a-8c53fe2cd8e9.png[/img]

ConsoleAppender是输出到控制台得类。
属性
Encoding
ImmediateFlush
Target String 值可以是"System.out" or "System.err"指定使用这两者之间哪个输出到控制台。默认System.out
System.out.
Threshold

FileAppender追加记录到文件
它使用FileOutputStream进行输出。
属性
Append boolean值指定追加还是覆盖。默认true
Encoding
BufferedIO Boolean,默认是false。如果设置为true。通过bufferedwriter对象进行一层包裹。设置为true,immediateflush自动设置为false。另外这个名字有点误导。会以为是否对BufferedIO进行支持。但是OutputStreamWriter本身已经支持BufferedIO。
BufferSize缓冲值大小 int,默认8192。
File String 写入到哪里。如果文件不存在,会被创建。在windows常常会忘记对\的处理,比如路径c:\temp\test.log这里的\t会被解释成制表符,应该进行\u0009转义,或者可以写成c:/temp/test.log或者c:\\temp\\test.log
ImmediateFlush
Threshold

对于文件输出,缓冲值设置很重要。

RollingFileAppender
继承自FileAppender 。可以限制文件大小。当文件达到上限,会进行文件重命名为xxxx.log.01,如果存在,命名为xxxx02.log,以此类推。直到MaxBackupIndex为止。如果达到MaxBackupIndex。如果到达了,就会把最后一个文件删除,其他文件全部重名名。如
删除xx.log.05
xx.log.04命名为xx.log.05
以此类推。

属性
Append Boolean See FileAppender options.
Encoding String See WriterAppender options.
BufferedIO Boolean See FileAppender options.
BufferSize int See FileAppender options.
File String See FileAppender options.
ImmediateFlush Boolean See WriterAppender options.
MaxBackupIndex int
MaxFileSize String默认10MB
Threshold Level

DailyRollingFileAppender
FileAppender 的子类。以时间作为日志文件名。如指定格式为yyyy-MM-dd,今天是2011-07-10,那么指定为/foo/bar.log的日志文件,最后输出的时候/foo/bar.log.2011-07-10
支持的格式
yyyy-MM年月
yyyy-ww年周
yyyy-MM-dd年月日
yyyy-MM-dd-a年月日(am或者pm)
yyyy-MM-dd-HH年月日时
yyyy-MM-dd-HH-mm年月日时分

属性
Append Boolean See FileAppender options.
DatePattern String 时间格式
Encoding String
BufferedIO Boolean
BufferSize int
File String
ImmediateFlush Boolean
Threshold Level

这个适配器并不是立刻进行检查时间的。为了减少性能消耗,而是由记录时间决定。比如我们设置了为yyyy-MM-dd,那么它会在23点末期之后,有一个事件进入了,才完成命名策略,因此可能会存在事件延迟

SocketAppender
用于远程化得日志记录。如果远程端关闭了连接,那么它的记录将会无效。它无法使用布局。
属性
LocationInfo boolean如果是true,会包含location information一起发送到远程端,默认是false;
Port int
ReconnectionDelay int如果连接断开,等待多少秒后再次连接。默认是30000.
Threshold Level

log4j提供了一个简单的时候org.apache.log4j.net.SimpleSocketServer,它作为远程放。它等待SocketAppender 发送数据过来。SimpleSocketServer 需要两个参数,configFile和port。

java org.apache.log4j.net.SimpleSocketServer 6000 chapter4/server1.xml
其中server1.xml的内容和普通的log4j配置一样的。


JMSAppender
1.2.6开始支持的,基于JMS功能的记录设备。
它的append方法
public void append(LoggingEvent event) {
//checkEntryConditions方法,用于检查JMSAppender是否运行正常。它会从TopicConnection中获取一个TopicSession。如果检查失败,它不会继续下去。如果满足,会创建一个ObjectMessage对象,然后把事件加入到Object中。,然后把msg加入到队列中,等待发送出去。
if(!checkEntryConditions()) {
return;
}
try {
ObjectMessage msg = topicSession.createObjectMessage();
if(locationInfo) {
event.getLocationInformation();
}
msg.setObject(event);
topicPublisher.publish(msg);
} catch(Exception e) {
errorHandler.error("Could not publish message in JMSAppender ["
+name+"].", e, ErrorCode.GENERIC_FAILURE);
}
}
其他信息,查看log4j-manual

SMTPAppender
将loggingevents组成到一个固定大小之后,发送一封邮件。默认情况下,只有在error或者更高级别的错误才会发送邮件。
例子
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration debug="true"
xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="EMAIL" class="org.apache.log4j.net.SMTPAppender">
<param name="SMTPHost" value="ADDRESS-OF-YOUR-SMTP-HOST"/>
<param name="To" value="DESTINATION1@EMAIL, DESTINATION2@EMAIL"/>
<param name="From" value="SENDER@EMAIL"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p %c - %m%n"/>
</layout>
</appender>
<root>
<level value ="debug"/>
<appender-ref ref="EMAIL" />
</root>
</log4j:configuration>

对于gmail,无法使用这个appender完成。在网上找到了一个gmail的实现

/*
Copyright (c) 2010 tgerm.com
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.tgerm.log4j.appender;

import java.util.Date;
import java.util.Properties;

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.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;

import org.apache.log4j.Layout;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.net.SMTPAppender;
import org.apache.log4j.spi.LoggingEvent;

import com.sun.mail.smtp.SMTPTransport;

/**
* Extension of Log4j {@link SMTPAppender} for Gmail support
*
* @author abhinav@tgerm.com
* @see <a href="http://code.google.com/p/log4j-gmail-smtp-appender/">Google Code Project</a> <br/>
* <a href="http://www.tgerm.com">My Blog</a>
*/
public class GmailSMTPAppender extends SMTPAppender {
/**
* Cached session for later use i.e. while sending emails
*/
protected Session session;

public GmailSMTPAppender() {
super();
}

/**
* Create mail session.
*
* @return mail session, may not be null.
*/
protected Session createSession() {
Properties props = new Properties();
props.put("mail.smtps.host", getSMTPHost());
props.put("mail.smtps.auth", "true");

Authenticator auth = null;
if (getSMTPPassword() != null && getSMTPUsername() != null) {
auth = new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(getSMTPUsername(),
getSMTPPassword());
}
};
}
session = Session.getInstance(props, auth);
if (getSMTPProtocol() != null) {
session.setProtocolForAddress("rfc822", getSMTPProtocol());
}
if (getSMTPDebug()) {
session.setDebug(getSMTPDebug());
}
return session;
}

/**
* Send the contents of the cyclic buffer as an e-mail message.
*/
protected void sendBuffer() {
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++) {
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());
send(msg);
} catch (Exception e) {
LogLog.error("Error occured while sending e-mail notification.", e);
}
}

/**
* Pulled email send stuff i.e. Transport.send()/Transport.sendMessage(). So
* that on required this logic can be enhanced.
*
* @param msg
* Email Message
* @throws MessagingException
*/
protected void send(Message msg) throws MessagingException {
SMTPTransport t = (SMTPTransport) session.getTransport("smtps");
try {
t.connect(getSMTPHost(), getSMTPUsername(), getSMTPPassword());
t.sendMessage(msg, msg.getAllRecipients());
} finally {
System.out.println("Response: " + t.getLastServerResponse());
t.close();
}
}
}

配置
#@author abhinav@tgerm.com
#Google Code Project http://code.google.com/p/log4j-gmail-smtp-appender/
#My Blog : http://www.tgerm.com

log4j.rootLogger=ERROR, Console,R
log4j.logger.com=DEBUG, Console, R, EMAIL
log4j.additivity.com.tgerm=false


log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=appender.log
log4j.appender.R.Append=false
log4j.appender.R.MaxFileSize=100KB
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n

log4j.appender.EMAIL=com.tgerm.log4j.appender.GmailSMTPAppender
log4j.appender.EMAIL.SMTPHost=smtp.gmail.com
log4j.appender.EMAIL.SMTPDebug=true
log4j.appender.EMAIL.From=xxxxxxxxxxx@gmail.com
log4j.appender.EMAIL.To=xxxxxxxxxxx@yahoo.com.cn
log4j.appender.EMAIL.SMTPUsername=xxxxxxxxxxx@gmail.com
log4j.appender.EMAIL.SMTPPassword=xxxxxxxxxxx
log4j.appender.EMAIL.Subject=log4j
log4j.appender.EMAIL.cc=cc@gmail.com
log4j.appender.EMAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.EMAIL.layout.ConversionPattern=%p %t %c - %m%n
log4j.appender.EMAIL.BufferSize=1

更多的appender可以看log4j-manual
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值