环境:SpringBoot2.7.18
项目中监控记录接口请求的相关信息是一个至关重要的环节,它对于提升系统稳定性、优化性能、快速定位问题以及保障数据安全等方面都起着至关重要的作用。大致可概况如下几方面:
问题追踪与定位:当系统出现错误或异常时,通过查看接口调用的请求信息,可以快速定位问题发生的源头。比如,通过查看请求参数、响应状态码、执行时间等
性能优化:监控接口请求的处理时间、响应时间性能指标,可以帮助开发团队了解系统的瓶颈所在,从而进行相应的优化。
用户行为分析:通过记录用户的请求信息,包括请求频率、请求时间、请求参数等,可以对用户行为进行分析,了解用户的使用习惯和需求,从而优化产品功能和用户体验。
安全审计:记录接口请求信息也是安全审计的一部分。通过监控和分析请求数据,可以发现潜在的安全威胁,如恶意请求、SQL注入、跨站脚本攻击等
在SpringBoot中我们可通过Actuator来实现对Http接口进行监控记录,接下来我们通过实操来演示如何通过Actuator来监控记录我们的即可。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId></dependency>
要使用Actuator的http接口监控功能,你还需要注册一个HttpTraceRepository类型的Bean,Actuator默认提供的是基于内存的实现
@Configurationpublic class HttpActuatorConfig { @Bean InMemoryHttpTraceRepository inMemoryHttpTraceRepository() { return new InMemoryHttpTraceRepository() ; }}
默认情况下,Actuator只开启了health接口(健康检查),我们还需要手动开启httptrace接口。
management: endpoints: web: exposure: include: httptrace
以上配置后,可以通过/actuator接口查看是否开启了httptrace接口
成功开启
@RestController@RequestMapping("/users")public class UserController { private static List<User> DATAS = new ArrayList<>() ; static { DATAS.add(new User(1L, "张三", 22)) ; DATAS.add(new User(2L, "李四", 32)) ; DATAS.add(new User(3L, "王五", 33)) ; DATAS.add(new User(4L, "赵六", 26)) ; DATAS.add(new User(5L, "田七", 29)) ; DATAS.add(new User(6L, "嘿哈", 44)) ; } @PostMapping("") public ResponseEntity<Void> save(@RequestBody User user) { DATAS.add(user) ; return ResponseEntity.created(URI.create(String.format("/users/%s", user.getId()))).build() ; } @DeleteMapping("/{id}") public ResponseEntity<Void> delete(@PathVariable("id") Long id) { DATAS.removeIf(user -> user.getId() == id) ; return ResponseEntity.noContent().build() ; } @PutMapping("") public ResponseEntity<Void> update(@RequestBody User user) { DATAS.stream() .filter(u -> u.getId() == user.getId()) .findFirst() .ifPresent(u -> { u.setAge(user.getAge()) ; u.setName(u.getName()) ; }); return ResponseEntity.noContent().build() ; } @GetMapping("") public ResponseEntity<List<User>> list() { return ResponseEntity.ok(DATAS) ; } @GetMapping("/{id}") public ResponseEntity<User> get(@PathVariable("id") Long id) { return ResponseEntity.ok(DATAS.stream() .filter(u -> u.getId() == id) .findFirst().orElse(null) ) ; } // 测试异常情况 @GetMapping("/exception") public ResponseEntity<Void> exce() { System.out.println(1 / 0) ; return ResponseEntity.noContent().build() ; }}
为了简单,上面操作都是基于内存数据进行。包括了CRUD及异常情况。
访问上面定义的任意接口之后通过/actuator/httptrace接口查看访问情况
图片
每个接口会详细的记录请求的URL,header,响应状态码及header信息。上图中的timeTaken属性记录的是该接口请求的耗时情况(单位:毫秒)。
通过以上的示例演示,使用Actuator监控接口还是非常简单的,你只需要做简单的配置即可,接下来继续介绍更多的配置及使用。
要自定义记录的信息,可以通过如下配置
management: trace: http: include: - time-taken - response-headers
注:在SpringBoot3以上的版本这里的配置发生了变化使用的是如下配置:
management: httpexchanges: recording: include: - time-taken
通过上面的配置后,再次访问接口
图片
此时,将不再包含请求headers。还支持如下的配置:
图片
在项目中你可以通过 HttpTraceRepository 获取所有请求中的请求-响应交换信息。如下示例,获取所有错误的请求(状态码为500)。
private final HttpTraceRepository httpTraceRepository ;public HttpController(HttpTraceRepository httpTraceRepository) { this.httpTraceRepository = httpTraceRepository ;}@GetMapping("/{status}")public Object info(@PathVariable("status") Integer status) { return httpTraceRepository.findAll() .stream() .filter(trace -> trace.getResponse().getStatus() == status) .collect(Collectors.toList()) ;}
通过上面的接口,我们可以过滤指定状态码的请求信息。
InMemoryHttpExchangeRepository,默认情况下,它会存储最近 100 次请求-响应信息,并且是内存级的。所以如果你需要在生产环境下使用还是建议你自定义HttpTraceRepository实现,将信息存入到Redis或者是ES中。如下存入Redis示例
@Componentpublic class PackHttpTraceRepository implements HttpTraceRepository { private static final String HTTP_TRACE_KEY = "http_request_response" ; private final StringRedisTemplate stringRedisTemplate ; public PackHttpTraceRepository(StringRedisTemplate stringRedisTemplate) { this.stringRedisTemplate = stringRedisTemplate ; } @Override public List<HttpTrace> findAll() { return this.stringRedisTemplate.opsForList().range(HTTP_TRACE_KEY, 0, -1).stream().map(json -> { try { return objectMapper.readValue(json, HttpTrace.class); } }).collect(Collectors.toList()) ; } @Override public void add(HttpTrace trace) { String json = null ; try { json = objectMapper.writeValueAsString(trace) ; } this.stringRedisTemplate.opsForList().leftPush(HTTP_TRACE_KEY, json) ; }}
这样我们就可以持久化存储数据了,你还可以根据当前日期来进行存储。
本文链接:http://www.28at.com/showinfo-26-98864-0.htmlSpringBoot自带Controller接口监控,赶紧用起来
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com