com.taobao.eagleeye.EagleEyeRequestTracer Maven / Gradle / Ivy
package com.taobao.eagleeye;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 抽离和前端相关的 EagleEye 通用埋点逻辑。
* 支持从 URL/Header 中获取 EagleEye 的配置。
* 常见埋点方法:
*
* String traceId = EagleEyeRequestTracer.getTraceId(httpRequest);
* EagleEyeRequestTracer.startTrace(traceId, req, resp);
* try {
* // 处理业务逻辑...
* chain.doFilter(req, resp);
* } finally {
* EagleEyeRequestTracer.endTrace(req, resp);
* }
*
* startTrace 调用后,一定要保证调用一次 endTrace。
* startTrace 和 endTrace 是幂等的,重复调用不会影响逻辑。
* 如果没有调用 startTrace,直接调用 endTrace,也是可以的。
* @since 1.5.0-exported
*/
public class EagleEyeRequestTracer {
/**
* 获取远程客户端的 IP
* @param request
* @return
*/
public static final String getRemoteAddress(HttpServletRequest request) {
return request.getRemoteAddr();
}
/**
* 获取 TraceId,如果没有,自动生成。
* @param request
* @return
* @see #getTraceId(HttpServletRequest, String)
*/
public static final String getTraceId(HttpServletRequest request) {
// 传入 null 则使用服务器自身的 IP
return getTraceId(request, null);
}
/**
* 获取 TraceId。根据以下步骤:
*
* - 从 ThreadLocal 获取
* - 从 URL 参数中 获取
* - 从 header 中 获取
* - 如果上述都没有,则自动生成,如果 ip 不为
null
,则基于指定的 ip,
* 否则,使用本机 ip
*
*
* @param httpRequest
* @param ip
*/
public static final String getTraceId(HttpServletRequest httpRequest, String ip) {
return EagleEye.generateTraceId(ip);
}
/**
* 开始调用链,注意,开始之后,不管后续处理是否正常,都需要调用
* {@link #endTrace(HttpServletRequest, HttpServletResponse)}。
* @param traceId
* @param httpRequest
* @param httpResponse
*/
public static final void startTrace(final String traceId,
HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
final String url = getRequestUrl(httpRequest);
final String rpcId = EagleEye.ROOT_RPC_ID;
final String queryString = httpRequest.getQueryString();
startTraceInner(traceId, rpcId, url, queryString, httpRequest, httpResponse);
}
private static final String getRequestUrl(HttpServletRequest httpRequest) {
StringBuffer sb = httpRequest.getRequestURL();
final String url;
if (sb != null) {
url = sb.toString();
} else {
url = httpRequest.getRequestURI();
}
return url;
}
/**
* 开始调用链,允许另外指定 TraceId、RpcId、URL、Query 参数等信息。注意,开始之后,不管后续处理是否正常,
* 都需要调用 {@link #endTrace(HttpServletRequest, HttpServletResponse)}。
* @param traceId
* @param url
* @param queryString
* @param httpRequest
* @param httpResponse
*/
public static final void startTraceInner(String traceId, String rpcId, String url,
String queryString, HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
}
/**
* 结束调用链。
* 注意:需要假定 response 已经提交,因此只能做只读操作,不能修改
* @param httpRequest
* @param httpResponse
*/
public static final void endTrace(HttpServletRequest httpRequest,
HttpServletResponse httpResponse) {
}
/**
* 结束调用链,设置响应状态码和调用类型。
* 注意:需要假定 response 已经提交,因此只能做只读操作,不能修改
* @param httpRequest
* @param httpResponse
* @param resultCode 建议使用 {@link HttpServletResponse#setStatus(int) HTTP 状态码}
* @param type
*/
public static final void endTrace(HttpServletRequest httpRequest,
HttpServletResponse httpResponse, String resultCode, int type) {
}
}