相信各位同道在写代码的时候,肯定会写一些日志打印,因为这对往后的运维而言,至关重要的。
那么我们请求一个restfull接口的时候,哪些信息是应该被日志记录的呢?
以下做了一个基本的简单例子,这里只是示例说明基本常规实现记录的信息,根据项目的真实情况选用:
1 . http请求拦截器(filter) : 从httpservletrequest获取基本的请求信息
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
|
import name.ealen.util.httputil;
import org.slf4j.logger;
import org.slf4j.loggerfactory;
import org.springframework.beans.factory.annotation.qualifier;
import org.springframework.boot.web.servlet.filterregistrationbean;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.core.annotation.order;
import javax.servlet.*;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import java.io.ioexception;
/**
* created by ealenxie on 2018/9/7 15:56.
* http请求拦截器,日志打印请求基本相关信息
*/
@configuration
public class filterconfiguration {
private static final logger log = loggerfactory.getlogger(filterconfig. class );
@bean
@order (integer.min_value)
@qualifier ( "filterregistration" )
public filterregistrationbean filterregistration() {
filterregistrationbean<filter> registration = new filterregistrationbean<>();
registration.setfilter(controllerfilter());
registration.addurlpatterns( "/*" );
return registration;
}
private filter controllerfilter() {
return new filter() {
@override
public void init(filterconfig filterconfig) {
log.info( "controllerfilter init success" );
}
@override
public void dofilter(servletrequest servletrequest, servletresponse servletresponse, filterchain chain) throws ioexception, servletexception {
httpservletrequest request = (httpservletrequest) servletrequest;
httpservletresponse response = (httpservletresponse) servletresponse;
string requestid = request.getheader( "request-id" );
if (requestid == null ) requestid = request.getrequestedsessionid();
system.out.println();
log.info( "http request request-id : " + requestid);
log.info( "http request information : {\"uri\":\"" + request.getrequesturl() +
"\",\"requestmethod\":\"" + request.getmethod() +
"\",\"clientip\":\"" + httputil.getipaddress(request) +
"\",\"content-type\":\"" + request.getcontenttype() +
"\"}" );
chain.dofilter(request, response);
}
@override
public void destroy() {
log.info( "controllerfilter destroy" );
}
};
}
}
|
2 . controller的拦截aop : 获取 请求的对象,请求参数,返回数据,请求返回状态,内部方法耗时。
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
|
import com.alibaba.fastjson.json;
import org.aspectj.lang.proceedingjoinpoint;
import org.aspectj.lang.annotation.around;
import org.aspectj.lang.annotation.aspect;
import org.slf4j.logger;
import org.slf4j.loggerfactory;
import org.springframework.core.env.environment;
import org.springframework.http.httpstatus;
import org.springframework.http.responseentity;
import org.springframework.stereotype.component;
import javax.annotation.resource;
/**
* created by ealenxie on 2018/9/7 14:19.
* aop打印日志 : 请求的对象,请求参数,返回数据,请求状态,内部方法耗时
*/
@aspect
@component
public class controllerinterceptor {
private static final logger log = loggerfactory.getlogger(controllerinterceptor. class );
@resource
private environment environment;
@around (value = "execution (* name.ealen.web.*.*(..))" )
public object processapifacade(proceedingjoinpoint pjp) {
string appname;
try {
appname = environment.getproperty( "spring.application.name" ).touppercase();
} catch (exception e) {
appname = "unnamed" ;
}
long starttime = system.currenttimemillis();
string name = pjp.gettarget().getclass().getsimplename();
string method = pjp.getsignature().getname();
object result = null ;
httpstatus status = null ;
try {
result = pjp.proceed();
log.info( "requesttarget : " + appname + "." + name + "." + method);
log.info( "requestparam : " + json.tojson(pjp.getargs()));
if (result instanceof responseentity) {
status = ((responseentity) result).getstatuscode();
} else {
status = httpstatus.ok;
}
} catch (throwable throwable) {
status = httpstatus.internal_server_error;
result = new responseentity<>( "{\"internal server error\" : \"" + throwable.getmessage() + "\"}" , status);
throwable.printstacktrace();
} finally {
log.info( "responseentity : {" + "\"httpstatus\":\"" + status.tostring() + "\"" + ",\"responsebody\": " + json.tojson(result) + "}" );
log.info( "internal method cost time: {}ms" , system.currenttimemillis() - starttime);
}
return result;
}
}
|
3 . 提供一个简单的restfull接口 :
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
|
package name.ealen.web;
import org.springframework.http.httpstatus;
import org.springframework.http.responseentity;
import org.springframework.web.bind.annotation.requestbody;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;
/**
* created by ealenxie on 2018/9/7 14:24.
*/
@restcontroller
public class sayhellocontroller {
@requestmapping ( "/sayhello" )
public string sayhello() {
return "hello world" ;
}
@requestmapping ( "/say" )
public responseentity<?> say( @requestbody object o) {
return new responseentity<>(o, httpstatus.ok);
}
}
|
4 . 使用postman进行基本测试 :
5 . 控制台可以看到基本效果 :
以上只是关于controller应该记录日志的一个简单的例子,完整代码可见 https://github.com/ealenxie/springboot-controller-logger
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:http://www.cnblogs.com/ealenxie/p/9618693.html