-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
print access log according to the attachment settings #988
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,14 +20,8 @@ | |
import com.weibo.api.motan.common.URLParamType; | ||
import com.weibo.api.motan.core.extension.Activation; | ||
import com.weibo.api.motan.core.extension.SpiMeta; | ||
import com.weibo.api.motan.rpc.Caller; | ||
import com.weibo.api.motan.rpc.Provider; | ||
import com.weibo.api.motan.rpc.Request; | ||
import com.weibo.api.motan.rpc.Response; | ||
import com.weibo.api.motan.util.LoggerUtil; | ||
import com.weibo.api.motan.util.MotanSwitcherUtil; | ||
import com.weibo.api.motan.util.NetUtils; | ||
import com.weibo.api.motan.util.StringTools; | ||
import com.weibo.api.motan.rpc.*; | ||
import com.weibo.api.motan.util.*; | ||
import org.apache.commons.lang3.StringUtils; | ||
|
||
/** | ||
|
@@ -47,36 +41,78 @@ | |
public class AccessLogFilter implements Filter { | ||
|
||
public static final String ACCESS_LOG_SWITCHER_NAME = "feature.motan.filter.accessLog"; | ||
public static final String PRINT_TRACE_LOG_SWITCHER_NAME = "feature.motan.printTraceLog.enable"; | ||
private String side; | ||
private Boolean accessLog; | ||
|
||
static { | ||
// init global switcher, default value is false | ||
// init global switcher | ||
MotanSwitcherUtil.initSwitcher(ACCESS_LOG_SWITCHER_NAME, false); | ||
MotanSwitcherUtil.initSwitcher(PRINT_TRACE_LOG_SWITCHER_NAME, true); | ||
} | ||
|
||
@Override | ||
public Response filter(Caller<?> caller, Request request) { | ||
if (accessLog == null) { | ||
accessLog = caller.getUrl().getBooleanParameter(URLParamType.accessLog.getName(), URLParamType.accessLog.getBooleanValue()); | ||
} | ||
if (accessLog || MotanSwitcherUtil.isOpen(ACCESS_LOG_SWITCHER_NAME)) { | ||
long t1 = System.currentTimeMillis(); | ||
if (accessLog || needLog(request)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这里判断有点别扭,应该只一个方法needLog去判断,是否需要打印逻辑封装在needLog里面。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这里的想法是把access自身配置显示独立出来,其他都属于非配置情况下打印accesslog的场景,后续其他判断条件都会在needlog方法中进行判断。这里可以对needlog方法增加注释来进行补充说明 |
||
long start = System.currentTimeMillis(); | ||
boolean success = false; | ||
Response response = null; | ||
try { | ||
Response response = caller.call(request); | ||
success = true; | ||
response = caller.call(request); | ||
if (response != null && response.getException() == null) { | ||
success = true; | ||
} | ||
return response; | ||
} finally { | ||
long consumeTime = System.currentTimeMillis() - t1; | ||
logAccess(caller, request, consumeTime, success); | ||
processFinalLog(caller, request, response, start, success); | ||
} | ||
} else { | ||
return caller.call(request); | ||
} | ||
} | ||
|
||
private void logAccess(Caller<?> caller, Request request, long consumeTime, boolean success) { | ||
private void processFinalLog(final Caller<?> caller, final Request request, final Response response, final long start, final boolean success) { | ||
long wholeTime = System.currentTimeMillis() - start; | ||
long segmentTime = wholeTime; // 分段耗时。server侧是内部业务耗时,client侧时server整体耗时+网络接收耗时 | ||
|
||
if (request instanceof Traceable && response instanceof Traceable) { // 可以取得细分时间点 | ||
if (caller instanceof Provider) { // server end | ||
if (response instanceof Callbackable) {// 因server侧完整耗时包括response发送时间,需要通过callback机制异步记录日志。 | ||
long finalSegmentTime = segmentTime; | ||
((Callbackable) response).addFinishCallback(() -> { | ||
long responseSend = ((Traceable) response).getTraceableContext().getSendTime(); | ||
long requestReceive = ((Traceable) request).getTraceableContext().getReceiveTime(); | ||
long finalWholeTime = responseSend - requestReceive; | ||
logAccess(caller, request, response, finalSegmentTime, finalWholeTime, success); | ||
}, null); | ||
return; | ||
} | ||
} else { // client end | ||
long requestSend = ((Traceable) request).getTraceableContext().getSendTime(); | ||
long responseReceive = ((Traceable) response).getTraceableContext().getReceiveTime(); | ||
segmentTime = responseReceive - requestSend; | ||
} | ||
} | ||
logAccess(caller, request, response, segmentTime, wholeTime, success); // 同步记录access日志 | ||
} | ||
|
||
// 除了access log配置外,其他需要动态打印access的情况 | ||
private boolean needLog(Request request) { | ||
if (MotanSwitcherUtil.isOpen(ACCESS_LOG_SWITCHER_NAME)) { | ||
return true; | ||
} | ||
|
||
// check trace log | ||
if (!MotanSwitcherUtil.isOpen(PRINT_TRACE_LOG_SWITCHER_NAME)) { | ||
return false; | ||
} | ||
return "true".equalsIgnoreCase(request.getAttachments().get(MotanConstants.ATT_PRINT_TRACE_LOG)); | ||
} | ||
|
||
private void logAccess(Caller<?> caller, Request request, Response response, long segmentTime, long wholeTime, boolean success) { | ||
if (getSide() == null) { | ||
String side = caller instanceof Provider ? MotanConstants.NODE_TYPE_SERVICE : MotanConstants.NODE_TYPE_REFERER; | ||
setSide(side); | ||
|
@@ -107,7 +143,10 @@ private void logAccess(Caller<?> caller, Request request, long consumeTime, bool | |
requestId = String.valueOf(request.getRequestId()); | ||
} | ||
append(builder, requestId); | ||
append(builder, consumeTime); | ||
append(builder, request.getAttachments().get(MotanConstants.CONTENT_LENGTH)); | ||
append(builder, response.getAttachments().get(MotanConstants.CONTENT_LENGTH)); | ||
append(builder, segmentTime); | ||
append(builder, wholeTime); | ||
|
||
LoggerUtil.accessLog(builder.substring(0, builder.length() - 1)); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
控制的是access log,使用trace字眼是否合适呢?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trace log是一个纵向行为,trace log 标记可以控制整个链路中不同位置的log 行为,不只是针对access 日志,后续其他地方也可能会处理该标记,包括业务侧。