Java系统日志管理

在一个系统中日志管理是一个很重要的部分,因为当系统发布到线网后出了问题只能看系统日志了,这个时候系统日志起到了一个错误排查功能,同时也可以通过系统日志统计用户吞吐量等等,总之系统日志是系统管理一个重点。
本系统架构为SpringMVC,myBatis,Shrio等等。

1.SpringMVC异常处理
SpringMVC负责接收用户请求并进行处理然后将结果返回给用户,那么为了不让异常抛给用户,我们一般在Controller类下每个方法都加上一个try{}catch(Exception e){},实例代码如下:
/**
	 * pengweikang 20170220 用户登陆
	 * 
	 * @param cgbUser
	 *            用户信息
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public @ResponseBody String userLogin(HttpServletRequest request) {
		try {
		     .....	 //Service方法调用
		} catch (Exception e) {
		     .....      //异常处理
		} 
		return null;
	}

该方法的缺点是代码冗余,不利于维护,一看就不想是一个专业的软件工程师应该写的,优化办法如下:

其实SpringMVC给我们提供了一个控制器增强标签,名称为@ControllerAdvice,通过这个标签就可以统一实现异常处理,代码如下:
创建统一的异常处理类CGBExceptionHandler.java

import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import ch.qos.logback.classic.Level;
import net.sf.json.JSONObject;

/**
*@author		create by pengweikang
*@date		2018年6月27日--下午12:49:23
*@problem
*@answer
*@action
*/
@ControllerAdvice
public class CGBExceptionHandler {
	ch.qos.logback.classic.Logger loggerback = (ch.qos.logback.classic.Logger)LoggerFactory.getLogger("error");
	{
		loggerback.setLevel(Level.ERROR);
	}
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Object handleException(Exception e,HttpServletRequest rquest) {
    	loggerback.error("错误日志记录");
    	Map dataMap  = rquest.getParameterMap();
        Set keySet = 	dataMap.keySet();
        for(String key : keySet) {
            String [] datas = (String[])dataMap.get(key);
            String value = new String();
            for(String data : datas) {
    	        value +=data+",";
            }
    	    loggerback.error("Param:"+key+" = "+ value.substring(0, value.length() - 1));//将请求参数保存在日志中
        }
    	loggerback.error(ExceptionUtils.getFullStackTrace(e));  // 记录错误信息
        String msg = e.getMessage();
        if (msg == null || msg.equals("")) {
            msg = "服务器出错";
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("message", msg);
        jsonObject.put("state", 0);
        return jsonObject.toString();
    }
}

这个时候你的Controller就不用在添加try-catch异常捕获了, 一但方法出了异常就会跳转到CGBExceptionHandler.java这个类的handleException方法。

2.logback日志管理

在这个方法中我们将方法调用的的错误消息都记录在日志中,并且将方法调用的参数也报错在错误日志中,logback配置内容如下:




     
    
    
    
    
    
     
     	
     	
            ERROR
            ACCEPT
            DENY
        
     
        
            [%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
            
        
    
    
    
        
            [%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
            
        
        
            ERROR
            ACCEPT
            DENY
        
        
            ${ROOT}%d/error.%i.log
            ${MAXHISTORY}
            
                ${FILESIZE}
            
        
    
    
    
    
        
            [%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
            
        
        
            WARN
            ACCEPT
            DENY
        
        
            ${ROOT}%d/warn.%i.log
            ${MAXHISTORY}
            
                ${FILESIZE}
            
        
    
    
    
    
        
            [%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
            
        
        
            INFO
            ACCEPT
            DENY
        
        
            ${ROOT}%d/info.%i.log
            ${MAXHISTORY}
            
                ${FILESIZE}
            
        
    
    
    
        
            [%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
            
        
        
            DEBUG
            ACCEPT
            DENY
        
        
            ${ROOT}%d/debug.%i.log
            ${MAXHISTORY}
            
                ${FILESIZE}
            
        
    
    
    
        
            [%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
            
        
        
            TRACE
            ACCEPT
            DENY
        
        
            ${ROOT}%d/trace.%i.log
            ${MAXHISTORY}
            
                ${FILESIZE}
            
        
    
    
    
    
    
    
    
    
    
         
          
        
        
         
        
    

该配置文件内容为将不同类型的日志按不同文件进行报错,并且每天记录不同的日志,文件夹按日期进行命名,儿控制台只打印错误日志。

3.测试

测试代码如下:

@Controller
@RequestMapping(value="/test")
public class TestController {
@RequestMapping(value="/exception")
	public @ResponseBody String throwexcep(int data) throws Exception {
		int a = data/0;// 一定会抛出 java.lang.ArithmeticException: / by zero		
		return null;
	}
}
请求 http://localhost:8080/logSystem/test/exception?data=100

首先看tomcat的log文件夹如下图所示:

Java系统日志管理_第1张图片


error.0.log日志记录如下:

[ERROR] 2018-07-06 15:05:39 [http-bio-8080-exec-3] error - 错误日志记录
[ERROR] 2018-07-06 15:09:30 [http-bio-8080-exec-2] error - 错误日志记录
[ERROR] 2018-07-06 15:09:30 [http-bio-8080-exec-2] error - Param:data = 100
[ERROR] 2018-07-06 15:09:30 [http-bio-8080-exec-2] error - ParameterMap:org.apache.catalina.util.ParameterMap@c7832d1
[ERROR] 2018-07-06 15:09:30 [http-bio-8080-exec-2] error - java.lang.ArithmeticException: / by zero
	at com.goldenbridge.recognizesystem.controller.ActivitiController.throwexcep(ActivitiController.java:137)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:222)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:969)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:860)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:845)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:123)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
	at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
	at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
	at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
	at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
	at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
	at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at com.goldenbridge.recognizesystem.utils.SimpleCORSFilter.doFilter(SimpleCORSFilter.java:34)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1115)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)


到此系统日志管理配置完成!


你可能感兴趣的:(Java,log)