/**
* @author Ly
* @create 2020/8/20 10:27
* @desc
**/
@Slf4j
public abstract class TagFilter{
protected SkywalkingConfigurationProperties skywalkingConfigurationProperties;
public TagFilter(SkywalkingConfigurationProperties skywalkingConfigurationProperties) {
this.skywalkingConfigurationProperties = skywalkingConfigurationProperties;
}
public TagFilter() {
}
public void handle(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain){
HttpServletRequest request = (HttpServletRequest) servletRequest;
String requestURI = request.getRequestURI();
HttpServletResponse response = (HttpServletResponse) servletResponse;
if(skywalkingConfigurationProperties.getEnable()){
ActiveSpan.tag(Constants.URI_TAG,requestURI);
CustomHttpServletResponseWrapper customHttpServletResponseWrapper = new CustomHttpServletResponseWrapper(response);
try {
filterChain.doFilter(this.handleRequestMethod(new CustomHttpServletRequestWrapper(request)), customHttpServletResponseWrapper);
byte[] bytes = this.handleResponseMethod(customHttpServletResponseWrapper);
response.getOutputStream().write(bytes);
}catch (Exception e){
log.error("添加skywalking-tag失败:",e);
}
}else{
try {
filterChain.doFilter(request,response);
} catch (Exception e) {
log.error("添加skywalking-tag失败:",e);
}
}
}
/**
* 处理请求
* @param request
* @return
*/
protected abstract HttpServletRequest handleRequestMethod(CustomHttpServletRequestWrapper request);
/**
* 处理响应
* @param customHttpServletResponseWrapper
* @return
*/
protected abstract byte[] handleResponseMethod(CustomHttpServletResponseWrapper customHttpServletResponseWrapper);
}
/**
* @author Ly
* @create 2020/11/6 16:08
* @desc
**/
@Slf4j
@Component
@ConditionalOnProperty(prefix = "skywalking.filter" , name = "default",havingValue = "true",matchIfMissing = true)
public class DefaultTagFilter extends TagFilter implements Filter {
@Autowired
private UserApi userApi;
@Autowired
public DefaultTagFilter(SkywalkingConfigurationProperties skywalkingConfigurationProperties) {
super(skywalkingConfigurationProperties);
}
public DefaultTagFilter() {
super();
}
@Override
@Trace
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {
super.handle(servletRequest, servletResponse, filterChain);
}
@Override
protected HttpServletRequest handleRequestMethod(CustomHttpServletRequestWrapper request) {
try {
return this.defaultHandleRequest(request);
} catch (Exception e) {
log.error("处理请求失败!");
return null;
}
}
@Override
protected byte[] handleResponseMethod(CustomHttpServletResponseWrapper response) {
try {
return this.defaultHandleResponse(response);
} catch (Exception e) {
log.error("处理请求失败!");
return null;
}
}
protected byte[] defaultHandleResponse(CustomHttpServletResponseWrapper customHttpServletResponseWrapper) throws Exception{
byte[] bytes = customHttpServletResponseWrapper.getBytes();
String content = new String(bytes,"UTF-8");
ActiveSpan.setOperationName(skywalkingConfigurationProperties.getOperationName());
ActiveSpan.tag(Constants.RESPONSE_BODY_TAG,content);
log.info("响应成功!");
return bytes;
}
protected HttpServletRequest defaultHandleRequest(CustomHttpServletRequestWrapper request) throws Exception{
String token = TagRequestParamUtil.tokenFromHeader(request.getHeader("Authorization"));
String requestURI = request.getRequestURI();
String name = skywalkingConfigurationProperties.getName();
ActiveSpan.setOperationName(skywalkingConfigurationProperties.getOperationName());
String params = null;
if(!StringUtils.isEmpty(token)){
Response<UserInfoRespDTO> userInfoWithToken = userApi.getUserInfoWithToken(token);
UserInfoRespDTO userInfos = userInfoWithToken.getData();
if(userInfos != null){
ActiveSpan.tag(name,userInfos.getUsername());
}else{
log.error("根据token获取用户信息失败!");
}
}
String method = request.getMethod();
if(HttpMethod.GET.name().equals(method)){
Map<String, String[]> parameterMap = request.getParameterMap();
if(StringUtils.isEmpty(token)){
String[] result = parameterMap.get(name);
if(result != null && result.length > 0){
ActiveSpan.tag(name,String.valueOf(result));
}else{
log.warn("请求{}不存在指定的tag参数{}",requestURI,name);
}
}
params = JSON.toJSONString(parameterMap);
log.info("获取GET请求参数成功:{}",requestURI);
}else if(HttpMethod.POST.name().equals(method)){
String bodyParams = CustomHttpServletRequestWrapper.getBodyMap(request.getInputStream());
if(bodyParams.startsWith("{")){
JSONObject jsonObject = JSON.parseObject(bodyParams);
if(StringUtils.isEmpty(token)){
Object o = jsonObject.get(name);
if(o != null){
ActiveSpan.tag(name,String.valueOf(o));
}else{
log.warn("请求{}不存在指定的tag参数{}",requestURI,name);
}
}
jsonObject.remove(Constants.LIMIT_OBJECT_KEY);
params = jsonObject.toJSONString();
}else{
params = bodyParams;
}
log.info("获取POST请求参数成功:{}",requestURI);
}
if(!StringUtils.isEmpty(params)){
ActiveSpan.tag(Constants.REQUEST_PARAMS_TAG,params);
}else{
log.warn("未获取到参数信息!");
}
return request;
}
}
/**
* @author Ly
* @create 2020/8/17 17:50
* @desc
**/
@Slf4j
public class TagRequestParamUtil {
public static String tokenFromHeader(String authorization) {
if(StringUtils.isEmpty(authorization)){
return authorization;
}
String prefix = "Bearer ";
if (authorization == null || !authorization.startsWith(prefix)) {
return null;
}
return authorization.substring(prefix.length());
}
public static byte[] addResponseTag(CustomHttpServletResponseWrapper customHttpServletResponseWrapper,String operationName,String requestURI) throws Exception{
Map<String,String> responseBodyMap = Maps.newHashMap();
byte[] bytes = customHttpServletResponseWrapper.getBytes();
String content = new String(bytes,"UTF-8");
responseBodyMap.put(requestURI, content);
ActiveSpan.setOperationName(operationName);
String responseBodyString = JSON.toJSONString(responseBodyMap);
ActiveSpan.tag(Constants.URI_TAG,requestURI);
ActiveSpan.tag(Constants.RESPONSE_BODY_TAG,content);
ActiveSpan.info(responseBodyString);
log.info("响应体信息:{}",responseBodyString);
return bytes;
}
}
/**
* @author Ly
* @create 2020/8/20 10:35
* @desc
**/
@Configuration
@ConfigurationProperties(prefix = "skywalking.tag")
@Data
@PropertySource(value = "skywalking.properties")
public class SkywalkingConfigurationProperties {
private Boolean enable;
private String operationName;
private String url;
private String name;
}
skywalking.properties:
skywalking.tag.operationName = puma-tag
skywalking.tag.url = http://localhost:8080/graphql
skywalking.tag.enable = true
skywalking.tag.name = username
skywalking.filter.default = false