JIRAを監視するためのカスタムアクチュエータエンドポイントの作成方法


スプリングブートアクチュエーターを使用すると、アプリケーションを監視するためのエンドポイントのセットを提供しますが、特定のメトリックを取得するカスタムエンドポイントを作成する必要があります.
カスタムエンドポイントを行うには2つの方法があります.
@ 56569182による
  • カスタム終点
  • コントローラの終了点を@ restcontroller erpointで指定します.
    我々は、2番目のものだけを見ます.
  • この例では、アプリケーションのカスタムエンドポイントを作成しませんが、外部でホストされているJIRAサーバーを監視します.確かに我々は、それがUPかダウンかを知っている必要がありますどのように多くの時間は、応答を返すために費やす.
    次の依存関係が必要になります.
    dependencies {
        implementation 'org.springframework.boot:spring-boot-starter-actuator'
        implementation "org.springframework.boot:spring-boot-starter-web"
        implementation "org.springframework.boot:spring-boot-starter-security"
        implementation 'org.springframework.boot:spring-boot-starter-tomcat'
        implementation group: 'com.konghq', name: 'unirest-java', version: '3.11.06'
        implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.11.3'
        implementation 'org.springframework.boot:spring-boot-starter-validation'
        implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.5.0'
        implementation group: 'org.springdoc', name: 'springdoc-openapi-data-rest', version: '1.5.0'
        }
    
    ここでは、我々のアプリケーション.アクチュエータとJIRAサーバーの接続プロパティーを持つYMLファイル
    management:
      endpoints:
        web:
          exposure:
              include: '*'
          base-path: "/management"
      security:
        enabled: false
    
      endpoint:
        health:
          show-details: always
    
    app:
      config:
        jira:
          host: "https://myjiraserver"
          user: "jiraUser"
          password: "jirapwd"
          api-path: "/rest/api/2"
    
    Java設定クラスでJIRAプロパティをマップしました.
    @Component
    @ConfigurationProperties("app.config.jira")
    @Validated
    public class JiraConfig {
    
        @NotEmpty
        protected String host;
        @NotEmpty
        protected String user;
        @NotEmpty
        protected String password;
        @NotEmpty
        protected String apiPath;
    
    
        public String getHost() {
            return host;
        }
    
        public void setHost(String host) {
            this.host = host;
        }
    
        public String getUser() {
            return user;
        }
    
        public void setUser(String user) {
            this.user = user;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public String getApiPath() {
            return apiPath;
        }
    
        public void setApiPath(String apiPath) {
            this.apiPath = apiPath;
        }
    }
    
    次に、JIRAエンドポイントを呼び出し、応答時間を指定します.
    @Service
    public class JiraConnectorService {
    
        private static final Logger logger = LoggerFactory.getLogger(JiraConnectorService.class);
        public static final String HEADER_ACCEPT = "accept";
        public static final String HEADER_APP_JSON = "application/json";
        public static final String JIRA_MYSELF_ENDPOINT = "/myself";
    
        private JiraConfig jiraConfig;
    
        @Autowired
        public void setJiraConfig(JiraConfig jiraConfig) {
            this.jiraConfig = jiraConfig;
        }
    
        public ResponseTimeData getResponseTime() throws UnirestException {
            logger.info("Get responseTime info");
            String mySelfEndPointUrl = jiraConfig.getHost() + jiraConfig.getApiPath() + JIRA_MYSELF_ENDPOINT;
    
            logger.info("Call {}", mySelfEndPointUrl);
            ResponseTimeData data = new ResponseTimeData();
            long start = System.currentTimeMillis();
    
            HttpResponse<JsonNode> jsonResponse = Unirest.get(mySelfEndPointUrl)
                    .basicAuth(jiraConfig.getUser(), jiraConfig.getPassword())
                    .header(HEADER_ACCEPT, HEADER_APP_JSON)
                    .asJson();
    
            data.setTime(System.currentTimeMillis() - start);
            data.setHttpStatusCode(jsonResponse.getStatus());
            data.setMessage(jsonResponse.getStatusText());
    
            logger.info("Call {} successfull", mySelfEndPointUrl);
            return data;
        }
    }
    
    データモデル
    public class ResponseTimeData {
    
        private long time;
        private int httpStatusCode;
        private String message;
    
    
        public long getTime() {
            return time;
        }
    
        public void setTime(long time) {
            this.time = time;
        }
    
        public int getHttpStatusCode() {
            return httpStatusCode;
        }
    
        public void setHttpStatusCode(int httpStatusCode) {
            this.httpStatusCode = httpStatusCode;
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    }
    
    public class HealthDtl {
    
        protected String status;
        private int httpStatusCode;
        private String message;
        private Long responseTimeMs;
    
        public String getStatus() {
            return status;
        }
    
        public void setStatus(String status) {
            this.status = status;
        }
    
        public int getHttpStatusCode() {
            return httpStatusCode;
        }
    
        public void setHttpStatusCode(int httpStatusCode) {
            this.httpStatusCode = httpStatusCode;
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        public Long getResponseTimeMs() {
            return responseTimeMs;
        }
    
        public void setResponseTimeMs(Long responseTimeMs) {
            this.responseTimeMs = responseTimeMs;
        }
    }
    
    そして今、カスタム残りのエンドポイント!
    @Component
    @RestControllerEndpoint(id = "jira")
    public class RestJiraEndPoint {
    
        private static final Logger logger = LoggerFactory.getLogger(RestJiraEndPoint.class);
    
        private final JiraConnectorService jiraConnectorService;
    
        public RestJiraEndPoint(JiraConnectorService jiraConnectorService, MessageSource messageSource){
            this.jiraConnectorService = jiraConnectorService;
        }
    
    
        @GetMapping("/healthDtl")
        @ResponseBody
        public ResponseEntity<HealthDtl> healthDtl() {
            logger.info("/jira/healthDtl endpoint called");
    
            HealthDtl health = new HealthDtl();
            ResponseTimeData data = new ResponseTimeData();
            try {
                data = jiraConnectorService.getResponseTime();
                if(data.getHttpStatusCode() == HttpStatus.OK.value())
                    health.setStatus("UP");
                else
                    health.setStatus("DOWN");
                health.setMessage(data.getMessage());
                health.setResponseTimeMs(data.getTime());
            } catch (UnirestException e) {
                logger.error(e.getLocalizedMessage(), e);
                health.setStatus("DOWN");
                health.setMessage(e.getMessage());
            }
            health.setHttpStatusCode(data.getHttpStatusCode());
    
            return new ResponseEntity<>(health, HttpStatus.OK);
        }
    }
    
    現在、新しいアクチュエータのエンドポイント/管理/JIRA/HealthDTLがあります.
    {
    "status":"UP",
    "httpStatusCode":200,
    "message":"",
    "responseTimeMs":369
    }
    
    私は、このカスタム・アクチュエータ終点を単体テストする方法に新しいポストを加えます.