Log4j 1.2 使用自定义级别、自定义过滤器、动态路径

0x00 需求

目前,公司有个需求,希望能把我们项目中,用户的登录日志、操作日志记录到日志文件中。由于是Multi-Tenant,所以每个实例都有自己的用户。那么实现思路和步奏应该就是:1. 自定义Logger(自定义级别和过滤器)。 2. 自定义过滤器。3. 配置文件。

0x01 自定义Logger

package net.wechance.onlinelog.log;

import java.io.IOException;

import org.apache.log4j.Appender;
import org.apache.log4j.DailyRollingFileAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.net.SyslogAppender;


public class UserOnlineLogger {

    private static final Logger logger = Logger.getLogger(UserOnlineLogger.class);

    private static class SeriousLevel extends Level {

        private SeriousLevel(int level, String name, int sysLogLevel) {
            super(level, name, sysLogLevel);
        }

    }

    /**
     * 自定义级别
     * 此处的level是自定义的,可以参考下面自定义过滤器的级别
     */
    private static final Level USER_ONLINE = new SeriousLevel(20050000, "USER_ONLINE", SyslogAppender.LOG_LOCAL0);

    public static void log(Object pm_objLogInfo, String tenantId) {
        // 样式
        Layout layout = new PatternLayout("%m%n");
        // Appender
        Appender appender = null;
        // 根据传进来的tenantId动态生成path
        // 注意生成的文件是userOnline
        String path = tenantId + "/logs/userOnlineLog/userOnline";
        try {
            appender = new DailyRollingFileAppender(layout, path, "'.'yyyy-MM-dd'.log'");
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 指定Appender
        logger.addAppender(appender);
        logger.log(USER_ONLINE, pm_objLogInfo);
    }

}

仔细看看,和我们在配置文件中定义一个Appender很相似。

0x02 自定义过滤器

package net.wechance.onlinelog.log;

import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;

public class CustomerLogFilter extends Filter {

    boolean acceptOnMatch = false;
    private String levelMin;
    private String levelMax;

    public String getLevelMin() {
        return levelMin;
    }

    public void setLevelMin(String levelMin) {
        this.levelMin = levelMin;
    }

    public String getLevelMax() {
        return levelMax;
    }

    public void setLevelMax(String levelMax) {
        this.levelMax = levelMax;
    }

    public boolean isAcceptOnMatch() {
        return acceptOnMatch;
    }

    public void setAcceptOnMatch(boolean acceptOnMatch) {
        this.acceptOnMatch = acceptOnMatch;
    }

    @Override
    public int decide(LoggingEvent lgEvent) {
        int inputLevel = lgEvent.getLevel().toInt();

        if (inputLevel >= getLevel(levelMin) && inputLevel <= getLevel(levelMax)) {
            return 0;
        }

        return -1;
    }

    private int getLevel(String level) {
        level = level.toUpperCase();

        // 用户操作日志级别
        if (level.equals("USER_OPT")) {
            return LevelType.USER_OPT.getType();
        }
        // 用户在线日志级别
        if (level.equals("USER_ONLINE")) {
            return LevelType.USER_ONLINE.getType();
        }
        if (level.equals("OFF")) {
            return LevelType.OFF.getType();
        }
        if (level.equals("FATAL")) {
            return LevelType.FATAL.getType();
        }
        if (level.equals("ERROR")) {
            return LevelType.ERROR.getType();
        }
        if (level.equals("INFO")) {
            return LevelType.INFO.getType();
        }
        if (level.equals("WARN")) {
            return LevelType.WARN.getType();
        }
        if (level.equals("DEBUG")) {
            return LevelType.DEBUG.getType();
        }
        if (level.equals("ALL")) {
            return LevelType.ALL.getType();
        }
        return LevelType.OFF.getType();
    }

    private static enum LevelType {

        OFF(2147483647),

        FATAL(50000),

        ERROR(40000),

        WARN(30000),

        INFO(20000),

        DEBUG(10000),

        ALL(-2147483648),

        // 用户操作日志级别
        USER_OPT(20050001),

        // 用户在线日志级别
        USER_ONLINE(20050000);

        int type;

        public int getType() {
            return type;
        }

        private LevelType(int type) {
            this.type = type;
        }
    }

}

0x03 配置文件

<?xml version="1.0" encoding="UTF-8"?>        
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">        

<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/' >        

    <appender name="userOnline" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="File" value="userOnlineLog/userOnline"></param>
        <param name="Append" value="true" /> 
        <param name="DatePattern" value="'.'yyyy-MM-dd'.log'" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%m%n" />
        </layout>
        <filter class="net.wechance.onlinelog.log.CustomerLogFilter">
            <param name="LevelMin" value="USER_ONLINE" />
            <param name="LevelMax" value="USER_ONLINE" />
            <param name="AcceptOnMatch" value="true" />
        </filter>
    </appender>

    <appender name="ERR" class="org.apache.log4j.DailyRollingFileAppender">           
        <!-- 设置日志输出文件名 -->
        <param name="File" value="/logs/error" />
        <!-- 设置是否在重新启动服务时,在原有日志的基础添加新日志 -->
        <param name="Append" value="true" />
        <param name="DatePattern" value="'.'yyyy-MM-dd'.html'" />       
        <layout class="org.apache.log4j.HTMLLayout" />
        <filter class="org.apache.log4j.varia.LevelRangeFilter">     
          <param name="LevelMin" value="ERROR" />     
          <param name="LevelMax" value="ERROR" />     
        </filter>  
    </appender>

    <!-- 定义各个包中的类日志appender -->
    <category name="com.opensymphony.sitemesh">
        <priority value="ERROR"/>
        <appender-ref ref="ERR"/>
    </category>

    <category name="org.apache.struts2">
        <priority value="ERROR"/>
        <appender-ref ref="ERR"/>
    </category>

    <category name="org.apache">
        <priority value="ERROR"/>
        <appender-ref ref="ERR"/>
    </category>

    <category name="org.drools">
        <priority value="ERROR"/>
        <appender-ref ref="ERR"/>
    </category>

    <category name="catalia">
        <priority value="ERROR"/>
        <appender-ref ref="ERR"/>
    </category>

    <!-- 根logger的设置-->        
    <root>        
        <priority value ="debug"/>        
        <appender-ref ref="userOnline" />
        <appender-ref ref="ERR"/>           
    </root>
</log4j:configuration>

0x04 日志记录

/**
 * 记录用户在线日志
 * @param dto 用户对象
 * @param flag 上下线标识符
 */
private void log(String userName, String flag) {
    StringBuffer strBuff = new StringBuffer();
       // id
       strBuff.append(UUID.randomUUID()).append(",")
       // 用户
       .append(userName).append(",")
       // 时间
       .append(new Date()).append(",")
       // 在线标志
       .append(flag);

       UserOnlineLogger.log(strBuff.toString(), appctx.getCurrentTenantId());
}

0x05 完成

Okey, 那么到此使用log4j自定义级别、自定义过滤器、动态路径就已经完成啦。赶紧试试吧。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值