• skywalking展示http请求和响应


    1.效果图

    可以在请求中看到自定义请求信息input和返回值output,方便快速定位问题

    2.添加依赖

    1. <dependency>
    2. <groupId>org.apache.skywalking</groupId>
    3. <artifactId>apm-toolkit-trace</artifactId>
    4. <version>9.1.0</version>
    5. <scope>provided</scope>
    6. </dependency>

    3.核心语法

    1. //将入参发送skywalking
    2. ActiveSpan.tag("input", sb.toString());
    3. //将返回值发送skywalking
    4. ActiveSpan.tag("output", responseBody);

    4.添加过滤器在过滤器中发送到skywalking

    因为HttpServletRequestHttpServletResponse中的body只能读取一次,如果在Filte中读取的话,应用本身就读取不到,所以需要使用ContentCachingRequestWrapperContentCachingResponseWrapper,所以需要添加一个过滤器即可

    1. import java.io.IOException;
    2. import java.nio.charset.StandardCharsets;
    3. import java.util.Enumeration;
    4. import java.util.Set;
    5. import java.util.stream.Collectors;
    6. import javax.servlet.FilterChain;
    7. import javax.servlet.ServletException;
    8. import javax.servlet.http.HttpFilter;
    9. import javax.servlet.http.HttpServletRequest;
    10. import javax.servlet.http.HttpServletResponse;
    11. import org.apache.skywalking.apm.toolkit.trace.ActiveSpan;
    12. import org.slf4j.Logger;
    13. import org.slf4j.LoggerFactory;
    14. import org.springframework.stereotype.Component;
    15. import org.springframework.util.StringUtils;
    16. import org.springframework.web.util.ContentCachingRequestWrapper;
    17. import org.springframework.web.util.ContentCachingResponseWrapper;
    18. import com.google.common.collect.ImmutableSet;
    19. @Component
    20. public class ApmHttpInfo extends HttpFilter {
    21. private Logger log = LoggerFactory.getLogger(getClass());
    22. private static final ImmutableSet IGNORED_HEADERS;
    23. static {
    24. Set ignoredHeaders = ImmutableSet.of("Content-Type", "User-Agent", "Accept", "Cache-Control",
    25. "Postman-Token", "Host", "Accept-Encoding", "Connection", "Content-Length").stream()
    26. .map(String::toUpperCase).collect(Collectors.toSet());
    27. IGNORED_HEADERS = ImmutableSet.copyOf(ignoredHeaders);
    28. }
    29. @Override
    30. public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
    31. throws IOException, ServletException {
    32. ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request);
    33. ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);
    34. try {
    35. filterChain.doFilter(requestWrapper, responseWrapper);
    36. } finally {
    37. try {
    38. // 构造请求信息: 比如 curl -X GET http://localhost:18080/getPerson?id=1 -H 'token:
    39. // me-token' -d '{ "name": "hello" }'
    40. // 构造请求的方法&URL&参数
    41. StringBuilder sb = new StringBuilder("curl").append(" -X ").append(request.getMethod()).append(" ")
    42. .append(request.getRequestURL().toString());
    43. if (StringUtils.hasLength(request.getQueryString())) {
    44. sb.append("?").append(request.getQueryString());
    45. }
    46. // 构造header
    47. Enumeration headerNames = request.getHeaderNames();
    48. while (headerNames.hasMoreElements()) {
    49. String headerName = headerNames.nextElement();
    50. if (!IGNORED_HEADERS.contains(headerName.toUpperCase())) {
    51. sb.append(" -H '").append(headerName).append(": ").append(request.getHeader(headerName))
    52. .append("'");
    53. }
    54. }
    55. // 获取body
    56. String body = new String(requestWrapper.getContentAsByteArray(), StandardCharsets.UTF_8);
    57. if (StringUtils.hasLength(body)) {
    58. sb.append(" -d '").append(body).append("'");
    59. }
    60. // 输出到input
    61. ActiveSpan.tag("input", sb.toString());
    62. // 获取返回值body
    63. String responseBody = new String(responseWrapper.getContentAsByteArray(), StandardCharsets.UTF_8);
    64. // 输出到output
    65. ActiveSpan.tag("output", responseBody);
    66. } catch (Exception e) {
    67. log.error("fail to build http log", e);
    68. } finally {
    69. // 这一行必须添加,否则就一直不返回
    70. responseWrapper.copyBodyToResponse();
    71. }
    72. }
    73. }
    74. }

  • 相关阅读:
    代码维护——本地仓与github建立连接
    【Linux】第十三章 多线程(线程互斥+线程安全和可重入+死锁+线程同步)
    贪吃蛇游戏
    【华为OD机试真题2023B卷 JAVA&JS】评论转换输出
    设f(x)=∑x^n/n^2,证明f(x)+f(1-x)+lnxln(1-x)=∑1/n^2
    Idea、VsCode、WebStorm常用插件
    亚马逊差评怎么删?常用的几种删差评方法介绍
    使用canvas做了一个最简单的网页版画板,5分钟学会
    免费发布web APP的四个途径(Python和R)
    面试题:说说Java并发运行中的一些安全问题
  • 原文地址:https://blog.csdn.net/weixin_44039105/article/details/135151811