|
1
2
3
4
|
package com.huaheng.framework.aspectj;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
|
|
5
|
import com.huaheng.common.constant.QuantityConstant;
|
|
6
7
|
import com.huaheng.common.utils.ServletUtils;
import com.huaheng.common.utils.StringUtils;
|
|
8
|
import com.huaheng.common.utils.security.ShiroUtils;
|
|
9
|
import com.huaheng.common.utils.spring.SpringUtils;
|
|
10
11
12
13
14
15
|
import com.huaheng.framework.aspectj.lang.annotation.ApiLogger;
import com.huaheng.framework.web.domain.AjaxResult;
import com.huaheng.pc.config.address.domain.Address;
import com.huaheng.pc.config.address.service.AddressService;
import com.huaheng.pc.monitor.apilog.domain.ApiLog;
import com.huaheng.pc.monitor.apilog.service.IApiLogService;
|
|
16
17
|
import okhttp3.Request;
import okhttp3.Response;
|
|
18
19
|
import org.apache.commons.lang.exception.ExceptionUtils;
import org.aspectj.lang.ProceedingJoinPoint;
|
|
20
21
22
|
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
|
|
23
24
25
26
|
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
|
|
27
28
|
import org.springframework.http.HttpHeaders;
import org.springframework.scheduling.annotation.Async;
|
|
29
30
|
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;
|
|
31
32
|
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
|
|
33
34
35
36
37
38
39
40
41
|
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
/**
* Api调用日志记录处理
|
|
42
|
*
|
|
43
44
45
46
|
* @author huaheng
*/
@Aspect
@Component
|
|
47
48
|
@EnableAsync
public class ApiLogAspect {
|
|
49
50
51
52
53
54
55
56
|
private static final Logger log = LoggerFactory.getLogger(ApiLogAspect.class);
private static IApiLogService apiLogService;
private static AddressService addressService;
@Autowired
|
|
57
|
public void setApiLogService(IApiLogService apiLogService) {
|
|
58
59
60
61
|
ApiLogAspect.apiLogService = apiLogService;
}
@Autowired
|
|
62
|
public void setAddressService(AddressService addressService) {
|
|
63
64
65
66
67
|
ApiLogAspect.addressService = addressService;
}
// 配置织入点
@Pointcut("@annotation(com.huaheng.framework.aspectj.lang.annotation.ApiLogger)")
|
|
68
|
public void logPointCut() {
|
|
69
70
71
|
}
@Around("logPointCut() && @annotation(apiLogger)")
|
|
72
73
|
public Object around(ProceedingJoinPoint point, ApiLogger apiLogger) throws Throwable {
if ("WMS".equalsIgnoreCase(apiLogger.from()))
|
|
74
|
//实际上静态方法上的Aop注解无法拦截到
|
|
75
76
77
78
79
|
return aroundWms2XXX(point, apiLogger);
else
return aroundXXX2Wms(point, apiLogger);
}
|
|
80
81
82
83
|
/**
* 处理xxx调用wms接口的日志
**/
private Object aroundXXX2Wms(ProceedingJoinPoint point, ApiLogger apiLogger) {
|
|
84
85
|
Object ret = null;
ApiLog log = initApiLog(apiLogger, point);
|
|
86
|
try {
|
|
87
|
ret = point.proceed();
|
|
88
|
} catch (Exception e) {
|
|
89
|
setApiLogException(log, e);
|
|
90
91
|
ret = AjaxResult.error(e.getMessage());
} finally {
|
|
92
93
94
95
96
|
finishApiLog(log, ret);
return ret;
}
}
|
|
97
98
99
100
|
/**
* 处理WMS调用xxx接口的日志
**/
private Object aroundWms2XXX(ProceedingJoinPoint point, ApiLogger apiLogger) {
|
|
101
102
103
104
105
106
107
|
Object ret = null;
ApiLog log = new ApiLog();
HttpURLConnection connection = null;
String body = null;
try {
|
|
108
|
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
|
109
110
|
connection = (HttpURLConnection) point.getArgs()[0];
body = (String) point.getArgs()[1];
|
|
111
|
initApiLog(connection, body, ShiroUtils.getWarehouseCode());
|
|
112
|
} catch (Exception e) {
|
|
113
114
115
|
}
|
|
116
|
try {
|
|
117
|
ret = point.proceed();
|
|
118
|
} catch (Exception e) {
|
|
119
120
|
setApiLogException(log, e);
throw e;
|
|
121
122
|
} finally {
if (ret != null) {
|
|
123
124
|
finishApiLog(log, connection, ret.toString());
}
|
|
125
126
127
128
|
return ret;
}
}
|
|
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
/**记录WMS调用外接口的请求信息
* 在HttpUtils.bodypost方法中直接调用本类static方法**/
public static ApiLog initApiLog(Request request, String body){
ApiLog log = new ApiLog();
try {
log.setApiMethod(request.method());
log.setUrl(request.url().toString());
log.setRequestTime(new Date());
parseUrl(log, request.url().url());
log.setRequestHeader(request.headers().toString());
log.setRequestBody(body);
}catch (Exception e){
e.printStackTrace();
}
return log;
}
/**根据url,从address表中判断调用的去向**/
public static void parseUrl(ApiLog log, URL url){
try {
String[] spList = url.toString().split("/");
String apiName = spList[spList.length - 1];
int index = url.toString().lastIndexOf(apiName);
String addUrl = url.toString().substring(0, index);
Address address = addressService.getAddressByUrl(url.toString(), QuantityConstant.DEFAULT_WAREHOUSE);
log.setApiName(apiName);
log.setRequestFrom("WMS");
log.setResponseBy(address.getParam().toUpperCase());
}catch (Exception e){
e.printStackTrace();
}
}
|
|
163
164
165
166
167
|
/**
* 记录WMS调用外接口的请求信息
* 在HttpUtils.bodypost方法中直接调用本类static方法
**/
public static ApiLog initApiLog(HttpURLConnection connection, String body, String warehouseCode) {
|
|
168
169
170
171
172
|
ApiLog log = new ApiLog();
try {
log.setApiMethod(connection.getRequestMethod());
log.setUrl(connection.getURL().toString());
log.setRequestTime(new Date());
|
|
173
|
parseUrl(log, connection.getURL(), warehouseCode);
|
|
174
175
176
177
178
179
180
181
182
183
184
|
//请求头
Set<String> keySet = connection.getRequestProperties().keySet();
ArrayList<String> headerList = new ArrayList<>();
Iterator<String> it = keySet.iterator();
while (it.hasNext()) {
String name = it.next();
String header = connection.getRequestProperty(name);
headerList.add(name + ": " + header);
}
|
|
185
|
log.setRequestHeader(org.apache.commons.lang3.StringUtils.join(headerList, "\n"));
|
|
186
|
log.setRequestBody(body);
|
|
187
|
} catch (Exception e) {
|
|
188
189
190
191
192
193
|
e.printStackTrace();
}
return log;
}
|
|
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
|
/**
* 记录WMS调用外接口的请求信息
* 在HttpUtils.bodypost方法中直接调用本类static方法
**/
public static ApiLog initApiLog(String Method, String url, String body, HttpHeaders headers, String warehouseCode) {
ApiLog log = new ApiLog();
try {
URL url1 = new URL(url);
log.setApiMethod(Method);
log.setUrl(url);
log.setRequestTime(new Date());
parseUrl(log, url1, warehouseCode);
//请求头
Set<String> keySet = headers.keySet();
ArrayList<String> headerList = new ArrayList<>();
Iterator<String> it = keySet.iterator();
while (it.hasNext()) {
String name = it.next();
String header = String.valueOf(headers.getContentType());
headerList.add(name + ": " + header);
}
log.setRequestHeader(org.apache.commons.lang3.StringUtils.join(headerList, "\n"));
log.setRequestBody(body);
} catch (Exception e) {
e.printStackTrace();
}
return log;
}
/**
* 根据url,从address表中判断调用的去向
**/
public static void parseUrl(ApiLog log, URL url, String warehouseCode) {
|
|
231
232
233
234
235
236
|
try {
String[] spList = url.toString().split("/");
String apiName = spList[spList.length - 1];
int index = url.toString().lastIndexOf(apiName);
String addUrl = url.toString().substring(0, index);
|
|
237
|
Address address = addressService.getAddressByUrl(url.toString(), warehouseCode);
|
|
238
239
240
|
log.setApiName(apiName);
log.setRequestFrom("WMS");
log.setResponseBy(address.getParam().toUpperCase());
|
|
241
|
} catch (Exception e) {
|
|
242
243
244
245
|
e.printStackTrace();
}
}
|
|
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
|
/**记录响应头信息**/
public static void finishApiLog(ApiLog log, Response response, String body){
try {
log.setResponseBody(body);
log.setResponseTime(new Date());
Long duration = log.getResponseTime().getTime() - log.getRequestTime().getTime();
log.setDuration(duration.intValue());
log.setHttpCode(String.valueOf(response.code()));
//响应头
log.setResponseHeader(response.headers().toString());
AjaxResult ajaxResult = null;
try{
ajaxResult = JSON.parseObject(body, AjaxResult.class);
}catch(Exception ex){
body = JSON.parse(body).toString();
ajaxResult = JSON.parseObject(body, AjaxResult.class);
}
log.setRetCode(String.valueOf(ajaxResult.getCode()));
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if (StringUtils.isNotEmpty(log.getResponseBody()) && log.getResponseBody().length() > 2001) {
log.setResponseBody(log.getResponseBody().substring(0, 2000) + "\n太长了...后面省略。\n" + log.getResponseBody().length());
}
}catch (Exception e){
}
SpringUtils.getBean(ApiLogAspect.class).saveApiLog(log);
}
}
|
|
279
280
281
282
|
/**
* 记录响应头信息
**/
public static void finishApiLog(ApiLog log, HttpURLConnection connection, String body) {
|
|
283
284
285
286
287
288
289
290
291
292
293
|
try {
log.setResponseBody(body);
log.setResponseTime(new Date());
Long duration = log.getResponseTime().getTime() - log.getRequestTime().getTime();
log.setDuration(duration.intValue());
log.setHttpCode(String.valueOf(connection.getResponseCode()));
//响应头
Set<String> keyset = connection.getHeaderFields().keySet();
ArrayList<String> headerList = new ArrayList<>();
Iterator<String> it = keyset.iterator();
|
|
294
|
while (it.hasNext()) {
|
|
295
296
|
String name = it.next();
String header = connection.getHeaderField(name);
|
|
297
|
if (name == null || "".equals(name))
|
|
298
299
300
301
302
|
//第一行没有name
//HTTP/1.1 200 OK
headerList.add(header);
else
headerList.add(name + ": " + header);
|
|
303
304
305
|
}
log.setResponseHeader(org.apache.commons.lang3.StringUtils.join(headerList, "\n"));
AjaxResult json = JSON.parseObject(body, AjaxResult.class);
|
|
306
|
log.setRetCode(String.valueOf(json.getCode()));
|
|
307
|
} catch (Exception e) {
|
|
308
|
e.printStackTrace();
|
|
309
310
|
} finally {
SpringUtils.getBean(ApiLogAspect.class).saveApiLog(log);
|
|
311
312
313
|
}
}
|
|
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
|
/**
* 记录响应头信息
**/
public static void finishApiLog(ApiLog log, HttpHeaders headers, String body) {
try {
log.setResponseBody(body);
log.setResponseTime(new Date());
Long duration = log.getResponseTime().getTime() - log.getRequestTime().getTime();
log.setDuration(duration.intValue());
log.setHttpCode(String.valueOf(200));
//响应头
Set<String> keyset = headers.keySet();
ArrayList<String> headerList = new ArrayList<>();
Iterator<String> it = keyset.iterator();
while (it.hasNext()) {
String name = it.next();
String header = String.valueOf(headers.getContentType());
if (name == null || "".equals(name))
//第一行没有name
//HTTP/1.1 200 OK
headerList.add(header);
else
headerList.add(name + ": " + header);
}
log.setResponseHeader(org.apache.commons.lang3.StringUtils.join(headerList, "\n"));
AjaxResult json = JSON.parseObject(body, AjaxResult.class);
log.setRetCode(String.valueOf(json.getCode()));
} catch (Exception e) {
e.printStackTrace();
} finally {
SpringUtils.getBean(ApiLogAspect.class).saveApiLog(log);
}
}
private ApiLog initApiLog(ApiLogger apiLogger, ProceedingJoinPoint point) {
|
|
352
|
ApiLog log = new ApiLog();
|
|
353
|
try {
|
|
354
355
356
357
358
359
360
361
362
|
log.setRequestTime(new Date());
log.setRequestFrom(apiLogger.from());
log.setResponseBy(apiLogger.to());
log.setApiName(apiLogger.apiName());
HttpServletRequest request = ServletUtils.getRequest();
String qryStr = request.getQueryString();
String url = request.getRequestURL().toString();
|
|
363
|
if (StringUtils.isNotEmpty(qryStr))
|
|
364
365
366
367
368
369
370
371
372
373
374
|
url = url + "?" + qryStr;
log.setUrl(url);
log.setApiMethod(request.getMethod());
log.setIp(request.getRemoteAddr());
rebuildRequestHeader(log);
rebuildRequestBody(log, request);
//如果reqeust中取不到post参数,就从接口方法参数中取json对象
|
|
375
|
if (StringUtils.isEmpty(log.getRequestBody()))
|
|
376
377
|
rebuildRequestBody(log, point);
|
|
378
|
} catch (Exception e) {
|
|
379
380
381
382
383
384
|
e.printStackTrace();
}
return log;
}
|
|
385
|
private void finishApiLog(ApiLog log, Object ret) {
|
|
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
|
try {
rebuildResponseHeader(log);
rebuildResponseBody(log, ret);
log.setResponseTime(new Date());
Long duration = log.getResponseTime().getTime() - log.getRequestTime().getTime();
log.setDuration(duration.intValue());
HttpServletResponse resp = ServletUtils.getResponse();
log.setHttpCode(String.valueOf(resp.getStatus()));
if (ret instanceof AjaxResult) {
int retCode = ((AjaxResult) ret).getCode();
log.setRetCode(String.valueOf(retCode));
}
|
|
401
|
} catch (Exception e) {
|
|
402
|
e.printStackTrace();
|
|
403
|
} finally {
|
|
404
405
406
407
|
saveApiLog(log);
}
}
|
|
408
|
public static void setApiLogException(ApiLog log, Exception e) {
|
|
409
410
|
try {
String exception = ExceptionUtils.getFullStackTrace(e);
|
|
411
|
String shortExpInfo = e.getMessage() + "\n" + org.apache.commons.lang3.StringUtils.left(exception, 1000);
|
|
412
|
log.setException(shortExpInfo);
|
|
413
|
} catch (Exception ex) {
|
|
414
415
416
417
|
ex.printStackTrace();
}
}
|
|
418
|
private void rebuildRequestHeader(ApiLog log) {
|
|
419
420
421
422
|
try {
HttpServletRequest req = ServletUtils.getRequest();
Enumeration names = req.getHeaderNames();
ArrayList<String> headerList = new ArrayList<>();
|
|
423
424
|
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
|
|
425
426
427
428
429
|
String header = req.getHeader(name);
headerList.add(name + ": " + header);
}
String headers = org.apache.commons.lang3.StringUtils.join(headerList, "\n");
log.setRequestHeader(headers);
|
|
430
|
} catch (Exception e) {
|
|
431
432
433
434
|
e.printStackTrace();
}
}
|
|
435
436
437
438
439
|
/**
* 先从post参数中构造request body
*/
private void rebuildRequestBody(ApiLog log, HttpServletRequest request) {
try {
|
|
440
441
442
|
Set<String> keySet = request.getParameterMap().keySet();
Iterator<String> it = keySet.iterator();
StringBuffer sbf = new StringBuffer();
|
|
443
|
while (it.hasNext()) {
|
|
444
445
446
|
String key = it.next();
String value = request.getParameter(key);
sbf.append(key).append("=").append(value);
|
|
447
|
if (it.hasNext())
|
|
448
449
450
|
sbf.append("&");
}
log.setRequestBody(sbf.toString());
|
|
451
|
} catch (Exception e) {
|
|
452
453
454
455
456
457
458
|
e.printStackTrace();
}
}
/**
* 根据接口中的参数构造request body
*/
|
|
459
|
private void rebuildRequestBody(ApiLog log, ProceedingJoinPoint point) {
|
|
460
461
462
463
464
465
466
467
468
469
470
471
472
|
try {
if (point.getArgs().length == 1) {
log.setRequestBody(JSONObject.toJSONString(point.getArgs()[0]));
return;
}
MethodSignature m = (MethodSignature) point.getSignature();
HashMap<String, Object> map = new HashMap<>();
Object[] args = point.getArgs();
for (int i = 0; i < m.getParameterNames().length; i++) {
String name = m.getParameterNames()[i];
// Class type = m.getParameterTypes()[i];
map.put(name, args[i]);
}
|
|
473
|
if (!map.isEmpty())
|
|
474
|
log.setRequestBody(JSONObject.toJSONString(map));
|
|
475
|
} catch (Exception e) {
|
|
476
477
478
479
|
e.printStackTrace();
}
}
|
|
480
|
private void rebuildResponseHeader(ApiLog log) {
|
|
481
482
483
484
485
|
try {
HttpServletResponse resp = ServletUtils.getResponse();
Collection names = resp.getHeaderNames();
ArrayList<String> headerList = new ArrayList<>();
Iterator<String> it = names.iterator();
|
|
486
|
while (it.hasNext()) {
|
|
487
488
489
490
491
492
|
String name = it.next();
String header = resp.getHeader(name);
headerList.add(name + ": " + header);
}
String headers = org.apache.commons.lang3.StringUtils.join(headerList, "\n");
log.setResponseHeader(headers);
|
|
493
|
} catch (Exception e) {
|
|
494
495
496
497
|
e.printStackTrace();
}
}
|
|
498
|
private void rebuildResponseBody(ApiLog log, Object ret) {
|
|
499
500
|
try {
log.setResponseBody(JSONObject.toJSON(ret).toString());
|
|
501
|
} catch (Exception e) {
|
|
502
503
504
505
|
e.printStackTrace();
}
}
|
|
506
507
508
|
@Async
public void saveApiLog(ApiLog log) {
try {
|
|
509
|
apiLogService.saveOrUpdate(log);
|
|
510
|
} catch (Exception e) {
|
|
511
512
513
514
|
e.printStackTrace();
}
}
}
|