【原】log4j 自定义Appender

如下是一个正确的log4j 配置

log4j.rootLogger = ERROR,dailyRolling

log4j.appender.dailyRolling=org.apache.log4j.DailyRollingFileAppender
log4j.appender.dailyRolling.Encoding=UTF-8
log4j.appender.dailyRolling.File=d:/logs/weds-pay
log4j.appender.dailyRolling.layout=org.apache.log4j.PatternLayout
log4j.appender.dailyRolling.layout.ConversionPattern=%d %p [%c.%M(%L)] - %m%n
log4j.appender.file.DatePattern=_yyyy-MM-dd'.log'
log4j.appender.file.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

#log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
#log4j.appender.CONSOLE.Encoding=UTF-8
#log4j.appender.CONSOLE.Target=System.out
#log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
#log4j.appender.CONSOLE.layout.ConversionPattern=%d %p [%c] - %m%n

log4j.logger.elkLog=INFO,elkLog
log4j.additivity.elkLog=false  #false为不传递,也就说只输出到redis,不输出到本地磁盘了, true的话是传递,默认为true,写redis还写本地磁盘
log4j.appender.elkLog=com.weds.framework.utils.elk.ELKApiAppender
log4j.appender.elkLog.writeLogKey=weds-pay-api
log4j.appender.elkLog.layout=org.apache.log4j.PatternLayout
log4j.appender.elkLog.layout.ConversionPattern=%d %p [%c] - %m%n  

#log4j.logger.org.springframework=WARN
#log4j.logger.org.apache.cxf=WARN
#log4j.logger.org.apache.cxf.jaxrs=WARN
#log4j.logger.org.apache.cxf.phase=WARN
#log4j.logger.org.apache.activemq=WARN
#log4j.logger.org.apache.zookeeper=WARN
#log4j.logger.com.baidu.disconf=WARN
#log4j.logger.org.apache.commons.digester=WARN
#log4j.logger.org.apache.http=WARN
#log4j.logger.org.mongodb.driver.cluster=WARN
#log4j.logger.com.alibaba.dubbo=WARN
#log4j.logger.org.elasticsearch=WARN

ELKApiAppender

package com.weds.framework.utils.elk;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import com.weds.framework.core.utils.JsonUtil;
import com.weds.framework.core.utils.redis.RedisService;

/**
 * 
 * <p>Title: ApiAppender</p>
 * <p>Description: 重写Appender 调用log4就时,将记录存入redis</p>
 * <p>Company: Leyou(China) Chain Store Co.,Ltd</p>
 * <p>版权所有: Copyright?1999-2016 leyou.com. All Rights Reserved</p> 
 * @author Illidan  
 * @date 2016年5月19日 上午10:25:59 
 * @version V1.0
 */
public class ELKApiAppender extends AppenderSkeleton{
    
    /**
     * Jredis连接redis的client
     */
    private RedisTemplate<String, Object> redisTemplate;
    /**
     * 记录接口方法调用次数日志需要先写入redis中,redis的key不能为空,这个key需要同步在logstash配置文件中配置
     */
    private String writeLogKey;
    
    @Override
    public void close() {
        // TODO Auto-generated method stub
        
    }
    @Override
    public boolean requiresLayout() {
        // TODO Auto-generated method stub
        return false;
    }
    /**
     * 重写日志输出输出
     */
    @Override
    protected void append(LoggingEvent event) {
        Map<String,Object> map =(Map<String,Object>)event.getMessage();
        map.put("levl", event.getLevel().toString());
        writeLogAsync(writeLogKey,map);
    }
    /**
     * 异步记录日志
     * @param key 记录到redis的中key,key需要同步在logstash配置文件中配置
     * @param value 日志的值,Map格式
     */
    public void writeLogAsync(String key,Map<String,Object> map){
        CompletableFuture.runAsync(() -> {
            writeLog(key,map);
        });
    }
    /**
     * 
     * @Title: writeLogAsync 
     * @Description: 异步存储日志
     * @param 
     * @return void    返回类型  
     * @throws 
     * @author Illidan  
     * @date 2016年5月18日 下午1:51:56
     */
    public void writeLogAsync(String key,String value){
        CompletableFuture.runAsync(() -> {
            writeLog(key,value);
        });
    }
    /**
     *记录日志到redis的List集合中,值为Map集合方式
     * @param key 记录redis的key,key需要同步在logstash配置文件中配置
     * @param map value为Map值
     */
    public void writeLog(String key,Map<String,Object> map){
        String value = JsonUtil.obj2string(map);
        writeLog(key, value);
    }
    /**
     * 记录日志到redis的List集合中
     * @param key 记录redis的key,key需要同步在logstash配置文件中配置
     * @param value  记录的值
     */
    public void writeLog(String key, String value) {
        if(key != null){
            redisTemplate =(RedisTemplate<String, Object>)SpringContextUtil.getBean("elkRedisTemplate",RedisTemplate.class);
            redisTemplate.opsForList().rightPush(key, value);
        }
    }
    public RedisTemplate getRedisTemplate() {
        return redisTemplate;
    }
    public void setRedisTemplate(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
    public String getWriteLogKey() {
        return writeLogKey;
    }
    public void setWriteLogKey(String writeLogKey) {
        this.writeLogKey = writeLogKey;
    }
}

用法:

protected static final Logger log = Logger.getLogger("elkLog"); 
原文地址:https://www.cnblogs.com/caoheyang911016/p/6283026.html