인프런 커뮤니티 질문&답변

SeJongDeveloper님의 프로필 이미지
SeJongDeveloper

작성한 질문수

Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)

Micrometer 구현

/actuator/metrics 에서 names 값에 대한 질문

작성

·

457

·

수정됨

0

스프링 부트 버전 : 3.2.2

JDK : 17

 

spring cloud gateway 를 사용하여
127.0.0.1:8000/user-service/welcome,

127.0.0.1:8000/user-service/heath_check

주소를 호출했습니다.

http://127.0.0.1:8000/user-service/actuator/prometheus 를 호출결과 중 일부입니다.

# HELP http_server_requests_seconds  
# TYPE http_server_requests_seconds summary
http_server_requests_seconds_count{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/heath_check",} 5.0
http_server_requests_seconds_sum{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/heath_check",} 0.020372399
http_server_requests_seconds_count{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/actuator/prometheus",} 1.0
http_server_requests_seconds_sum{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/actuator/prometheus",} 0.8039679
http_server_requests_seconds_count{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/actuator/health",} 1.0
http_server_requests_seconds_sum{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/actuator/health",} 0.0116107
http_server_requests_seconds_count{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/welcome",} 3.0
http_server_requests_seconds_sum{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/welcome",} 3.827017999
http_server_requests_seconds_count{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/actuator/metrics",} 8.0
http_server_requests_seconds_sum{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/actuator/metrics",} 0.039744298
http_server_requests_seconds_count{error="none",exception="none",method="GET",outcome="CLIENT_ERROR",status="404",uri="/**",} 1.0
http_server_requests_seconds_sum{error="none",exception="none",method="GET",outcome="CLIENT_ERROR",status="404",uri="/**",} 0.014729801
http_server_requests_seconds_count{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/actuator/info",} 1.0
http_server_requests_seconds_sum{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/actuator/info",} 0.090424499
# HELP http_server_requests_seconds_max  
# TYPE http_server_requests_seconds_max gauge
http_server_requests_seconds_max{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/heath_check",} 0.003873199
http_server_requests_seconds_max{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/actuator/prometheus",} 0.8039679
http_server_requests_seconds_max{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/actuator/health",} 0.0
http_server_requests_seconds_max{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/welcome",} 0.0
http_server_requests_seconds_max{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/actuator/metrics",} 0.0
http_server_requests_seconds_max{error="none",exception="none",method="GET",outcome="CLIENT_ERROR",status="404",uri="/**",} 0.0
http_server_requests_seconds_max{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/actuator/info",} 0.0


http://localhost:8000/user-service/actuator/metrics 를 호출결과 names 배열값에
강의화면과 다르게 users.welcome, users.status 값이 없습니다.

 

pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>
<dependency>
    <groupId>io.zipkin.reporter2</groupId>
    <artifactId>zipkin-reporter-brave</artifactId>
</dependency>
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-micrometer</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifactId>
    <version>2.2.8.RELEASE</version>
</dependency>

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

 

application.yml

management:
  endpoints:
    web:
      exposure:
        include: refresh, health, beans, busrefresh, info, metrics, prometheus
  tracing:
    sampling:
      probability: 1.0
    propagation:
      consume: b3
      produce: b3
  zipkin:
    tracing:
      endpoint: "http://localhost:9411/api/v2/spans"

 

controller.java

package com.example.userservice.controller;

import com.example.userservice.dto.UserDto;
import com.example.userservice.jpa.UserEntity;
import com.example.userservice.service.UserService;
import com.example.userservice.vo.Greeting;
import com.example.userservice.vo.RequestUser;
import com.example.userservice.vo.ResponseUser;
import io.micrometer.core.annotation.Timed;
import org.modelmapper.ModelMapper;
import org.modelmapper.convention.MatchingStrategies;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@RestController
public class UserController {
    private Environment env;
    private UserService userService;

    @Autowired
    private Greeting greeting;

    public UserController(Environment env, UserService userService) {
        this.env = env;
        this.userService = userService;
    }

    @GetMapping("/heath_check")
    @Timed(value = "users.status", longTask = true)
    public String status() {
        return String.format("It's Working in User Service "
            + ", port(local.server.port)=" + env.getProperty("local.server.port")
            + ", port(server.port)=" + env.getProperty("server.port")
            + ", port(token.secret)=" + env.getProperty("token.secret")
            + ", port(token.expiration_time)=" + env.getProperty("token.expiration_time")
        );
    }

    @GetMapping("/welcome")
    @Timed(value = "users.welcome", longTask = true)
    public String welcome() {
//        return env.getProperty("greeting.message");
        return greeting.getMessage();
    }

    @PostMapping("/users")
    public ResponseEntity<ResponseUser> createUser(@RequestBody RequestUser user) {
        ModelMapper mapper = new ModelMapper();
        mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);

        UserDto userDto = mapper.map(user, UserDto.class);
        userService.createUser(userDto);

        ResponseUser responseUser = mapper.map(userDto, ResponseUser.class);

        return ResponseEntity.status(HttpStatus.CREATED).body(responseUser);
    }

    @GetMapping("/users")
    public ResponseEntity<List<ResponseUser>> getUsers() {
        Iterable<UserEntity> userList = userService.getUserByAll();

        List<ResponseUser> result = new ArrayList<>();
        userList.forEach(v -> {
            result.add(new ModelMapper().map(v, ResponseUser.class));
        });

        return ResponseEntity.status(HttpStatus.OK).body(result);
    }

    @GetMapping("/users/{userId}")
    public ResponseEntity<ResponseUser> getUser(@PathVariable String userId) {
        UserDto userDto = userService.getUserById(userId);

        ResponseUser returnValue = new ModelMapper().map(userDto, ResponseUser.class);

        return ResponseEntity.status(HttpStatus.OK).body(returnValue);
    }
}

답변 1

0

안녕하세요, 인프런 AI 인턴입니다.

/actuator/metrics에서 users.welcomeusers.status 항목이 없는 경우는 @Timed 애노테이션이 적용된 메서드의 메트릭이 노출되지 않았을 가능성이 있습니다. @Timed를 사용하셨으나 Micrometer로 측정된 메트릭이 actuator/metrics에서 보이지 않는다면 다음의 사항들을 확인해보시길 권장드립니다:

  1. @Timed 애노테이션이 정확히 적용되었는지 확인해주세요.

    • @Timed(value = "users.status", longTask = true)와 같이 적용되어야 합니다.
  2. 의존성 문제가 있을 수 있으니, pom.xml에 정의된 의존성이 올바르게 추가되었는지 다시 확인해보시기 바랍니다.

  3. 메트릭 측정을 위한 MeterRegistry의 빈(bean)이 올바르게 설정되었는지 검토해보세요.

  4. 스프링 부트 버전과 실제 코드에서 사용하는 애노테이션 및 기능들이 호환되는지 확인해보세요.

    • 예를 들어, 스프링 부트 버전이 정확히 3.2.2인지, 본문에 제공된 정보는 3.1.5 기준이기 때문에 약간의 차이가 있을 수 있습니다.
  5. 설정 파일(application.yml 혹은 properties)에 메트릭 관련 설정을 올바르게 적용했는지 검토하세요.

  6. 어플리케이션이 적절히 기동되어 @Timed 애노테이션이 적용된 메서드가 호출되었는지 확인해보세요. 메서드 호출 없이는 해당 메트릭 값들이 측정되지 않습니다.

  7. 마지막으로, 해당 문제가 여전히 해결되지 않는다면 스프링 부트 및 Actuator의 자세한 로깅을 활성화하여 문제를 진단해볼 수 있습니다.

이와 관련된 상세 내용은 Spring Boot Reference Documentation를 참고하여 도움을 받을 수 있습니다. 원하시는 메트릭이 정확히 노출되도록 설정하는 데 필요한 지침이 포함되어 있을 것입니다.

감사합니다.

SeJongDeveloper님의 프로필 이미지
SeJongDeveloper

작성한 질문수

질문하기