PRECISION 오류 수정

This commit is contained in:
pksup
2026-01-13 17:00:01 +09:00
parent f9bc9fafcd
commit 5a898e0e1d
3 changed files with 83 additions and 6 deletions
@@ -203,12 +203,12 @@ public class HourStatsAggregator {
stats.setSeq900BizErrCnt(seq900BizErrCnt.get());
// 응답시간 메트릭
if (total > 0) {
// 평균
if (total > 0 && totalRespTime.get() > 0) {
// 응답시간이 실제로 기록된 경우만 처리
double avg = (double) totalRespTime.get() / total;
stats.setAvgRespTime(BigDecimal.valueOf(avg).setScale(3, RoundingMode.HALF_UP));
// Min/Max
// Min/Max (totalRespTime > 0이면 반드시 갱신됨)
stats.setMinRespTime(BigDecimal.valueOf(minRespTime.get()).setScale(3, RoundingMode.HALF_UP));
stats.setMaxRespTime(BigDecimal.valueOf(maxRespTime.get()).setScale(3, RoundingMode.HALF_UP));
@@ -218,6 +218,7 @@ public class HourStatsAggregator {
stats.setP50RespTime(BigDecimal.valueOf(p50).setScale(3, RoundingMode.HALF_UP));
stats.setP95RespTime(BigDecimal.valueOf(p95).setScale(3, RoundingMode.HALF_UP));
} else {
// 응답시간이 기록되지 않음 (logSeq 400 없음)
stats.setAvgRespTime(BigDecimal.ZERO);
stats.setMinRespTime(BigDecimal.ZERO);
stats.setMaxRespTime(BigDecimal.ZERO);
@@ -203,12 +203,12 @@ public class MinuteStatsAggregator {
stats.setSeq900BizErrCnt(seq900BizErrCnt.get());
// 응답시간 메트릭
if (total > 0) {
// 평균
if (total > 0 && totalRespTime.get() > 0) {
// 응답시간이 실제로 기록된 경우만 처리
double avg = (double) totalRespTime.get() / total;
stats.setAvgRespTime(BigDecimal.valueOf(avg).setScale(3, RoundingMode.HALF_UP));
// Min/Max
// Min/Max (totalRespTime > 0이면 반드시 갱신됨)
stats.setMinRespTime(BigDecimal.valueOf(minRespTime.get()).setScale(3, RoundingMode.HALF_UP));
stats.setMaxRespTime(BigDecimal.valueOf(maxRespTime.get()).setScale(3, RoundingMode.HALF_UP));
@@ -218,6 +218,7 @@ public class MinuteStatsAggregator {
stats.setP50RespTime(BigDecimal.valueOf(p50).setScale(3, RoundingMode.HALF_UP));
stats.setP95RespTime(BigDecimal.valueOf(p95).setScale(3, RoundingMode.HALF_UP));
} else {
// 응답시간이 기록되지 않음 (logSeq 400 없음)
stats.setAvgRespTime(BigDecimal.ZERO);
stats.setMinRespTime(BigDecimal.ZERO);
stats.setMaxRespTime(BigDecimal.ZERO);
@@ -90,6 +90,9 @@ public class ApiStatsScheduler {
for (ApiStatsMinute stats : statsList) {
try {
// Precision 체크 (디버깅)
checkPrecision(stats);
minuteLogger.log(stats);
savedCount++;
@@ -158,6 +161,9 @@ public class ApiStatsScheduler {
for (ApiStatsHour stats : statsList) {
try {
// Precision 체크 (디버깅)
checkPrecision(stats);
hourLogger.log(stats);
savedCount++;
@@ -285,4 +291,73 @@ public class ApiStatsScheduler {
log.error("Error during shutdown", e);
}
}
/**
* Precision 체크 (디버깅용)
*/
private void checkPrecision(ApiStatsMinute stats) {
checkPrecisionCommon(stats.getApiName(), stats.getStatTime(),
stats.getTotalCnt(), stats.getSuccessCnt(), stats.getTimeoutCnt(),
stats.getSystemErrCnt(), stats.getBizErrCnt(),
stats.getSeq900TimeoutCnt(), stats.getSeq900SystemErrCnt(), stats.getSeq900BizErrCnt(),
stats.getAvgRespTime(), stats.getMinRespTime(), stats.getMaxRespTime(),
stats.getP50RespTime(), stats.getP95RespTime());
}
/**
* Precision 체크 (디버깅용)
*/
private void checkPrecision(ApiStatsHour stats) {
checkPrecisionCommon(stats.getApiName(), stats.getStatTime(),
stats.getTotalCnt(), stats.getSuccessCnt(), stats.getTimeoutCnt(),
stats.getSystemErrCnt(), stats.getBizErrCnt(),
stats.getSeq900TimeoutCnt(), stats.getSeq900SystemErrCnt(), stats.getSeq900BizErrCnt(),
stats.getAvgRespTime(), stats.getMinRespTime(), stats.getMaxRespTime(),
stats.getP50RespTime(), stats.getP95RespTime());
}
private void checkPrecisionCommon(String apiName, Object statTime,
Long totalCnt, Long successCnt, Long timeoutCnt, Long systemErrCnt, Long bizErrCnt,
Long seq900TimeoutCnt, Long seq900SystemErrCnt, Long seq900BizErrCnt,
java.math.BigDecimal avgRespTime, java.math.BigDecimal minRespTime, java.math.BigDecimal maxRespTimeValue,
java.math.BigDecimal p50RespTime, java.math.BigDecimal p95RespTime) {
// NUMBER(12) 체크 - 건수 필드
if (totalCnt != null && totalCnt > 999999999999L) {
log.warn("PRECISION EXCEEDED - API: {}, Time: {}, TOTAL_CNT: {}", apiName, statTime, totalCnt);
}
if (successCnt != null && successCnt < 0) {
log.warn("NEGATIVE VALUE - API: {}, Time: {}, SUCCESS_CNT: {}", apiName, statTime, successCnt);
}
if (successCnt != null && successCnt > 999999999999L) {
log.warn("PRECISION EXCEEDED - API: {}, Time: {}, SUCCESS_CNT: {}", apiName, statTime, successCnt);
}
if (timeoutCnt != null && timeoutCnt > 999999999999L) {
log.warn("PRECISION EXCEEDED - API: {}, Time: {}, TIMEOUT_CNT: {}", apiName, statTime, timeoutCnt);
}
if (systemErrCnt != null && systemErrCnt > 999999999999L) {
log.warn("PRECISION EXCEEDED - API: {}, Time: {}, SYSTEM_ERR_CNT: {}", apiName, statTime, systemErrCnt);
}
if (bizErrCnt != null && bizErrCnt > 999999999999L) {
log.warn("PRECISION EXCEEDED - API: {}, Time: {}, BIZ_ERR_CNT: {}", apiName, statTime, bizErrCnt);
}
// NUMBER(10,3) 체크 - 응답시간 필드
java.math.BigDecimal maxRespTimeLimit = new java.math.BigDecimal("9999999.999");
if (avgRespTime != null && avgRespTime.compareTo(maxRespTimeLimit) > 0) {
log.warn("PRECISION EXCEEDED - API: {}, Time: {}, AVG_RESP_TIME: {}", apiName, statTime, avgRespTime);
}
if (minRespTime != null && minRespTime.compareTo(maxRespTimeLimit) > 0) {
log.warn("PRECISION EXCEEDED - API: {}, Time: {}, MIN_RESP_TIME: {}", apiName, statTime, minRespTime);
}
if (maxRespTimeValue != null && maxRespTimeValue.compareTo(maxRespTimeLimit) > 0) {
log.warn("PRECISION EXCEEDED - API: {}, Time: {}, MAX_RESP_TIME: {}", apiName, statTime, maxRespTimeValue);
}
if (p50RespTime != null && p50RespTime.compareTo(maxRespTimeLimit) > 0) {
log.warn("PRECISION EXCEEDED - API: {}, Time: {}, P50_RESP_TIME: {}", apiName, statTime, p50RespTime);
}
if (p95RespTime != null && p95RespTime.compareTo(maxRespTimeLimit) > 0) {
log.warn("PRECISION EXCEEDED - API: {}, Time: {}, P95_RESP_TIME: {}", apiName, statTime, p95RespTime);
}
}
}