API상태변화감시JOB api.status.if_id_로 시작하는 파라미터가 있는 경우 감시조건에 if_id 추가
eapim-admin CI / build (push) Waiting to run
eapim-admin CI / build (push) Waiting to run
This commit is contained in:
@@ -73,6 +73,9 @@ public interface ApiStatusRepository extends BaseRepository<ApiStatus, String> {
|
|||||||
+ " BETWEEN TO_CHAR(:delayRangeStart,'YYYYMMDDHH24MI')"
|
+ " BETWEEN TO_CHAR(:delayRangeStart,'YYYYMMDDHH24MI')"
|
||||||
+ " AND TO_CHAR(:rangeEnd,'YYYYMMDDHH24MI'))) AS DELAY_YN"
|
+ " AND TO_CHAR(:rangeEnd,'YYYYMMDDHH24MI'))) AS DELAY_YN"
|
||||||
+ " FROM TSEAIHE01 A LEFT OUTER JOIN API_STATUS B ON A.EAISVCNAME = B.EAISVCNAME"
|
+ " FROM TSEAIHE01 A LEFT OUTER JOIN API_STATUS B ON A.EAISVCNAME = B.EAISVCNAME"
|
||||||
|
// apiIdsProvided='N'이면 전체 API 대상(무조건 참), 'Y'면 apiIds로 좁힌다.
|
||||||
|
// (apiIds는 :apiIdsProvided='N'일 때도 항상 바인딩되어야 하므로 이 경우 호출측에서 더미 1건을 채워 보낸다)
|
||||||
|
+ " WHERE (:apiIdsProvided = 'N' OR A.EAISVCNAME IN (:apiIds))"
|
||||||
+ " )"
|
+ " )"
|
||||||
+ " ) A WHERE EVENT != 'STAY'")
|
+ " ) A WHERE EVENT != 'STAY'")
|
||||||
List<ApiStatusEvent> findApiStatusEvents(
|
List<ApiStatusEvent> findApiStatusEvents(
|
||||||
@@ -80,7 +83,9 @@ public interface ApiStatusRepository extends BaseRepository<ApiStatus, String> {
|
|||||||
@Param("delayAvgRespTime") int delayAvgRespTime,
|
@Param("delayAvgRespTime") int delayAvgRespTime,
|
||||||
@Param("errorRangeStart") LocalDateTime errorRangeStart,
|
@Param("errorRangeStart") LocalDateTime errorRangeStart,
|
||||||
@Param("delayRangeStart") LocalDateTime delayRangeStart,
|
@Param("delayRangeStart") LocalDateTime delayRangeStart,
|
||||||
@Param("rangeEnd") LocalDateTime rangeEnd
|
@Param("rangeEnd") LocalDateTime rangeEnd,
|
||||||
|
@Param("apiIdsProvided") String apiIdsProvided,
|
||||||
|
@Param("apiIds") Collection<String> apiIds
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,6 +118,23 @@ public interface ApiStatusRepository extends BaseRepository<ApiStatus, String> {
|
|||||||
@Param("modifiedBy") String modifiedBy,
|
@Param("modifiedBy") String modifiedBy,
|
||||||
@Param("modifiedDate") LocalDateTime modifiedDate);
|
@Param("modifiedDate") LocalDateTime modifiedDate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API 상태 변경 히스토리 적재. {@code claimStatusChange}로 선점에 성공한 실행에서만
|
||||||
|
* (즉 실제로 상태가 바뀐 건에 대해서만) 1행 기록한다.
|
||||||
|
*/
|
||||||
|
@Modifying
|
||||||
|
@Query(nativeQuery = true, value =
|
||||||
|
"INSERT INTO API_STATUS_HIST" +
|
||||||
|
" (HIST_SEQ, EAISVCNAME, STATUS_CODE, PREV_STATUS_CODE, JOBNAME, INSTANCENAME, CREATED_BY, CREATED_DATE)" +
|
||||||
|
" VALUES (API_STATUS_HIST_SEQ.NEXTVAL, :eaisvcname, :statusCode, :prevStatusCode, :jobName, :instanceName, :createdBy, :createdDate)")
|
||||||
|
void insertHistory(@Param("eaisvcname") String eaisvcname,
|
||||||
|
@Param("statusCode") String statusCode,
|
||||||
|
@Param("prevStatusCode") String prevStatusCode,
|
||||||
|
@Param("jobName") String jobName,
|
||||||
|
@Param("instanceName") String instanceName,
|
||||||
|
@Param("createdBy") String createdBy,
|
||||||
|
@Param("createdDate") LocalDateTime createdDate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 판정 구간에 트래픽이 있는 API 의 오류율·지연 판정값. 개발 모드(-Deai.systemmode=D) 진단 로그 전용.
|
* 판정 구간에 트래픽이 있는 API 의 오류율·지연 판정값. 개발 모드(-Deai.systemmode=D) 진단 로그 전용.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import java.net.UnknownHostException;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -69,7 +70,7 @@ public class ApiStatusService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void updateApiStatus(HashMap<String, String> param) {
|
public void updateApiStatus(HashMap<String, String> param, List<String> targetApiIds, String jobName) {
|
||||||
|
|
||||||
int errorRate = Integer.parseInt(param.get("errorRate"));
|
int errorRate = Integer.parseInt(param.get("errorRate"));
|
||||||
int errorRangeMinute = Integer.parseInt(param.get("errorRangeMinute"));
|
int errorRangeMinute = Integer.parseInt(param.get("errorRangeMinute"));
|
||||||
@@ -86,12 +87,18 @@ public class ApiStatusService {
|
|||||||
LocalDateTime errorRangeStart = rangeEnd.minusMinutes(errorRangeMinute);
|
LocalDateTime errorRangeStart = rangeEnd.minusMinutes(errorRangeMinute);
|
||||||
LocalDateTime delayRangeStart = rangeEnd.minusMinutes(delayRangeMinute);
|
LocalDateTime delayRangeStart = rangeEnd.minusMinutes(delayRangeMinute);
|
||||||
|
|
||||||
|
// targetApiIds가 비어있으면 전체 API 대상, 값이 있으면 그 API들로만 판정 대상을 좁힌다
|
||||||
|
// (JobDataMap의 api.status.if_id_ 로 시작하는 파라미터들의 값 - ApiStatusMonitorJob 참고)
|
||||||
|
boolean apiIdsProvided = targetApiIds != null && !targetApiIds.isEmpty();
|
||||||
|
|
||||||
List<ApiStatusEvent> list = apiStatusRepository.findApiStatusEvents(
|
List<ApiStatusEvent> list = apiStatusRepository.findApiStatusEvents(
|
||||||
errorRate,
|
errorRate,
|
||||||
delayAvgRespTime,
|
delayAvgRespTime,
|
||||||
errorRangeStart,
|
errorRangeStart,
|
||||||
delayRangeStart,
|
delayRangeStart,
|
||||||
rangeEnd
|
rangeEnd,
|
||||||
|
apiIdsProvided ? "Y" : "N",
|
||||||
|
apiIdsProvided ? targetApiIds : Collections.singletonList("")
|
||||||
);
|
);
|
||||||
|
|
||||||
HashMap<String, List<String>> eventMap = new HashMap<>();
|
HashMap<String, List<String>> eventMap = new HashMap<>();
|
||||||
@@ -110,6 +117,15 @@ public class ApiStatusService {
|
|||||||
|
|
||||||
log.debug("API 상태 변경: {}-{} {} → {}", event.getEaisvcname(), event.getEaisvcdesc(), event.getEvent(), newStatusCode);
|
log.debug("API 상태 변경: {}-{} {} → {}", event.getEaisvcname(), event.getEaisvcdesc(), event.getEvent(), newStatusCode);
|
||||||
|
|
||||||
|
// API 상태 변경 히스토리 적재 (선점에 성공한 실행에서만 - 실제 상태 전이 1건당 1행)
|
||||||
|
apiStatusRepository.insertHistory(
|
||||||
|
event.getEaisvcname(),
|
||||||
|
newStatusCode,
|
||||||
|
event.getPrevStatusCode(),
|
||||||
|
jobName,
|
||||||
|
System.getProperty("inst.Name"),
|
||||||
|
"SCHEDULER",
|
||||||
|
LocalDateTime.now());
|
||||||
|
|
||||||
//이벤트별로 api분리 저장
|
//이벤트별로 api분리 저장
|
||||||
List<String> apis = (List<String>)eventMap.get(event.getEvent());
|
List<String> apis = (List<String>)eventMap.get(event.getEvent());
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package com.eactive.eai.rms.ext.djb.job;
|
package com.eactive.eai.rms.ext.djb.job;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -39,6 +41,8 @@ import com.eactive.eai.rms.onl.common.util.DateUtil;
|
|||||||
* <b>api.status.error.rate</b>: API 장애기준 오류건수 비율(%) (단위: 시간, 기본값: 100)
|
* <b>api.status.error.rate</b>: API 장애기준 오류건수 비율(%) (단위: 시간, 기본값: 100)
|
||||||
* <b>api.status.delay.range_minute</b>: API 지연기준 판단 시간간격 (단위: 분, 기본값: 1)
|
* <b>api.status.delay.range_minute</b>: API 지연기준 판단 시간간격 (단위: 분, 기본값: 1)
|
||||||
* <b>api.status.delay.avg_resp_time</b>: API 지연기준 평균응답시간 (단위: 밀리세컨드, 기본값: 10000)
|
* <b>api.status.delay.avg_resp_time</b>: API 지연기준 평균응답시간 (단위: 밀리세컨드, 기본값: 10000)
|
||||||
|
* <b>api.status.if_id_*</b>: 판정 대상 API ID(인터페이스ID). 여러 개면 접두사가 같은 키를
|
||||||
|
* 여러 개 등록(api.status.if_id_1, api.status.if_id_2, ...). 미등록 시 전체 API 대상.
|
||||||
* </li>
|
* </li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
@@ -64,7 +68,15 @@ public class ApiStatusMonitorJob implements Job {
|
|||||||
|
|
||||||
/** Job 파라미터 키: API 지연기준 평균응답시간(ms) */
|
/** Job 파라미터 키: API 지연기준 평균응답시간(ms) */
|
||||||
public static final String KEY_API_STATUS_DELAY_AVG_RESP_TIME = "api.status.delay.avg_resp_time";
|
public static final String KEY_API_STATUS_DELAY_AVG_RESP_TIME = "api.status.delay.avg_resp_time";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Job 파라미터 키 접두사: 판정 대상 API ID(인터페이스ID) 목록.
|
||||||
|
* JobDataMap은 배열을 담을 수 없어, 이 접두사로 시작하는 키를 여러 개 등록하면
|
||||||
|
* (예: api.status.if_id_1, api.status.if_id_2, ...) 그 값들을 모아 배열로 취급한다.
|
||||||
|
* 값이 하나도 없으면(=전체 등록 안 함) 기존처럼 전체 API가 판정 대상이다.
|
||||||
|
*/
|
||||||
|
public static final String KEY_API_STATUS_IF_ID_PREFIX = "api.status.if_id_";
|
||||||
|
|
||||||
public static final String DEFAULT_ERROR_RANGE_MINUTE = "1";
|
public static final String DEFAULT_ERROR_RANGE_MINUTE = "1";
|
||||||
public static final String DEFAULT_ERROR_RATE = "100";
|
public static final String DEFAULT_ERROR_RATE = "100";
|
||||||
public static final String DEFAULT_DELAY_RANGE_MINUTE = "1";
|
public static final String DEFAULT_DELAY_RANGE_MINUTE = "1";
|
||||||
@@ -96,6 +108,11 @@ public class ApiStatusMonitorJob implements Job {
|
|||||||
|
|
||||||
HashMap<String, String> param = this.checkParameters(jobDataMap);
|
HashMap<String, String> param = this.checkParameters(jobDataMap);
|
||||||
|
|
||||||
|
//다른 조건으로 특정 API들을 감시하기 위해 Job을 다른이름으로 등록하여 추가로 감시한다.
|
||||||
|
//파라미터에 api.status.if_id_(n)=ASCORBED000S1 을 필요한 만큼 추가한다(최대 500개)
|
||||||
|
List<String> apiIds = this.collectApiIds(jobDataMap);
|
||||||
|
String jobName = context.getJobDetail().getKey().getName();
|
||||||
|
|
||||||
|
|
||||||
ApplicationContext appContext;
|
ApplicationContext appContext;
|
||||||
try {
|
try {
|
||||||
@@ -111,7 +128,7 @@ public class ApiStatusMonitorJob implements Job {
|
|||||||
DataSourceContextHolder.setDataSourceType(
|
DataSourceContextHolder.setDataSourceType(
|
||||||
DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.APIGW));
|
DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.APIGW));
|
||||||
try {
|
try {
|
||||||
apiStatusUpdateService.updateApiStatus(param);
|
apiStatusUpdateService.updateApiStatus(param, apiIds, jobName);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("ApiStatusUpdateJob execution failed", e);
|
log.error("ApiStatusUpdateJob execution failed", e);
|
||||||
@@ -184,6 +201,33 @@ public class ApiStatusMonitorJob implements Job {
|
|||||||
return param;
|
return param;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* KEY_API_STATUS_IF_ID_PREFIX(api.status.if_id_)로 시작하는 Job 파라미터들의 값을 모아
|
||||||
|
* 판정 대상 API ID 목록을 만든다. JobDataMap은 배열을 지원하지 않아 접두사 붙은 키를
|
||||||
|
* 여러 개 등록하는 방식으로 배열을 흉내낸다. 값이 없으면(=아무 키도 등록 안 함) 빈 리스트를
|
||||||
|
* 반환하며, 이 경우 {@code ApiStatusService.updateApiStatus}는 전체 API를 판정 대상으로 삼는다.
|
||||||
|
*/
|
||||||
|
private List<String> collectApiIds(JobDataMap jobDataMap) {
|
||||||
|
List<String> apiIds = new ArrayList<>();
|
||||||
|
|
||||||
|
if (jobDataMap == null) {
|
||||||
|
return apiIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String key : jobDataMap.getKeys()) {
|
||||||
|
if (!key.startsWith(KEY_API_STATUS_IF_ID_PREFIX)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String value = jobDataMap.getString(key);
|
||||||
|
if (StringUtils.isNotBlank(value)) {
|
||||||
|
apiIds.add(value.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return apiIds;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 개발 모드 여부 확인
|
* 개발 모드 여부 확인
|
||||||
* @return eai.systemmode=D 이면 true
|
* @return eai.systemmode=D 이면 true
|
||||||
|
|||||||
Reference in New Issue
Block a user