NutBoot,想统一处理所有接口的入参、出参日志打印,请问有没有什么好的解决方案
另外,有没有判断对象非空的注解
33 回复
public class LogTimeProcessor extends AbstractProcessor {
private static final Log log = Logs.get();
@Override
public void process(ActionContext ac) throws Throwable {
Stopwatch sw = Stopwatch.begin();
try {
doNext(ac);
} finally {
sw.stop();
if (log.isDebugEnabled()) {
HttpServletRequest req = ac.getRequest();
log.debugf("[%4s]URI=%s %sms", req.getMethod(), req.getRequestURI(), sw.getDuration());
}
}
}
}
用这个例子实现了,但是有没有办法可以把接口内的入参和出参回传回来就好了
@wendal 如果接口是入参是json,且是使用@Param("..")接收的对象参数,貌似在这里也没办法做到通用打印哦
我现在是在MainLauncher添加ChainBy进行日志打印
想实现无论接口是GET请求,POST的form请求、json请求
统一打印 请求类型|参数|结果
如:
[GET] | params:a=1&b=2 | ok
[POST] | params:a=1&b=2 | ok
[POST] | params: {a:1,b:2} | ok
// 正常处理的列表
List<Processor> list = new ArrayList<>();
list.add(new LogTimeProcessor()); // 设置日志处理类
list.add(new UpdateRequestAttributesProcessor()); // 设置base/msg等内置属性
list.add(new EncodingProcessor()); // 设置编码信息@Encoding
list.add(new ModuleProcessor()); // 获取入口类的对象,从ioc或直接new
list.add(new ActionFiltersProcessor()); // 处理@Filters
list.add(new AdaptorProcessor()); // 处理@Adaptor
list.add(new MethodInvokeProcessor()); // 执行入口方法
list.add(new ViewProcessor()); // 对入口方法进行渲染@Ok
public void process(ActionContext ac) throws Throwable {
Stopwatch sw = Stopwatch.begin();
try {
doNext(ac);
} finally {
sw.stop();
if (log.isDebugEnabled()) {
HttpServletRequest req = ac.getRequest();
String path = ac.getPath();
List<String> params = new ArrayList<>();
String result = ac.getMethodReturn().toString();
switch (req.getMethod().trim()) {
case "GET":
Enumeration<String> parameterNames = req.getParameterNames();
while(parameterNames.hasMoreElements()) {
String name = parameterNames.nextElement();
String value = req.getParameter(name);
params.add(name + "=" + value);
}
log.infof("[%s]|%s|params:[%s] result:[%s]", "GET", path, StringUtils.join(params, "&"), result);
break;
case "POST":
log.infof("[%s]|%s|params:[%s] result:[%s]", "POST", path, Json.toJson(ac.getMethodArgs(), JsonFormat.compact()), result);
break;
}
}
}
}
@wendal 用fliter实现,copy一个req对象,是不是就可以实现了呢?
@Wizzercn 在我看来就浪费计算资源。。。 日志内容巨多的。。。
然后话说回来,应该是稍微改一下AdaptorProcessor,把json/upload的refer object放入ActionContext,这样就能拿到完整的json/文件上传的数据了,然后把req.getParams和refer object输出到日志
@wendal 判断content-type好说,可是怎么获取post的参数名就不知道怎么操作了
把最后代码放在这里,留给有需要的人
public class LogTimeProcessor extends AbstractProcessor {
private static final Log log = Logs.get();
@Override
public void process(ActionContext ac) throws Throwable {
Stopwatch sw = Stopwatch.begin();
try {
doNext(ac);
} finally {
sw.stop();
HttpServletRequest req = ac.getRequest();
String path = ac.getPath();
String result = Json.toJson(ac.getMethodReturn(), JsonFormat.tidy());
switch (req.getMethod().trim()) {
case "GET":
log.infof("[%s] url:%s params:%s result:%s time:%sms", "GET", path, getParameters(req), result, sw.getDuration());
break;
case "POST":
if(req.getContentType().contains("json")) {
log.infof("[%s] url:%s params:%s result:%s time:%sms", "POST JSON", path, Json.toJson(ac.getMethodArgs(), JsonFormat.tidy()), result, sw.getDuration());
} else {
log.infof("[%s] url:%s params:%s result:%s time:%sms", "POST FORM", path, getParameters(req), result, sw.getDuration());
}
break;
}
}
}
private String getParameters(HttpServletRequest req) {
// 按json格式返回参数
return Json.toJson(req.getParameterMap(), JsonFormat.tidy());
// 下面是按pv模式组织参数
// List<String> params = new ArrayList<>();
// Map map = req.getParameterMap();
// for (Object o : map.keySet()) {
// params.add(o.toString() + "=" + req.getParameter(o.toString()));
// }
// return StringUtils.join(params, "&");
}
}
添加回复
请先登陆