/*
* Copyright 2009-2016 Weibo, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.weibo.api.motan.filter;
import com.weibo.api.motan.common.MotanConstants;
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.NetUtils;
import com.weibo.api.motan.util.StringTools;
/**
* <pre>
* Access log filter
*
* 统计整个call的执行状况,尽量到最上层,最后执行.
* 此filter会对性能产生一定影响,请求量较大时建议关闭。
*
* </pre>
*
* @author fishermen
* @version V1.0 created at: 2013-5-22
*/
@SpiMeta(name = "access")
@Activation(sequence = 100)
public class AccessLogFilter implements Filter {
private String side;
@Override
public Response filter(Caller<?> caller, Request request) {
boolean needLog = caller.getUrl().getBooleanParameter(URLParamType.accessLog.getName(), URLParamType.accessLog.getBooleanValue());
if (needLog) {
long t1 = System.currentTimeMillis();
boolean success = false;
try {
Response response = caller.call(request);
success = true;
return response;
} finally {
long consumeTime = System.currentTimeMillis() - t1;
logAccess(caller, request, consumeTime, success);
}
} else {
return caller.call(request);
}
}
private void logAccess(Caller<?> caller, Request request, long consumeTime, boolean success) {
if (getSide() == null) {
String side = caller instanceof Provider ? MotanConstants.NODE_TYPE_SERVICE : MotanConstants.NODE_TYPE_REFERER;
setSide(side);
}
StringBuilder builder = new StringBuilder(128);
append(builder, side);
append(builder, caller.getUrl().getParameter(URLParamType.application.getName()));
append(builder, caller.getUrl().getParameter(URLParamType.module.getName()));
append(builder, NetUtils.getLocalAddress().getHostAddress());
append(builder, request.getInterfaceName());
append(builder, request.getMethodName());
append(builder, request.getParamtersDesc());
// 对于client,url中的remote ip, application, module,referer 和 service获取的地方不同
if (MotanConstants.NODE_TYPE_REFERER.equals(side)) {
append(builder, caller.getUrl().getHost());
append(builder, caller.getUrl().getParameter(URLParamType.application.getName()));
append(builder, caller.getUrl().getParameter(URLParamType.module.getName()));
} else {
append(builder, request.getAttachments().get(URLParamType.host.getName()));
append(builder, request.getAttachments().get(URLParamType.application.getName()));
append(builder, request.getAttachments().get(URLParamType.module.getName()));
}
append(builder, success);
append(builder, request.getAttachments().get(URLParamType.requestIdFromClient.getName()));
append(builder, consumeTime);
LoggerUtil.accessLog(builder.substring(0, builder.length() - 1));
}
private void append(StringBuilder builder, Object field) {
if (field != null) {
builder.append(StringTools.urlEncode(field.toString()));
}
builder.append(MotanConstants.SEPERATOR_ACCESS_LOG);
}
public String getSide() {
return side;
}
public void setSide(String side) {
this.side = side;
}
}