LogAspect.java
4.37 KB
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package com.studymachine.www.aop;
import android.os.Looper;
import android.os.Trace;
import androidx.annotation.NonNull;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.CodeSignature;
import org.aspectj.lang.reflect.MethodSignature;
import java.util.concurrent.TimeUnit;
import timber.log.Timber;
/**
* time : 2019/12/06
* desc : Debug 日志切面
*/
@Aspect
public class LogAspect {
/**
* 构造方法切入点
*/
@Pointcut("execution(@com.studymachine.www.aop.Log *.new(..))")
public void constructor() {}
/**
* 方法切入点
*/
@Pointcut("execution(@com.studymachine.www.aop.Log * *(..))")
public void method() {}
/**
* 在连接点进行方法替换
*/
@Around("(method() || constructor()) && @annotation(log)")
public Object aroundJoinPoint(ProceedingJoinPoint joinPoint, Log log) throws Throwable {
enterMethod(joinPoint, log);
long startNanos = System.nanoTime();
Object result = joinPoint.proceed();
long stopNanos = System.nanoTime();
exitMethod(joinPoint, log, result, TimeUnit.NANOSECONDS.toMillis(stopNanos - startNanos));
return result;
}
/**
* 方法执行前切入
*/
private void enterMethod(ProceedingJoinPoint joinPoint, Log log) {
CodeSignature codeSignature = (CodeSignature) joinPoint.getSignature();
// 方法所在类
String className = codeSignature.getDeclaringType().getName();
// 方法名
String methodName = codeSignature.getName();
// 方法参数名集合
String[] parameterNames = codeSignature.getParameterNames();
// 方法参数值集合
Object[] parameterValues = joinPoint.getArgs();
//记录并打印方法的信息
StringBuilder builder = getMethodLogInfo(className, methodName, parameterNames, parameterValues);
log(log.value(), builder.toString());
final String section = builder.substring(2);
Trace.beginSection(section);
}
/**
* 获取方法的日志信息
*
* @param className 类名
* @param methodName 方法名
* @param parameterNames 方法参数名集合
* @param parameterValues 方法参数值集合
*/
@NonNull
private StringBuilder getMethodLogInfo(String className, String methodName, String[] parameterNames, Object[] parameterValues) {
StringBuilder builder = new StringBuilder("\u21E2 ");
builder.append(className)
.append(".")
.append(methodName)
.append('(');
for (int i = 0; i < parameterValues.length; i++) {
if (i > 0) {
builder.append(", ");
}
builder.append(parameterNames[i]).append('=');
builder.append(parameterValues[i].toString());
}
builder.append(')');
if (Looper.myLooper() != Looper.getMainLooper()) {
builder.append(" [Thread:\"").append(Thread.currentThread().getName()).append("\"]");
}
return builder;
}
/**
* 方法执行完毕,切出
*
* @param result 方法执行后的结果
* @param lengthMillis 执行方法所需要的时间
*/
private void exitMethod(ProceedingJoinPoint joinPoint, Log log, Object result, long lengthMillis) {
Trace.endSection();
Signature signature = joinPoint.getSignature();
String className = signature.getDeclaringType().getName();
String methodName = signature.getName();
StringBuilder builder = new StringBuilder("\u21E0 ")
.append(className)
.append(".")
.append(methodName)
.append(" [")
.append(lengthMillis)
.append("ms]");
// 判断方法是否有返回值
if (signature instanceof MethodSignature && ((MethodSignature) signature).getReturnType() != void.class) {
builder.append(" = ");
builder.append(result.toString());
}
log(log.value(), builder.toString());
}
private void log(String tag, String msg) {
Timber.tag(tag);
Timber.d(msg);
}
}