zoukankan      html  css  js  c++  java
  • log4j 滚动日志 及 实现操作日志

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

    @Override
    public 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>
  • 相关阅读:
    ASP.NET MVC5+EF6+EasyUI 后台管理系统(28)-系统小结
    用谷歌浏览器来当手机模拟器
    解决PHP使用CVS导出Excel乱码问题
    Linux系统中关于Sqlite3中文乱码问题及解决办法
    解决excel日期变成数字的问题
    基于IE的多标签的浏览器-世界之窗2.4
    Thinkphp 获取所有子分类或父分类ID
    PhpExcel 删除默认的Sheet
    Mysql 创建表时错误:Tablespace for table `tablexx` exists. Please DISCARD the tablespace before IMPORT.
    关于ThinkPhp中getField方法存在的问题
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13317755.html
Copyright © 2011-2022 走看看