Merge branch 'jenkins_with_weblogic' of ssh://192.168.240.178:18081/eapim/eapim-admin into jenkins_with_weblogic
This commit is contained in:
@@ -144,9 +144,9 @@
|
|||||||
rowNum: -1,
|
rowNum: -1,
|
||||||
// rowList: [10, 20, 30],
|
// rowList: [10, 20, 30],
|
||||||
// pager: '#selectedApiGridPager',
|
// pager: '#selectedApiGridPager',
|
||||||
sortname: 'apiId',
|
// sortname: 'apiId',
|
||||||
viewrecords: true,
|
viewrecords: true,
|
||||||
sortorder: "asc",
|
// sortorder: "asc",
|
||||||
caption: "선택된 API",
|
caption: "선택된 API",
|
||||||
height: 200,
|
height: 200,
|
||||||
autowidth: true,
|
autowidth: true,
|
||||||
|
|||||||
@@ -201,7 +201,7 @@
|
|||||||
const isOutboundWithoutNet = !json.PSVSYSADPTRBZWKGROUPNAME.includes('NET');
|
const isOutboundWithoutNet = !json.PSVSYSADPTRBZWKGROUPNAME.includes('NET');
|
||||||
fullMessageData = json.FULLMESSAGEDATA;
|
fullMessageData = json.FULLMESSAGEDATA;
|
||||||
layoutInfo = json.standardHeader;
|
layoutInfo = json.standardHeader;
|
||||||
bzwkdatatntInfo = json.BZWKDATATNT;
|
bzwkdatatntInfo = json.BZWKDATACTNT;
|
||||||
|
|
||||||
if((isInboundPart && isInboundWithoutNet) || (isOutboundPart && isOutboundWithoutNet)){
|
if((isInboundPart && isInboundWithoutNet) || (isOutboundPart && isOutboundWithoutNet)){
|
||||||
selectHttpLog(url, prcsDate, json.EAISVCSERNO.trim(), logPrcssSerno);
|
selectHttpLog(url, prcsDate, json.EAISVCSERNO.trim(), logPrcssSerno);
|
||||||
|
|||||||
+21
-47
@@ -8,6 +8,12 @@ import java.util.stream.Collectors;
|
|||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.PersistenceContext;
|
import javax.persistence.PersistenceContext;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.PageImpl;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import com.eactive.eai.data.entity.onl.logger.EAILog;
|
import com.eactive.eai.data.entity.onl.logger.EAILog;
|
||||||
import com.eactive.eai.data.entity.onl.logger.EAILogId;
|
import com.eactive.eai.data.entity.onl.logger.EAILogId;
|
||||||
import com.eactive.eai.data.entity.onl.logger.QEAILog;
|
import com.eactive.eai.data.entity.onl.logger.QEAILog;
|
||||||
@@ -20,12 +26,6 @@ import com.querydsl.core.types.dsl.EntityPathBase;
|
|||||||
import com.querydsl.jpa.impl.JPAQuery;
|
import com.querydsl.jpa.impl.JPAQuery;
|
||||||
import com.querydsl.jpa.impl.JPAQueryFactory;
|
import com.querydsl.jpa.impl.JPAQueryFactory;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.data.domain.Page;
|
|
||||||
import org.springframework.data.domain.PageImpl;
|
|
||||||
import org.springframework.data.domain.Pageable;
|
|
||||||
import org.springframework.stereotype.Repository;
|
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
public class EAILogRepositoryImpl implements EAILogRepository {
|
public class EAILogRepositoryImpl implements EAILogRepository {
|
||||||
|
|
||||||
@@ -43,43 +43,26 @@ public class EAILogRepositoryImpl implements EAILogRepository {
|
|||||||
EntityPathBase<?> entityPathBase = new EntityPathBase<>(clazz, qeaiLog.getMetadata().getName());
|
EntityPathBase<?> entityPathBase = new EntityPathBase<>(clazz, qeaiLog.getMetadata().getName());
|
||||||
|
|
||||||
QEAIMessageEntity qeaiMessageEntity = QEAIMessageEntity.eAIMessageEntity;
|
QEAIMessageEntity qeaiMessageEntity = QEAIMessageEntity.eAIMessageEntity;
|
||||||
|
|
||||||
// Count Query
|
|
||||||
JPAQuery<?> countQuery = new JPAQueryFactory(em)
|
|
||||||
.from(entityPathBase)
|
|
||||||
.leftJoin(qeaiMessageEntity)
|
|
||||||
.on(qeaiLog.eaisvcname.eq(qeaiMessageEntity.eaisvcname));
|
|
||||||
|
|
||||||
appendConditions(eaiLogSearch, qeaiLog, entityPathBase, qeaiMessageEntity, countQuery);
|
|
||||||
|
|
||||||
long totalCount = countQuery.select(qeaiLog.id.msgdpstyms.count()).fetchOne();
|
JPAQuery<?> query = new JPAQueryFactory(em).from(entityPathBase);
|
||||||
|
appendConditions(eaiLogSearch, qeaiLog, entityPathBase, query);
|
||||||
|
|
||||||
|
long totalCount = query.select(qeaiLog.id.msgdpstyms.count()).fetchOne();
|
||||||
|
|
||||||
if (totalCount == 0) {
|
if (totalCount == 0) {
|
||||||
return new PageImpl<>(new ArrayList<>(), pageable, 0);
|
return new PageImpl<>(new ArrayList<>(), pageable, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// List Query 분리
|
|
||||||
JPAQuery<?> listQuery = new JPAQueryFactory(em)
|
|
||||||
.from(entityPathBase)
|
|
||||||
.leftJoin(qeaiMessageEntity)
|
|
||||||
.on(qeaiLog.eaisvcname.eq(qeaiMessageEntity.eaisvcname));
|
|
||||||
|
|
||||||
List<EAILogDto> list = listQuery
|
List<EAILogDto> list = query
|
||||||
// .select(Projections.constructor(EAILogDto.class, qeaiLog, qeaiMessageEntity.eaisvcdesc))
|
// .select(Projections.constructor(EAILogDto.class, qeaiLog, qeaiMessageEntity.eaisvcdesc))
|
||||||
.select(Projections.constructor(EAILogDto.class,
|
.select(Projections.constructor(EAILogDto.class,
|
||||||
qeaiLog.id,
|
qeaiLog.id, qeaiLog.trackasiskey1ctnt, qeaiLog.trackasiskey2ctnt, qeaiLog.keymgtmsgctnt,
|
||||||
qeaiLog.trackasiskey1ctnt,
|
qeaiLog.eaisvcname, qeaiLog.extbizcd, qeaiLog.refkey, qeaiLog.clientname,
|
||||||
qeaiLog.trackasiskey2ctnt,
|
qeaiLog.orgname, qeaiLog.msgprcssyms, qeaiLog.companycode, qeaiLog.eaierrctnt,
|
||||||
qeaiLog.keymgtmsgctnt,
|
|
||||||
qeaiLog.eaisvcname,
|
|
||||||
qeaiLog.extbizcd,
|
|
||||||
qeaiLog.refkey,
|
|
||||||
qeaiLog.clientname,
|
|
||||||
qeaiLog.orgname,
|
|
||||||
qeaiLog.msgprcssyms,
|
|
||||||
qeaiLog.companycode,
|
|
||||||
qeaiLog.eaierrctnt,
|
|
||||||
qeaiMessageEntity.eaisvcdesc))
|
qeaiMessageEntity.eaisvcdesc))
|
||||||
|
.from(entityPathBase)
|
||||||
|
.leftJoin(qeaiMessageEntity)
|
||||||
|
.on(qeaiLog.eaisvcname.eq(qeaiMessageEntity.eaisvcname))
|
||||||
.orderBy(qeaiLog.id.msgdpstyms.desc(), qeaiLog.id.eaisvcserno.asc(), qeaiLog.id.logprcssserno.asc())
|
.orderBy(qeaiLog.id.msgdpstyms.desc(), qeaiLog.id.eaisvcserno.asc(), qeaiLog.id.logprcssserno.asc())
|
||||||
.limit(1000)
|
.limit(1000)
|
||||||
.fetch();
|
.fetch();
|
||||||
@@ -90,15 +73,9 @@ public class EAILogRepositoryImpl implements EAILogRepository {
|
|||||||
public Map<String, Long> countDetailedTransactions(Class<? extends EAILog> clazz, EAILogSearch eaiLogSearch) {
|
public Map<String, Long> countDetailedTransactions(Class<? extends EAILog> clazz, EAILogSearch eaiLogSearch) {
|
||||||
QEAILog qeaiLog = QEAILog.eAILog;
|
QEAILog qeaiLog = QEAILog.eAILog;
|
||||||
EntityPathBase<?> entityPathBase = new EntityPathBase<>(clazz, qeaiLog.getMetadata().getName());
|
EntityPathBase<?> entityPathBase = new EntityPathBase<>(clazz, qeaiLog.getMetadata().getName());
|
||||||
|
|
||||||
QEAIMessageEntity qeaiMessageEntity = QEAIMessageEntity.eAIMessageEntity;
|
|
||||||
|
|
||||||
JPAQuery<?> query = new JPAQueryFactory(em)
|
JPAQuery<?> query = new JPAQueryFactory(em).from(entityPathBase);
|
||||||
.from(entityPathBase)
|
appendConditions(eaiLogSearch, qeaiLog, entityPathBase, query);
|
||||||
.leftJoin(qeaiMessageEntity)
|
|
||||||
.on(qeaiLog.eaisvcname.eq(qeaiMessageEntity.eAIMessageEntity.eaisvcname));
|
|
||||||
|
|
||||||
appendConditions(eaiLogSearch, qeaiLog, entityPathBase, qeaiMessageEntity, query);
|
|
||||||
|
|
||||||
List<Tuple> results = query.select(
|
List<Tuple> results = query.select(
|
||||||
qeaiLog.id.logprcssserno, // 로그 처리 상태
|
qeaiLog.id.logprcssserno, // 로그 처리 상태
|
||||||
@@ -114,7 +91,8 @@ public class EAILogRepositoryImpl implements EAILogRepository {
|
|||||||
return reult;
|
return reult;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendConditions(EAILogSearch eaiLogSearch, QEAILog qeaiLog, EntityPathBase<?> entityPathBase, QEAIMessageEntity qeaiMessageEntity, JPAQuery<?> query) {
|
private void appendConditions(EAILogSearch eaiLogSearch, QEAILog qeaiLog, EntityPathBase<?> entityPathBase, JPAQuery<?> query) {
|
||||||
|
|
||||||
if (StringUtils.equalsIgnoreCase(eaiLogSearch.getAuthChk(), "Y")) {
|
if (StringUtils.equalsIgnoreCase(eaiLogSearch.getAuthChk(), "Y")) {
|
||||||
QUserBusiness qUserBusiness = QUserBusiness.userBusiness;
|
QUserBusiness qUserBusiness = QUserBusiness.userBusiness;
|
||||||
JPAQuery<String> subQuery = new JPAQueryFactory(em)
|
JPAQuery<String> subQuery = new JPAQueryFactory(em)
|
||||||
@@ -149,10 +127,6 @@ public class EAILogRepositoryImpl implements EAILogRepository {
|
|||||||
if (StringUtils.isNotBlank(eaiLogSearch.getSearchEaiSvcName())) {
|
if (StringUtils.isNotBlank(eaiLogSearch.getSearchEaiSvcName())) {
|
||||||
query.where(qeaiLog.eaisvcname.containsIgnoreCase(eaiLogSearch.getSearchEaiSvcName()));
|
query.where(qeaiLog.eaisvcname.containsIgnoreCase(eaiLogSearch.getSearchEaiSvcName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(eaiLogSearch.getSearchEaiSvcDesc())) {
|
|
||||||
query.where(qeaiMessageEntity.eaisvcdesc.containsIgnoreCase(eaiLogSearch.getSearchEaiSvcDesc()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(eaiLogSearch.getSearchKeyMgtMsgCtnt())) {
|
if (StringUtils.isNotBlank(eaiLogSearch.getSearchKeyMgtMsgCtnt())) {
|
||||||
query.where(qeaiLog.keymgtmsgctnt.contains(eaiLogSearch.getSearchKeyMgtMsgCtnt()));
|
query.where(qeaiLog.keymgtmsgctnt.contains(eaiLogSearch.getSearchKeyMgtMsgCtnt()));
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
### 수집 차원
|
### 수집 차원
|
||||||
- **시간 단위**: 분 단위
|
- **시간 단위**: 분 단위
|
||||||
- **분류 차원**: API명, API Gateway Instance, ClientId, Scope, 업무구분코드 (값이 없을 경우 'NONE' 으로 대체)
|
- **분류 차원**: API명, API Gateway Instance, ClientId, Inbound Adapter, Outbound Adapter, 업무구분코드 (값이 없을 경우 'NONE' 으로 대체)
|
||||||
|
|
||||||
### 메트릭
|
### 메트릭
|
||||||
- **처리 건수**:
|
- **처리 건수**:
|
||||||
@@ -24,6 +24,23 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 구현 완료
|
||||||
|
|
||||||
|
### 구현 위치
|
||||||
|
- **패키지**: `com.eactive.eai.custom.statistics`
|
||||||
|
- **경로**: `eapim-online/src/main/java/com/eactive/eai/custom/statistics/`
|
||||||
|
|
||||||
|
### 주요 컴포넌트
|
||||||
|
1. **ApiStatsCollector**: 거래마다 호출되어 메모리에 집계
|
||||||
|
2. **MinuteStatsAggregator**: HdrHistogram 기반 백분위 계산
|
||||||
|
3. **ApiStatsScheduler**: 매 분 5초에 DB 저장
|
||||||
|
4. **TransactionEvent**: 거래 이벤트 DTO
|
||||||
|
|
||||||
|
### 사용법
|
||||||
|
상세한 사용법은 `eapim-online/src/main/java/com/eactive/eai/custom/statistics/README.md` 참조
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 테이블 DDL
|
## 테이블 DDL
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
@@ -32,9 +49,10 @@ CREATE TABLE API_STATS_MINUTE (
|
|||||||
STAT_TIME TIMESTAMP(0) NOT NULL, -- 통계 시간 (분 단위, 초는 00)
|
STAT_TIME TIMESTAMP(0) NOT NULL, -- 통계 시간 (분 단위, 초는 00)
|
||||||
API_NAME VARCHAR2(100) NOT NULL, -- API명
|
API_NAME VARCHAR2(100) NOT NULL, -- API명
|
||||||
GW_INSTANCE_ID VARCHAR2(50) NOT NULL, -- API Gateway 인스턴스 ID
|
GW_INSTANCE_ID VARCHAR2(50) NOT NULL, -- API Gateway 인스턴스 ID
|
||||||
CLIENT_ID VARCHAR2(100) NOT NULL, -- 클라이언트 ID
|
|
||||||
SCOPE VARCHAR2(100) DEFAULT 'NONE' NOT NULL, -- 스코프
|
|
||||||
BIZ_DIV_CODE VARCHAR2(50) DEFAULT 'NONE' NOT NULL, -- 업무구분코드
|
BIZ_DIV_CODE VARCHAR2(50) DEFAULT 'NONE' NOT NULL, -- 업무구분코드
|
||||||
|
CLIENT_ID VARCHAR2(100) DEFAULT 'NONE' NOT NULL, -- 클라이언트 ID
|
||||||
|
INBOUND_ADAPTER VARCHAR2(100) DEFAULT 'NONE' NOT NULL, -- Inbound Adapter
|
||||||
|
OUTBOUND_ADAPTER VARCHAR2(100) DEFAULT 'NONE' NOT NULL, -- Outbound Adapter
|
||||||
|
|
||||||
-- 건수 메트릭
|
-- 건수 메트릭
|
||||||
TOTAL_CNT NUMBER(12) DEFAULT 0 NOT NULL,
|
TOTAL_CNT NUMBER(12) DEFAULT 0 NOT NULL,
|
||||||
@@ -43,6 +61,11 @@ CREATE TABLE API_STATS_MINUTE (
|
|||||||
SYSTEM_ERR_CNT NUMBER(12) DEFAULT 0 NOT NULL,
|
SYSTEM_ERR_CNT NUMBER(12) DEFAULT 0 NOT NULL,
|
||||||
BIZ_ERR_CNT NUMBER(12) DEFAULT 0 NOT NULL,
|
BIZ_ERR_CNT NUMBER(12) DEFAULT 0 NOT NULL,
|
||||||
|
|
||||||
|
-- 로그 시퀀스 900 구간 에러 카운트
|
||||||
|
SEQ900_TIMEOUT_CNT NUMBER(12) DEFAULT 0 NOT NULL,
|
||||||
|
SEQ900_SYSTEM_ERR_CNT NUMBER(12) DEFAULT 0 NOT NULL,
|
||||||
|
SEQ900_BIZ_ERR_CNT NUMBER(12) DEFAULT 0 NOT NULL,
|
||||||
|
|
||||||
-- 응답시간 메트릭 (ms, 소수점 3자리)
|
-- 응답시간 메트릭 (ms, 소수점 3자리)
|
||||||
AVG_RESP_TIME NUMBER(10,3) DEFAULT 0,
|
AVG_RESP_TIME NUMBER(10,3) DEFAULT 0,
|
||||||
MIN_RESP_TIME NUMBER(10,3) DEFAULT 0,
|
MIN_RESP_TIME NUMBER(10,3) DEFAULT 0,
|
||||||
@@ -50,12 +73,8 @@ CREATE TABLE API_STATS_MINUTE (
|
|||||||
P50_RESP_TIME NUMBER(10,3) DEFAULT 0,
|
P50_RESP_TIME NUMBER(10,3) DEFAULT 0,
|
||||||
P95_RESP_TIME NUMBER(10,3) DEFAULT 0,
|
P95_RESP_TIME NUMBER(10,3) DEFAULT 0,
|
||||||
|
|
||||||
-- 관리 정보
|
|
||||||
REG_DTIME TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL,
|
|
||||||
UPD_DTIME TIMESTAMP DEFAULT SYSTIMESTAMP,
|
|
||||||
|
|
||||||
CONSTRAINT PK_API_STATS_MINUTE PRIMARY KEY (
|
CONSTRAINT PK_API_STATS_MINUTE PRIMARY KEY (
|
||||||
STAT_TIME, API_NAME, GW_INSTANCE_ID, CLIENT_ID, SCOPE, BIZ_DIV_CODE
|
STAT_TIME, API_NAME, GW_INSTANCE_ID, BIZ_DIV_CODE, CLIENT_ID, INBOUND_ADAPTER, OUTBOUND_ADAPTER
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -64,14 +83,18 @@ COMMENT ON TABLE API_STATS_MINUTE IS 'API Gateway 분단위 처리 통계';
|
|||||||
COMMENT ON COLUMN API_STATS_MINUTE.STAT_TIME IS '통계시간(분단위, 초는 00초로 절사)';
|
COMMENT ON COLUMN API_STATS_MINUTE.STAT_TIME IS '통계시간(분단위, 초는 00초로 절사)';
|
||||||
COMMENT ON COLUMN API_STATS_MINUTE.API_NAME IS 'API 명칭';
|
COMMENT ON COLUMN API_STATS_MINUTE.API_NAME IS 'API 명칭';
|
||||||
COMMENT ON COLUMN API_STATS_MINUTE.GW_INSTANCE_ID IS 'API Gateway 인스턴스 ID';
|
COMMENT ON COLUMN API_STATS_MINUTE.GW_INSTANCE_ID IS 'API Gateway 인스턴스 ID';
|
||||||
COMMENT ON COLUMN API_STATS_MINUTE.CLIENT_ID IS '클라이언트 ID';
|
|
||||||
COMMENT ON COLUMN API_STATS_MINUTE.SCOPE IS '스코프 (없으면 NONE)';
|
|
||||||
COMMENT ON COLUMN API_STATS_MINUTE.BIZ_DIV_CODE IS '업무구분코드 (없으면 NONE)';
|
COMMENT ON COLUMN API_STATS_MINUTE.BIZ_DIV_CODE IS '업무구분코드 (없으면 NONE)';
|
||||||
|
COMMENT ON COLUMN API_STATS_MINUTE.CLIENT_ID IS '클라이언트 ID (없으면 NONE)';
|
||||||
|
COMMENT ON COLUMN API_STATS_MINUTE.INBOUND_ADAPTER IS 'Inbound Adapter (없으면 NONE)';
|
||||||
|
COMMENT ON COLUMN API_STATS_MINUTE.OUTBOUND_ADAPTER IS 'Outbound Adapter (없으면 NONE)';
|
||||||
COMMENT ON COLUMN API_STATS_MINUTE.TOTAL_CNT IS '총 처리 건수';
|
COMMENT ON COLUMN API_STATS_MINUTE.TOTAL_CNT IS '총 처리 건수';
|
||||||
COMMENT ON COLUMN API_STATS_MINUTE.SUCCESS_CNT IS '성공 건수';
|
COMMENT ON COLUMN API_STATS_MINUTE.SUCCESS_CNT IS '성공 건수';
|
||||||
COMMENT ON COLUMN API_STATS_MINUTE.TIMEOUT_CNT IS 'Timeout 오류 건수';
|
COMMENT ON COLUMN API_STATS_MINUTE.TIMEOUT_CNT IS 'Timeout 오류 건수';
|
||||||
COMMENT ON COLUMN API_STATS_MINUTE.SYSTEM_ERR_CNT IS '시스템 오류 건수';
|
COMMENT ON COLUMN API_STATS_MINUTE.SYSTEM_ERR_CNT IS '시스템 오류 건수';
|
||||||
COMMENT ON COLUMN API_STATS_MINUTE.BIZ_ERR_CNT IS '업무 오류 건수';
|
COMMENT ON COLUMN API_STATS_MINUTE.BIZ_ERR_CNT IS '업무 오류 건수';
|
||||||
|
COMMENT ON COLUMN API_STATS_MINUTE.SEQ900_TIMEOUT_CNT IS '로그시퀀스900 Timeout 오류 건수';
|
||||||
|
COMMENT ON COLUMN API_STATS_MINUTE.SEQ900_SYSTEM_ERR_CNT IS '로그시퀀스900 시스템 오류 건수';
|
||||||
|
COMMENT ON COLUMN API_STATS_MINUTE.SEQ900_BIZ_ERR_CNT IS '로그시퀀스900 업무 오류 건수';
|
||||||
COMMENT ON COLUMN API_STATS_MINUTE.AVG_RESP_TIME IS '평균 응답시간(ms)';
|
COMMENT ON COLUMN API_STATS_MINUTE.AVG_RESP_TIME IS '평균 응답시간(ms)';
|
||||||
COMMENT ON COLUMN API_STATS_MINUTE.MIN_RESP_TIME IS '최소 응답시간(ms)';
|
COMMENT ON COLUMN API_STATS_MINUTE.MIN_RESP_TIME IS '최소 응답시간(ms)';
|
||||||
COMMENT ON COLUMN API_STATS_MINUTE.MAX_RESP_TIME IS '최대 응답시간(ms)';
|
COMMENT ON COLUMN API_STATS_MINUTE.MAX_RESP_TIME IS '최대 응답시간(ms)';
|
||||||
@@ -81,3 +104,66 @@ COMMENT ON COLUMN API_STATS_MINUTE.P95_RESP_TIME IS '95 백분위 응답시간(m
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 시간별 통계 테이블 DDL
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- API Gateway 시간별 통계 테이블
|
||||||
|
CREATE TABLE API_STATS_HOUR (
|
||||||
|
STAT_TIME TIMESTAMP(0) NOT NULL, -- 통계 시간 (시간 단위, 분/초는 00)
|
||||||
|
API_NAME VARCHAR2(100) NOT NULL, -- API명
|
||||||
|
GW_INSTANCE_ID VARCHAR2(50) NOT NULL, -- API Gateway 인스턴스 ID
|
||||||
|
BIZ_DIV_CODE VARCHAR2(50) DEFAULT 'NONE' NOT NULL, -- 업무구분코드
|
||||||
|
CLIENT_ID VARCHAR2(100) DEFAULT 'NONE' NOT NULL, -- 클라이언트 ID
|
||||||
|
INBOUND_ADAPTER VARCHAR2(100) DEFAULT 'NONE' NOT NULL, -- Inbound Adapter
|
||||||
|
OUTBOUND_ADAPTER VARCHAR2(100) DEFAULT 'NONE' NOT NULL, -- Outbound Adapter
|
||||||
|
|
||||||
|
-- 건수 메트릭
|
||||||
|
TOTAL_CNT NUMBER(12) DEFAULT 0 NOT NULL,
|
||||||
|
SUCCESS_CNT NUMBER(12) DEFAULT 0 NOT NULL,
|
||||||
|
TIMEOUT_CNT NUMBER(12) DEFAULT 0 NOT NULL,
|
||||||
|
SYSTEM_ERR_CNT NUMBER(12) DEFAULT 0 NOT NULL,
|
||||||
|
BIZ_ERR_CNT NUMBER(12) DEFAULT 0 NOT NULL,
|
||||||
|
|
||||||
|
-- 로그 시퀀스 900 구간 에러 카운트
|
||||||
|
SEQ900_TIMEOUT_CNT NUMBER(12) DEFAULT 0 NOT NULL,
|
||||||
|
SEQ900_SYSTEM_ERR_CNT NUMBER(12) DEFAULT 0 NOT NULL,
|
||||||
|
SEQ900_BIZ_ERR_CNT NUMBER(12) DEFAULT 0 NOT NULL,
|
||||||
|
|
||||||
|
-- 응답시간 메트릭 (ms, 소수점 3자리)
|
||||||
|
AVG_RESP_TIME NUMBER(10,3) DEFAULT 0,
|
||||||
|
MIN_RESP_TIME NUMBER(10,3) DEFAULT 0,
|
||||||
|
MAX_RESP_TIME NUMBER(10,3) DEFAULT 0,
|
||||||
|
P50_RESP_TIME NUMBER(10,3) DEFAULT 0,
|
||||||
|
P95_RESP_TIME NUMBER(10,3) DEFAULT 0,
|
||||||
|
|
||||||
|
CONSTRAINT PK_API_STATS_HOUR PRIMARY KEY (
|
||||||
|
STAT_TIME, API_NAME, GW_INSTANCE_ID, BIZ_DIV_CODE, CLIENT_ID, INBOUND_ADAPTER, OUTBOUND_ADAPTER
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 코멘트
|
||||||
|
COMMENT ON TABLE API_STATS_HOUR IS 'API Gateway 시간별 처리 통계';
|
||||||
|
COMMENT ON COLUMN API_STATS_HOUR.STAT_TIME IS '통계시간(시간단위, 분/초는 00으로 절사)';
|
||||||
|
COMMENT ON COLUMN API_STATS_HOUR.API_NAME IS 'API 명칭';
|
||||||
|
COMMENT ON COLUMN API_STATS_HOUR.GW_INSTANCE_ID IS 'API Gateway 인스턴스 ID';
|
||||||
|
COMMENT ON COLUMN API_STATS_HOUR.BIZ_DIV_CODE IS '업무구분코드 (없으면 NONE)';
|
||||||
|
COMMENT ON COLUMN API_STATS_HOUR.CLIENT_ID IS '클라이언트 ID (없으면 NONE)';
|
||||||
|
COMMENT ON COLUMN API_STATS_HOUR.INBOUND_ADAPTER IS 'Inbound Adapter (없으면 NONE)';
|
||||||
|
COMMENT ON COLUMN API_STATS_HOUR.OUTBOUND_ADAPTER IS 'Outbound Adapter (없으면 NONE)';
|
||||||
|
COMMENT ON COLUMN API_STATS_HOUR.TOTAL_CNT IS '총 처리 건수';
|
||||||
|
COMMENT ON COLUMN API_STATS_HOUR.SUCCESS_CNT IS '성공 건수';
|
||||||
|
COMMENT ON COLUMN API_STATS_HOUR.TIMEOUT_CNT IS 'Timeout 오류 건수';
|
||||||
|
COMMENT ON COLUMN API_STATS_HOUR.SYSTEM_ERR_CNT IS '시스템 오류 건수';
|
||||||
|
COMMENT ON COLUMN API_STATS_HOUR.BIZ_ERR_CNT IS '업무 오류 건수';
|
||||||
|
COMMENT ON COLUMN API_STATS_HOUR.SEQ900_TIMEOUT_CNT IS '로그시퀀스900 Timeout 오류 건수';
|
||||||
|
COMMENT ON COLUMN API_STATS_HOUR.SEQ900_SYSTEM_ERR_CNT IS '로그시퀀스900 시스템 오류 건수';
|
||||||
|
COMMENT ON COLUMN API_STATS_HOUR.SEQ900_BIZ_ERR_CNT IS '로그시퀀스900 업무 오류 건수';
|
||||||
|
COMMENT ON COLUMN API_STATS_HOUR.AVG_RESP_TIME IS '평균 응답시간(ms)';
|
||||||
|
COMMENT ON COLUMN API_STATS_HOUR.MIN_RESP_TIME IS '최소 응답시간(ms)';
|
||||||
|
COMMENT ON COLUMN API_STATS_HOUR.MAX_RESP_TIME IS '최대 응답시간(ms)';
|
||||||
|
COMMENT ON COLUMN API_STATS_HOUR.P50_RESP_TIME IS '50 백분위 응답시간(ms)';
|
||||||
|
COMMENT ON COLUMN API_STATS_HOUR.P95_RESP_TIME IS '95 백분위 응답시간(ms)';
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user