Merge branch 'jenkins_with_weblogic' of http://192.168.240.178:18080/eapim/eapim-online.git into jenkins_with_weblogic
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
package com.eactive.eai.custom.statistics;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.eactive.eai.common.message.EAIMessage;
|
||||
@@ -120,6 +122,10 @@ public class ApiStatsMonitorImpl implements StatisticsMonitor {
|
||||
private long extractResponseTime(EAIMessage msg) {
|
||||
long msgPssTm = msg.getMsgPssTm(); // 메시지 처리시각
|
||||
long msgRcvTm = msg.getMsgRcvTm(); // 메시지 수신시각
|
||||
|
||||
if (msgPssTm == 0) {
|
||||
msgPssTm = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
if (msgPssTm > 0 && msgRcvTm > 0) {
|
||||
return msgPssTm - msgRcvTm;
|
||||
|
||||
@@ -17,7 +17,6 @@ import com.eactive.eai.data.entity.custom.statistics.ApiStatsHour;
|
||||
import com.eactive.eai.data.entity.custom.statistics.ApiStatsMinute;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* API 통계 수집기
|
||||
@@ -60,80 +59,74 @@ public class ApiStatsCollector {
|
||||
}
|
||||
|
||||
/**
|
||||
* 거래 이벤트 기록 (시간 지정 - 테스트용)
|
||||
* 거래 이벤트 기록 (시간 지정)
|
||||
*
|
||||
* @param event 거래 이벤트
|
||||
* @param eventTime 이벤트 발생 시간
|
||||
*/
|
||||
public void recordEvent(TransactionEvent event, LocalDateTime eventTime) {
|
||||
// 통계 수집 비활성화 체크 (분단위 또는 시간별 중 하나라도 활성화되어야 함)
|
||||
boolean minuteEnabled = apiStatsConfig.isMinuteEnabled();
|
||||
boolean hourEnabled = apiStatsConfig.isHourEnabled();
|
||||
|
||||
if (!minuteEnabled && !hourEnabled) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("API stats collection is disabled (both minute and hour)");
|
||||
}
|
||||
log.debug("API stats collection is disabled (both minute and hour)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (minuteEnabled) {
|
||||
recordMinuteEvent(event, eventTime);
|
||||
}
|
||||
|
||||
if (hourEnabled) {
|
||||
recordHourEvent(event, eventTime);
|
||||
}
|
||||
}
|
||||
|
||||
private void recordMinuteEvent(TransactionEvent event, LocalDateTime eventTime) {
|
||||
try {
|
||||
MinuteStatsKey minuteKey = null;
|
||||
MinuteStatsAggregator minuteAggregator = null;
|
||||
HourStatsKey hourKey = null;
|
||||
HourStatsAggregator hourAggregator = null;
|
||||
if (minuteAggregators.size() >= MAX_MINUTE_AGGREGATORS) {
|
||||
log.warn("Minute aggregator limit reached ({}), forcing flush of completed minutes", MAX_MINUTE_AGGREGATORS);
|
||||
flushCompletedMinutes();
|
||||
|
||||
// 분단위 집계 (활성화된 경우만)
|
||||
if (minuteEnabled) {
|
||||
// Aggregator 개수 제한 체크 (메모리 보호)
|
||||
if (minuteAggregators.size() >= MAX_MINUTE_AGGREGATORS) {
|
||||
log.warn("Minute aggregator limit reached ({}), forcing flush of completed minutes", MAX_MINUTE_AGGREGATORS);
|
||||
flushCompletedMinutes();
|
||||
|
||||
// flush 후에도 여전히 제한 초과 시 경고
|
||||
if (minuteAggregators.size() >= MAX_MINUTE_AGGREGATORS) {
|
||||
log.error("Minute aggregator count still exceeds limit after flush: {}", minuteAggregators.size());
|
||||
}
|
||||
log.error("Minute aggregator count still exceeds limit after flush: {}", minuteAggregators.size());
|
||||
}
|
||||
|
||||
minuteKey = MinuteStatsKey.from(event, eventTime);
|
||||
minuteAggregator = minuteAggregators.computeIfAbsent(
|
||||
minuteKey,
|
||||
MinuteStatsAggregator::new
|
||||
);
|
||||
minuteAggregator.recordEvent(event);
|
||||
}
|
||||
|
||||
// 시간별 집계 (활성화된 경우만)
|
||||
if (hourEnabled) {
|
||||
// Aggregator 개수 제한 체크 (메모리 보호)
|
||||
if (hourAggregators.size() >= MAX_HOUR_AGGREGATORS) {
|
||||
log.warn("Hour aggregator limit reached ({}), forcing flush of completed hours", MAX_HOUR_AGGREGATORS);
|
||||
flushCompletedHours();
|
||||
|
||||
// flush 후에도 여전히 제한 초과 시 경고
|
||||
if (hourAggregators.size() >= MAX_HOUR_AGGREGATORS) {
|
||||
log.error("Hour aggregator count still exceeds limit after flush: {}", hourAggregators.size());
|
||||
}
|
||||
}
|
||||
|
||||
hourKey = HourStatsKey.from(event, eventTime);
|
||||
hourAggregator = hourAggregators.computeIfAbsent(
|
||||
hourKey,
|
||||
HourStatsAggregator::new
|
||||
);
|
||||
hourAggregator.recordEvent(event);
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Recorded event: minute={}, hour={}, minute_total={}, hour_total={}",
|
||||
minuteKey, hourKey,
|
||||
minuteAggregator != null ? minuteAggregator.getTotalCount() : 0,
|
||||
hourAggregator != null ? hourAggregator.getTotalCount() : 0);
|
||||
}
|
||||
MinuteStatsKey minuteKey = MinuteStatsKey.from(event, eventTime);
|
||||
MinuteStatsAggregator minuteAggregator = minuteAggregators.computeIfAbsent(
|
||||
minuteKey,
|
||||
MinuteStatsAggregator::new
|
||||
);
|
||||
minuteAggregator.recordEvent(event);
|
||||
|
||||
log.debug("Recorded minute event: key={}, total={}", minuteKey, minuteAggregator.getTotalCount());
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to record event: {}", event, e);
|
||||
log.error("Failed to record minute event: {}", event, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void recordHourEvent(TransactionEvent event, LocalDateTime eventTime) {
|
||||
try {
|
||||
if (hourAggregators.size() >= MAX_HOUR_AGGREGATORS) {
|
||||
log.warn("Hour aggregator limit reached ({}), forcing flush of completed hours", MAX_HOUR_AGGREGATORS);
|
||||
flushCompletedHours();
|
||||
|
||||
if (hourAggregators.size() >= MAX_HOUR_AGGREGATORS) {
|
||||
log.error("Hour aggregator count still exceeds limit after flush: {}", hourAggregators.size());
|
||||
}
|
||||
}
|
||||
|
||||
HourStatsKey hourKey = HourStatsKey.from(event, eventTime);
|
||||
HourStatsAggregator hourAggregator = hourAggregators.computeIfAbsent(
|
||||
hourKey,
|
||||
HourStatsAggregator::new
|
||||
);
|
||||
hourAggregator.recordEvent(event);
|
||||
|
||||
log.debug("Recorded hour event: key={}, total={}", hourKey, hourAggregator.getTotalCount());
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to record hour event: {}", event, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,6 @@ public class HourStatsAggregator {
|
||||
|
||||
/**
|
||||
* 거래 이벤트 기록
|
||||
* - AtomicLong 사용으로 synchronized 불필요 (성능 최적화)
|
||||
*/
|
||||
public void recordEvent(TransactionEvent event) {
|
||||
int logSeq = event.getLogSequence();
|
||||
@@ -194,6 +193,7 @@ public class HourStatsAggregator {
|
||||
long timeout = timeoutCnt.get();
|
||||
long systemErr = systemErrCnt.get();
|
||||
long bizErr = bizErrCnt.get();
|
||||
long avgCount = success + timeout + systemErr + bizErr;
|
||||
|
||||
stats.setTotalCnt(total);
|
||||
stats.setSuccessCnt(success);
|
||||
@@ -207,9 +207,9 @@ public class HourStatsAggregator {
|
||||
stats.setSeq900BizErrCnt(seq900BizErrCnt.get());
|
||||
|
||||
// 응답시간 메트릭
|
||||
if (total > 0 && totalRespTime.get() > 0) {
|
||||
if (avgCount > 0 && totalRespTime.get() > 0) {
|
||||
// 응답시간이 실제로 기록된 경우만 처리
|
||||
double avg = (double) totalRespTime.get() / total;
|
||||
double avg = (double) totalRespTime.get() / avgCount;
|
||||
stats.setAvgRespTime(BigDecimal.valueOf(avg).setScale(3, RoundingMode.HALF_UP));
|
||||
|
||||
// Min/Max (totalRespTime > 0이면 반드시 갱신됨)
|
||||
|
||||
+3
-3
@@ -57,7 +57,6 @@ public class MinuteStatsAggregator {
|
||||
|
||||
/**
|
||||
* 거래 이벤트 기록
|
||||
* - AtomicLong 사용으로 synchronized 불필요 (성능 최적화)
|
||||
*/
|
||||
public void recordEvent(TransactionEvent event) {
|
||||
int logSeq = event.getLogSequence();
|
||||
@@ -194,6 +193,7 @@ public class MinuteStatsAggregator {
|
||||
long timeout = timeoutCnt.get();
|
||||
long systemErr = systemErrCnt.get();
|
||||
long bizErr = bizErrCnt.get();
|
||||
long avgCount = success + timeout + systemErr + bizErr;
|
||||
|
||||
stats.setTotalCnt(total);
|
||||
stats.setSuccessCnt(success);
|
||||
@@ -207,9 +207,9 @@ public class MinuteStatsAggregator {
|
||||
stats.setSeq900BizErrCnt(seq900BizErrCnt.get());
|
||||
|
||||
// 응답시간 메트릭
|
||||
if (total > 0 && totalRespTime.get() > 0) {
|
||||
if (avgCount > 0 && totalRespTime.get() > 0) {
|
||||
// 응답시간이 실제로 기록된 경우만 처리
|
||||
double avg = (double) totalRespTime.get() / total;
|
||||
double avg = (double) totalRespTime.get() / avgCount;
|
||||
stats.setAvgRespTime(BigDecimal.valueOf(avg).setScale(3, RoundingMode.HALF_UP));
|
||||
|
||||
// Min/Max (totalRespTime > 0이면 반드시 갱신됨)
|
||||
|
||||
Reference in New Issue
Block a user