/* * 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; } }