log4j 滚动日志 及 实现操作日志

来源:互联网 发布:centos开机自启动 编辑:程序博客网 时间:2024/05/22 06:31

1、建立log4j.xml 文件

<?xml version="1.0" encoding="UTF-8" ?>  <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">  <log4j:configuration>   <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">        <layout class="org.apache.log4j.PatternLayout">         <param name="ConversionPattern"          value="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c - %m%n" />        </layout>        <!--限制输出级别-->        <filter class="org.apache.log4j.varia.LevelRangeFilter">         <param name="LevelMax" value="ERROR"/>         <param name="LevelMin" value="TRACE"/>        </filter>   </appender>   <appender name="FILE" class="org.apache.log4j.FileAppender">        <param name="File" value="/data/log/error.log"/>        <layout class="org.apache.log4j.PatternLayout">         <param name="ConversionPattern"          value="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c - %m%n" />        </layout>        <filter class="org.apache.log4j.varia.LevelRangeFilter">         <param name="LevelMax" value="ERROR"/>         <param name="LevelMin" value="TRACE"/>        </filter>  </appender>     <apender name="ROLLING_FILE" class="org.apache.log4j.RollingFileAppender">      <param name="File" value="/data/log/rolling.log"/>       <param name="Append" value="true"/>       <param name="MaxFileSize" value="1024KB"/>       <layout class="org.apache.log4j.PatternLayout">           <param name="ConversionPattern"              value="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c - %m%n" />        </layout>  </apender> <appender name="DATABASE" class="com.test.sys.log.MyJDBCAppender">        <param name="Threshold" value="INFO" />        <filter class="com.test.sys.log.CustomWarnLevelFilter">             </filter>       <layout class="org.apache.log4j.PatternLayout">             <param name="ConversionPattern"              value="INSERT INTO account_operate_log (aol_id,operate_type,operate_content,operate_result,user_id,user_name,operate_date,operate_ip,organization) VALUES(UUID(),'%X{operate}','%X{content}',1,%X{userid},'%X{username}',%d{yyyyMMddHHmmss},'%X{ip}','%X{organization}')" />        </layout>   </appender>   <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">    <param name="BufferSize" value="256" />    <appender-ref ref="ROLLING_FILE" />   <appender-ref ref="FILE" />  </appender>   <root>    <priority value="debug" />    <appender-ref ref="CONSOLE" />    <appender-ref ref="FILE" />   <appender-ref ref="ROLLING_FILE" />   <appender-ref ref="DATABASE" />  <appender-ref ref="ASYNC" />       </root>  </log4j:configuration>  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72

2、com.test.sys.log.MyJDBCAppender 依赖类的实现

import java.sql.Connection;import java.sql.SQLException;import org.apache.log4j.jdbc.JDBCAppender;import org.apache.log4j.spi.ErrorCode;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.alibaba.druid.pool.DruidDataSource;/*** @Description MyJDBCAppender.java* 用于Log4j的数据库Session管理[连接池用Druid]* @version 1.0*/public class MyJDBCAppender extends JDBCAppender{        /* Druid数据源 */        private static DruidDataSource dataSource;        public MyJDBCAppender() {            super();        }        static{            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");             dataSource= (DruidDataSource) context.getBean("dataSource");// 这里博主是用的alibaba 的Druid 的连接池  ,原先使用的c3p0连接池,使用此种方式获取不到连接池,而且项目中,c3p0总是关闭连接错误,所以果断改为了Druid ,不失所望,Druid 很好用,效率很高,Druid连接池的配置会贴在此文最后        }        @Override        protected void closeConnection(Connection con) {            try {                /* 如果数据库连接对象不为空和没有被关闭的话,关闭数据库连接 */                if ( con != null && !con.isClosed())                con.close();            } catch (SQLException e) {                errorHandler.error("Error closing MyJDBCAppender.closeConnection() 's connection",e,ErrorCode.GENERIC_FAILURE);            }        }        @Override         protected Connection getConnection() throws SQLException {            return dataSource.getConnection();        }        /* 取消初始化 */        public void uninitialize() {                try {                    if (dataSource != null)                        dataSource.close();                } finally {                    super.close();                }        }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83

3、com.test.sys.log.CustomWarnLevelFilter 依赖类的实现

import java.util.regex.Matcher;import java.util.regex.Pattern;import org.apache.log4j.spi.LoggingEvent;import org.slf4j.MDC;public class CustomWarnLevelFilter extends org.apache.log4j.spi.Filter{    @Override    public int decide(LoggingEvent event) {        //大于等于WARN的日志不允许输出//      if(event.getLevel().toInt() >= Level. WARN.toInt()) {//          return DENY;//      } else {//          return ACCEPT;//      }        event.getMDCCopy();        if(event.getMessage()!=null && isContainChinese(event.getMessage().toString()) && null !=event.getMDC("userid")){            if( isContainGt(event.getMessage().toString())){                String[] split = event.getMessage().toString().split(">");                MDC.put("operate", split[0]+"");                MDC.put("content", event.getMessage().toString()+"");                return ACCEPT;            }else if( event.getMessage().toString().indexOf("登录")>-1 || event.getMessage().toString().indexOf("退出")>-1                     || event.getMessage().toString().indexOf("列表")>-1 || event.getMessage().toString().indexOf("主页")>-1 || event.getMessage().toString().indexOf("导入")>-1){                MDC.put("operate", event.getMessage().toString());                MDC.put("content", event.getMessage().toString());                return ACCEPT;            }else{                return DENY;            }        }else{            return DENY;        }    }     public static boolean isContainChinese(String str) {            Pattern p = Pattern.compile("[\u4e00-\u9fa5]");            Matcher m = p.matcher(str);            if (m.find()) {                return true;            }            return false;        }     public static boolean isContainGt(String str) {         Pattern p = Pattern.compile("(.*)(?:>)");            Matcher m = p.matcher(str);            if (m.find()) {                return true;            }            return false;        }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

4、在登陆的拦截器 中要将 userId 和 企业id 放入MDC 中去,然后在log4j.xml 中 用 %X{userid} 方式可取出其值

import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.slf4j.MDC; 
import org.springframework.web.method.HandlerMethod; 
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class LoginInterceptor extends HandlerInterceptorAdapter{ 
private static final Logger LOG = LoggerFactory.getLogger(LoginInterceptor.class);

@Overridepublic boolean preHandle(HttpServletRequest request,        HttpServletResponse response, Object handler) throws Exception {        HandlerMethod handlerMethod = (HandlerMethod) handler;        if ("GET".equalsIgnoreCase(request.getMethod())) {          }         String requestUri = request.getRequestURI();          LOG.info("requestUri:"+requestUri);            String requestURI = request.getRequestURI();        if(null != request.getSession(false)){             UserInfo user = (UserInfo) request.getSession(false).getAttribute("UserInfo");             if(null == user){                LOG.info("未登录,请先登录");                request.getSession(false).setAttribute("msg", "用户未登录,请先登录");             request.getRequestDispatcher("/pages/login.jsp").forward(request, response);                   return false;               }else{                 MDC.put("userid", user.getUserId()+"");                 MDC.put("username", user.getUserName()+"");                 MDC.put("ip", request.getRemoteAddr()+"");                Enterprise enter = (Enterprise) request.getSession(false).getAttribute("Enterprise");                if(null !=user.getOrganizationId()){                    MDC.put("organization", enter.getEnterprise()+"");                }else{                    MDC.put("organization","");                }             }        }else{            LOG.info("未登录,请先登录");     request.getRequestDispatcher("/pages/login.jsp").forward(request, response);                  return false;          }        return true;}

}

5、applicationContext.xml 中的Druid 连接池的配置

<!-- 配置数据源 -->    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">           <!-- 基本属性 url、user、password -->          <property name="driverClassName" value="com.mysql.jdbc.Driver" />          <property name="url" value="jdbc:mysql://********:3306/logistic?useUnicode=true&amp;characterEncoding=utf-8" />          <property name="username" value="****" />          <property name="password" value="****" />          <!-- 配置初始化大小、最小、最大 -->          <property name="initialSize" value="5" />          <property name="minIdle" value="10" />           <property name="maxActive" value="20" />          <!-- 配置获取连接等待超时的时间 -->          <property name="maxWait" value="60000" />          <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->          <property name="timeBetweenEvictionRunsMillis" value="60000" />          <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->          <property name="minEvictableIdleTimeMillis" value="300000" />          <property name="validationQuery" value="SELECT 'x'" />          <property name="testWhileIdle" value="true" />          <property name="testOnBorrow" value="false" />          <property name="testOnReturn" value="false" />          <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->          <property name="poolPreparedStatements" value="true" />          <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />          <!-- 配置监控统计拦截的filters -->          <property name="filters" value="stat" />    </bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

6、在web.xml 中加入Druid 的监控,启动应用,访问http://localhost/应用名/monitor/ 就可以看到Druid 的监控页面了

     <servlet>        <servlet-name>DruidStatView</servlet-name>        <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>     </servlet>     <servlet-mapping>        <servlet-name>DruidStatView</servlet-name>        <url-pattern>/monitor/*</url-pattern>     </servlet-mapping>
0 0