API명별 요약 통계

This commit is contained in:
daekuk1
2026-01-28 16:59:42 +09:00
parent f352b38d7f
commit d4739e2bc1
18 changed files with 1431 additions and 56 deletions
@@ -1,11 +1,14 @@
package com.eactive.eai.rms.data.entity.onl.kjb.statistics;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
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.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -13,8 +16,10 @@ import org.springframework.transaction.annotation.Transactional;
import com.eactive.eai.data.jpa.AbstractDataService;
import com.eactive.ext.kjb.statistics.ui.ApiStatsChartUI;
import com.eactive.ext.kjb.statistics.ui.ApiStatsSearch;
import com.eactive.ext.kjb.statistics.ui.ApiStatsUI;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.Expressions;
@Service
@Transactional
@@ -87,6 +92,113 @@ public class ApiStatsDayService
.fetch();
}
/**
* API명별 요약 통계 조회 (GROUP BY apiName)
*/
public Page<ApiStatsUI> selectSummaryList(ApiStatsSearch search, Pageable pageable) {
QApiStatsDay q = QApiStatsDay.apiStatsDay;
BooleanBuilder builder = buildSearchConditions(q, search);
// 전체 건수 조회
Long total = getJPAQueryFactory()
.select(q.apiName.countDistinct())
.from(q)
.where(builder)
.fetchOne();
// 페이징 적용하여 조회
List<ApiStatsUI> results = getJPAQueryFactory()
.select(Projections.fields(ApiStatsUI.class,
q.apiName,
q.totalCnt.sum().as("totalCnt"),
q.successCnt.sum().as("successCnt"),
q.timeoutCnt.sum().as("timeoutCnt"),
q.systemErrCnt.sum().as("systemErrCnt"),
q.bizErrCnt.sum().as("bizErrCnt"),
q.seq900TimeoutCnt.sum().as("seq900TimeoutCnt"),
q.seq900SystemErrCnt.sum().as("seq900SystemErrCnt"),
q.seq900BizErrCnt.sum().as("seq900BizErrCnt"),
q.minRespTime.min().castToNum(BigDecimal.class).as("minRespTime"),
q.maxRespTime.max().castToNum(BigDecimal.class).as("maxRespTime"),
// 가중 평균: SUM(avg * successCnt) / SUM(successCnt)
Expressions.cases()
.when(q.successCnt.sum().gt(0))
.then(q.avgRespTime.multiply(q.successCnt).sum()
.divide(q.successCnt.sum()).castToNum(BigDecimal.class))
.otherwise((BigDecimal) null)
.as("avgRespTime")))
.from(q)
.where(builder)
.groupBy(q.apiName)
.orderBy(q.apiName.asc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
// 소수점 3자리로 반올림
results.forEach(ui -> {
if (ui.getAvgRespTime() != null) {
ui.setAvgRespTime(ui.getAvgRespTime().setScale(3, RoundingMode.HALF_UP));
}
if (ui.getMinRespTime() != null) {
ui.setMinRespTime(ui.getMinRespTime().setScale(3, RoundingMode.HALF_UP));
}
if (ui.getMaxRespTime() != null) {
ui.setMaxRespTime(ui.getMaxRespTime().setScale(3, RoundingMode.HALF_UP));
}
});
return new PageImpl<>(results, pageable, total != null ? total.longValue() : 0);
}
/**
* API명별 요약 통계 전체 조회 (Excel용)
*/
public List<ApiStatsUI> selectSummaryListForExcel(ApiStatsSearch search) {
QApiStatsDay q = QApiStatsDay.apiStatsDay;
BooleanBuilder builder = buildSearchConditions(q, search);
List<ApiStatsUI> results = getJPAQueryFactory()
.select(Projections.fields(ApiStatsUI.class,
q.apiName,
q.totalCnt.sum().as("totalCnt"),
q.successCnt.sum().as("successCnt"),
q.timeoutCnt.sum().as("timeoutCnt"),
q.systemErrCnt.sum().as("systemErrCnt"),
q.bizErrCnt.sum().as("bizErrCnt"),
q.seq900TimeoutCnt.sum().as("seq900TimeoutCnt"),
q.seq900SystemErrCnt.sum().as("seq900SystemErrCnt"),
q.seq900BizErrCnt.sum().as("seq900BizErrCnt"),
q.minRespTime.min().castToNum(BigDecimal.class).as("minRespTime"),
q.maxRespTime.max().castToNum(BigDecimal.class).as("maxRespTime"),
Expressions.cases()
.when(q.successCnt.sum().gt(0))
.then(q.avgRespTime.multiply(q.successCnt).sum()
.divide(q.successCnt.sum()).castToNum(BigDecimal.class))
.otherwise((BigDecimal) null)
.as("avgRespTime")))
.from(q)
.where(builder)
.groupBy(q.apiName)
.orderBy(q.apiName.asc())
.fetch();
// 소수점 3자리로 반올림
results.forEach(ui -> {
if (ui.getAvgRespTime() != null) {
ui.setAvgRespTime(ui.getAvgRespTime().setScale(3, RoundingMode.HALF_UP));
}
if (ui.getMinRespTime() != null) {
ui.setMinRespTime(ui.getMinRespTime().setScale(3, RoundingMode.HALF_UP));
}
if (ui.getMaxRespTime() != null) {
ui.setMaxRespTime(ui.getMaxRespTime().setScale(3, RoundingMode.HALF_UP));
}
});
return results;
}
private BooleanBuilder buildSearchConditions(QApiStatsDay q, ApiStatsSearch search) {
BooleanBuilder builder = new BooleanBuilder();
@@ -1,11 +1,14 @@
package com.eactive.eai.rms.data.entity.onl.kjb.statistics;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
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.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -13,8 +16,10 @@ import org.springframework.transaction.annotation.Transactional;
import com.eactive.eai.data.jpa.AbstractDataService;
import com.eactive.ext.kjb.statistics.ui.ApiStatsChartUI;
import com.eactive.ext.kjb.statistics.ui.ApiStatsSearch;
import com.eactive.ext.kjb.statistics.ui.ApiStatsUI;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.Expressions;
@Service
@Transactional
@@ -148,6 +153,173 @@ public class ApiStatsHourService
.fetch();
}
/**
* API명별 요약 통계 조회 (GROUP BY apiName)
*/
public Page<ApiStatsUI> selectSummaryList(ApiStatsSearch search, Pageable pageable) {
QApiStatsHour q = QApiStatsHour.apiStatsHour;
BooleanBuilder builder = new BooleanBuilder();
calculateDateRange(search);
if (search.getParsedStartDateTime() != null) {
builder.and(q.statTime.goe(search.getParsedStartDateTime()));
builder.and(q.statTime.loe(search.getParsedEndDateTime()));
}
if (StringUtils.isNotBlank(search.getSearchApiName())) {
builder.and(q.apiName.containsIgnoreCase(search.getSearchApiName()));
}
if (StringUtils.isNotBlank(search.getSearchGwInstanceId())) {
builder.and(q.gwInstanceId.containsIgnoreCase(search.getSearchGwInstanceId()));
}
if (StringUtils.isNotBlank(search.getSearchBizDivCode())) {
builder.and(q.bizDivCode.containsIgnoreCase(search.getSearchBizDivCode()));
}
if (StringUtils.isNotBlank(search.getSearchClientId())) {
builder.and(q.clientId.containsIgnoreCase(search.getSearchClientId()));
}
if (StringUtils.isNotBlank(search.getSearchInboundAdapter())) {
builder.and(q.inboundAdapter.containsIgnoreCase(search.getSearchInboundAdapter()));
}
if (StringUtils.isNotBlank(search.getSearchOutboundAdapter())) {
builder.and(q.outboundAdapter.containsIgnoreCase(search.getSearchOutboundAdapter()));
}
// 전체 건수 조회
Long total = getJPAQueryFactory()
.select(q.apiName.countDistinct())
.from(q)
.where(builder)
.fetchOne();
// 페이징 적용하여 조회
List<ApiStatsUI> results = getJPAQueryFactory()
.select(Projections.fields(ApiStatsUI.class,
q.apiName,
q.totalCnt.sum().as("totalCnt"),
q.successCnt.sum().as("successCnt"),
q.timeoutCnt.sum().as("timeoutCnt"),
q.systemErrCnt.sum().as("systemErrCnt"),
q.bizErrCnt.sum().as("bizErrCnt"),
q.seq900TimeoutCnt.sum().as("seq900TimeoutCnt"),
q.seq900SystemErrCnt.sum().as("seq900SystemErrCnt"),
q.seq900BizErrCnt.sum().as("seq900BizErrCnt"),
q.minRespTime.min().castToNum(BigDecimal.class).as("minRespTime"),
q.maxRespTime.max().castToNum(BigDecimal.class).as("maxRespTime"),
// 가중 평균: SUM(avg * successCnt) / SUM(successCnt)
Expressions.cases()
.when(q.successCnt.sum().gt(0))
.then(q.avgRespTime.multiply(q.successCnt).sum()
.divide(q.successCnt.sum()).castToNum(BigDecimal.class))
.otherwise((BigDecimal) null)
.as("avgRespTime")))
.from(q)
.where(builder)
.groupBy(q.apiName)
.orderBy(q.apiName.asc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
// 소수점 3자리로 반올림
results.forEach(ui -> {
if (ui.getAvgRespTime() != null) {
ui.setAvgRespTime(ui.getAvgRespTime().setScale(3, RoundingMode.HALF_UP));
}
if (ui.getMinRespTime() != null) {
ui.setMinRespTime(ui.getMinRespTime().setScale(3, RoundingMode.HALF_UP));
}
if (ui.getMaxRespTime() != null) {
ui.setMaxRespTime(ui.getMaxRespTime().setScale(3, RoundingMode.HALF_UP));
}
});
return new PageImpl<>(results, pageable, total != null ? total.longValue() : 0);
}
/**
* API명별 요약 통계 전체 조회 (Excel용)
*/
public List<ApiStatsUI> selectSummaryListForExcel(ApiStatsSearch search) {
QApiStatsHour q = QApiStatsHour.apiStatsHour;
BooleanBuilder builder = new BooleanBuilder();
calculateDateRange(search);
if (search.getParsedStartDateTime() != null) {
builder.and(q.statTime.goe(search.getParsedStartDateTime()));
builder.and(q.statTime.loe(search.getParsedEndDateTime()));
}
if (StringUtils.isNotBlank(search.getSearchApiName())) {
builder.and(q.apiName.containsIgnoreCase(search.getSearchApiName()));
}
if (StringUtils.isNotBlank(search.getSearchGwInstanceId())) {
builder.and(q.gwInstanceId.containsIgnoreCase(search.getSearchGwInstanceId()));
}
if (StringUtils.isNotBlank(search.getSearchBizDivCode())) {
builder.and(q.bizDivCode.containsIgnoreCase(search.getSearchBizDivCode()));
}
if (StringUtils.isNotBlank(search.getSearchClientId())) {
builder.and(q.clientId.containsIgnoreCase(search.getSearchClientId()));
}
if (StringUtils.isNotBlank(search.getSearchInboundAdapter())) {
builder.and(q.inboundAdapter.containsIgnoreCase(search.getSearchInboundAdapter()));
}
if (StringUtils.isNotBlank(search.getSearchOutboundAdapter())) {
builder.and(q.outboundAdapter.containsIgnoreCase(search.getSearchOutboundAdapter()));
}
List<ApiStatsUI> results = getJPAQueryFactory()
.select(Projections.fields(ApiStatsUI.class,
q.apiName,
q.totalCnt.sum().as("totalCnt"),
q.successCnt.sum().as("successCnt"),
q.timeoutCnt.sum().as("timeoutCnt"),
q.systemErrCnt.sum().as("systemErrCnt"),
q.bizErrCnt.sum().as("bizErrCnt"),
q.seq900TimeoutCnt.sum().as("seq900TimeoutCnt"),
q.seq900SystemErrCnt.sum().as("seq900SystemErrCnt"),
q.seq900BizErrCnt.sum().as("seq900BizErrCnt"),
q.minRespTime.min().castToNum(BigDecimal.class).as("minRespTime"),
q.maxRespTime.max().castToNum(BigDecimal.class).as("maxRespTime"),
Expressions.cases()
.when(q.successCnt.sum().gt(0))
.then(q.avgRespTime.multiply(q.successCnt).sum()
.divide(q.successCnt.sum()).castToNum(BigDecimal.class))
.otherwise((BigDecimal) null)
.as("avgRespTime")))
.from(q)
.where(builder)
.groupBy(q.apiName)
.orderBy(q.apiName.asc())
.fetch();
// 소수점 3자리로 반올림
results.forEach(ui -> {
if (ui.getAvgRespTime() != null) {
ui.setAvgRespTime(ui.getAvgRespTime().setScale(3, RoundingMode.HALF_UP));
}
if (ui.getMinRespTime() != null) {
ui.setMinRespTime(ui.getMinRespTime().setScale(3, RoundingMode.HALF_UP));
}
if (ui.getMaxRespTime() != null) {
ui.setMaxRespTime(ui.getMaxRespTime().setScale(3, RoundingMode.HALF_UP));
}
});
return results;
}
/**
* 조회 기간 계산 (최대 24시간 제한)
*/
@@ -1,11 +1,15 @@
package com.eactive.eai.rms.data.entity.onl.kjb.statistics;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
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.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -13,8 +17,10 @@ import org.springframework.transaction.annotation.Transactional;
import com.eactive.eai.data.jpa.AbstractDataService;
import com.eactive.ext.kjb.statistics.ui.ApiStatsChartUI;
import com.eactive.ext.kjb.statistics.ui.ApiStatsSearch;
import com.eactive.ext.kjb.statistics.ui.ApiStatsUI;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.Expressions;
@Service
@Transactional
@@ -150,6 +156,173 @@ public class ApiStatsMinuteService
.fetch();
}
/**
* API명별 요약 통계 조회 (GROUP BY apiName)
*/
public Page<ApiStatsUI> selectSummaryList(ApiStatsSearch search, Pageable pageable) {
QApiStatsMinute q = QApiStatsMinute.apiStatsMinute;
BooleanBuilder builder = new BooleanBuilder();
calculateDateRange(search);
if (search.getParsedStartDateTime() != null) {
builder.and(q.statTime.goe(search.getParsedStartDateTime()));
builder.and(q.statTime.loe(search.getParsedEndDateTime()));
}
if (StringUtils.isNotBlank(search.getSearchApiName())) {
builder.and(q.apiName.containsIgnoreCase(search.getSearchApiName()));
}
if (StringUtils.isNotBlank(search.getSearchGwInstanceId())) {
builder.and(q.gwInstanceId.containsIgnoreCase(search.getSearchGwInstanceId()));
}
if (StringUtils.isNotBlank(search.getSearchBizDivCode())) {
builder.and(q.bizDivCode.containsIgnoreCase(search.getSearchBizDivCode()));
}
if (StringUtils.isNotBlank(search.getSearchClientId())) {
builder.and(q.clientId.containsIgnoreCase(search.getSearchClientId()));
}
if (StringUtils.isNotBlank(search.getSearchInboundAdapter())) {
builder.and(q.inboundAdapter.containsIgnoreCase(search.getSearchInboundAdapter()));
}
if (StringUtils.isNotBlank(search.getSearchOutboundAdapter())) {
builder.and(q.outboundAdapter.containsIgnoreCase(search.getSearchOutboundAdapter()));
}
// 전체 건수 조회
Long total = getJPAQueryFactory()
.select(q.apiName.countDistinct())
.from(q)
.where(builder)
.fetchOne();
// 페이징 적용하여 조회
List<ApiStatsUI> results = getJPAQueryFactory()
.select(Projections.fields(ApiStatsUI.class,
q.apiName,
q.totalCnt.sum().as("totalCnt"),
q.successCnt.sum().as("successCnt"),
q.timeoutCnt.sum().as("timeoutCnt"),
q.systemErrCnt.sum().as("systemErrCnt"),
q.bizErrCnt.sum().as("bizErrCnt"),
q.seq900TimeoutCnt.sum().as("seq900TimeoutCnt"),
q.seq900SystemErrCnt.sum().as("seq900SystemErrCnt"),
q.seq900BizErrCnt.sum().as("seq900BizErrCnt"),
q.minRespTime.min().castToNum(BigDecimal.class).as("minRespTime"),
q.maxRespTime.max().castToNum(BigDecimal.class).as("maxRespTime"),
// 가중 평균: SUM(avg * successCnt) / SUM(successCnt)
Expressions.cases()
.when(q.successCnt.sum().gt(0))
.then(q.avgRespTime.multiply(q.successCnt).sum()
.divide(q.successCnt.sum()).castToNum(BigDecimal.class))
.otherwise((BigDecimal) null)
.as("avgRespTime")))
.from(q)
.where(builder)
.groupBy(q.apiName)
.orderBy(q.apiName.asc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
// 소수점 3자리로 반올림
results.forEach(ui -> {
if (ui.getAvgRespTime() != null) {
ui.setAvgRespTime(ui.getAvgRespTime().setScale(3, RoundingMode.HALF_UP));
}
if (ui.getMinRespTime() != null) {
ui.setMinRespTime(ui.getMinRespTime().setScale(3, RoundingMode.HALF_UP));
}
if (ui.getMaxRespTime() != null) {
ui.setMaxRespTime(ui.getMaxRespTime().setScale(3, RoundingMode.HALF_UP));
}
});
return new PageImpl<>(results, pageable, total != null ? total.longValue() : 0);
}
/**
* API명별 요약 통계 전체 조회 (Excel용)
*/
public List<ApiStatsUI> selectSummaryListForExcel(ApiStatsSearch search) {
QApiStatsMinute q = QApiStatsMinute.apiStatsMinute;
BooleanBuilder builder = new BooleanBuilder();
calculateDateRange(search);
if (search.getParsedStartDateTime() != null) {
builder.and(q.statTime.goe(search.getParsedStartDateTime()));
builder.and(q.statTime.loe(search.getParsedEndDateTime()));
}
if (StringUtils.isNotBlank(search.getSearchApiName())) {
builder.and(q.apiName.containsIgnoreCase(search.getSearchApiName()));
}
if (StringUtils.isNotBlank(search.getSearchGwInstanceId())) {
builder.and(q.gwInstanceId.containsIgnoreCase(search.getSearchGwInstanceId()));
}
if (StringUtils.isNotBlank(search.getSearchBizDivCode())) {
builder.and(q.bizDivCode.containsIgnoreCase(search.getSearchBizDivCode()));
}
if (StringUtils.isNotBlank(search.getSearchClientId())) {
builder.and(q.clientId.containsIgnoreCase(search.getSearchClientId()));
}
if (StringUtils.isNotBlank(search.getSearchInboundAdapter())) {
builder.and(q.inboundAdapter.containsIgnoreCase(search.getSearchInboundAdapter()));
}
if (StringUtils.isNotBlank(search.getSearchOutboundAdapter())) {
builder.and(q.outboundAdapter.containsIgnoreCase(search.getSearchOutboundAdapter()));
}
List<ApiStatsUI> results = getJPAQueryFactory()
.select(Projections.fields(ApiStatsUI.class,
q.apiName,
q.totalCnt.sum().as("totalCnt"),
q.successCnt.sum().as("successCnt"),
q.timeoutCnt.sum().as("timeoutCnt"),
q.systemErrCnt.sum().as("systemErrCnt"),
q.bizErrCnt.sum().as("bizErrCnt"),
q.seq900TimeoutCnt.sum().as("seq900TimeoutCnt"),
q.seq900SystemErrCnt.sum().as("seq900SystemErrCnt"),
q.seq900BizErrCnt.sum().as("seq900BizErrCnt"),
q.minRespTime.min().castToNum(BigDecimal.class).as("minRespTime"),
q.maxRespTime.max().castToNum(BigDecimal.class).as("maxRespTime"),
Expressions.cases()
.when(q.successCnt.sum().gt(0))
.then(q.avgRespTime.multiply(q.successCnt).sum()
.divide(q.successCnt.sum()).castToNum(BigDecimal.class))
.otherwise((BigDecimal) null)
.as("avgRespTime")))
.from(q)
.where(builder)
.groupBy(q.apiName)
.orderBy(q.apiName.asc())
.fetch();
// 소수점 3자리로 반올림
results.forEach(ui -> {
if (ui.getAvgRespTime() != null) {
ui.setAvgRespTime(ui.getAvgRespTime().setScale(3, RoundingMode.HALF_UP));
}
if (ui.getMinRespTime() != null) {
ui.setMinRespTime(ui.getMinRespTime().setScale(3, RoundingMode.HALF_UP));
}
if (ui.getMaxRespTime() != null) {
ui.setMaxRespTime(ui.getMaxRespTime().setScale(3, RoundingMode.HALF_UP));
}
});
return results;
}
/**
* 조회 기간 계산 (최대 1시간 제한)
*/
@@ -1,11 +1,14 @@
package com.eactive.eai.rms.data.entity.onl.kjb.statistics;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.List;
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.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -13,8 +16,10 @@ import org.springframework.transaction.annotation.Transactional;
import com.eactive.eai.data.jpa.AbstractDataService;
import com.eactive.ext.kjb.statistics.ui.ApiStatsChartUI;
import com.eactive.ext.kjb.statistics.ui.ApiStatsSearch;
import com.eactive.ext.kjb.statistics.ui.ApiStatsUI;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.Expressions;
@Service
@Transactional
@@ -87,6 +92,113 @@ public class ApiStatsMonthService
.fetch();
}
/**
* API명별 요약 통계 조회 (GROUP BY apiName)
*/
public Page<ApiStatsUI> selectSummaryList(ApiStatsSearch search, Pageable pageable) {
QApiStatsMonth q = QApiStatsMonth.apiStatsMonth;
BooleanBuilder builder = buildSearchConditions(q, search);
// 전체 건수 조회
Long total = getJPAQueryFactory()
.select(q.apiName.countDistinct())
.from(q)
.where(builder)
.fetchOne();
// 페이징 적용하여 조회
List<ApiStatsUI> results = getJPAQueryFactory()
.select(Projections.fields(ApiStatsUI.class,
q.apiName,
q.totalCnt.sum().as("totalCnt"),
q.successCnt.sum().as("successCnt"),
q.timeoutCnt.sum().as("timeoutCnt"),
q.systemErrCnt.sum().as("systemErrCnt"),
q.bizErrCnt.sum().as("bizErrCnt"),
q.seq900TimeoutCnt.sum().as("seq900TimeoutCnt"),
q.seq900SystemErrCnt.sum().as("seq900SystemErrCnt"),
q.seq900BizErrCnt.sum().as("seq900BizErrCnt"),
q.minRespTime.min().castToNum(BigDecimal.class).as("minRespTime"),
q.maxRespTime.max().castToNum(BigDecimal.class).as("maxRespTime"),
// 가중 평균: SUM(avg * successCnt) / SUM(successCnt)
Expressions.cases()
.when(q.successCnt.sum().gt(0))
.then(q.avgRespTime.multiply(q.successCnt).sum()
.divide(q.successCnt.sum()).castToNum(BigDecimal.class))
.otherwise((BigDecimal) null)
.as("avgRespTime")))
.from(q)
.where(builder)
.groupBy(q.apiName)
.orderBy(q.apiName.asc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
// 소수점 3자리로 반올림
results.forEach(ui -> {
if (ui.getAvgRespTime() != null) {
ui.setAvgRespTime(ui.getAvgRespTime().setScale(3, RoundingMode.HALF_UP));
}
if (ui.getMinRespTime() != null) {
ui.setMinRespTime(ui.getMinRespTime().setScale(3, RoundingMode.HALF_UP));
}
if (ui.getMaxRespTime() != null) {
ui.setMaxRespTime(ui.getMaxRespTime().setScale(3, RoundingMode.HALF_UP));
}
});
return new PageImpl<>(results, pageable, total != null ? total.longValue() : 0);
}
/**
* API명별 요약 통계 전체 조회 (Excel용)
*/
public List<ApiStatsUI> selectSummaryListForExcel(ApiStatsSearch search) {
QApiStatsMonth q = QApiStatsMonth.apiStatsMonth;
BooleanBuilder builder = buildSearchConditions(q, search);
List<ApiStatsUI> results = getJPAQueryFactory()
.select(Projections.fields(ApiStatsUI.class,
q.apiName,
q.totalCnt.sum().as("totalCnt"),
q.successCnt.sum().as("successCnt"),
q.timeoutCnt.sum().as("timeoutCnt"),
q.systemErrCnt.sum().as("systemErrCnt"),
q.bizErrCnt.sum().as("bizErrCnt"),
q.seq900TimeoutCnt.sum().as("seq900TimeoutCnt"),
q.seq900SystemErrCnt.sum().as("seq900SystemErrCnt"),
q.seq900BizErrCnt.sum().as("seq900BizErrCnt"),
q.minRespTime.min().castToNum(BigDecimal.class).as("minRespTime"),
q.maxRespTime.max().castToNum(BigDecimal.class).as("maxRespTime"),
Expressions.cases()
.when(q.successCnt.sum().gt(0))
.then(q.avgRespTime.multiply(q.successCnt).sum()
.divide(q.successCnt.sum()).castToNum(BigDecimal.class))
.otherwise((BigDecimal) null)
.as("avgRespTime")))
.from(q)
.where(builder)
.groupBy(q.apiName)
.orderBy(q.apiName.asc())
.fetch();
// 소수점 3자리로 반올림
results.forEach(ui -> {
if (ui.getAvgRespTime() != null) {
ui.setAvgRespTime(ui.getAvgRespTime().setScale(3, RoundingMode.HALF_UP));
}
if (ui.getMinRespTime() != null) {
ui.setMinRespTime(ui.getMinRespTime().setScale(3, RoundingMode.HALF_UP));
}
if (ui.getMaxRespTime() != null) {
ui.setMaxRespTime(ui.getMaxRespTime().setScale(3, RoundingMode.HALF_UP));
}
});
return results;
}
private BooleanBuilder buildSearchConditions(QApiStatsMonth q, ApiStatsSearch search) {
BooleanBuilder builder = new BooleanBuilder();
@@ -1,10 +1,13 @@
package com.eactive.eai.rms.data.entity.onl.kjb.statistics;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Year;
import java.util.List;
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.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -12,8 +15,10 @@ import org.springframework.transaction.annotation.Transactional;
import com.eactive.eai.data.jpa.AbstractDataService;
import com.eactive.ext.kjb.statistics.ui.ApiStatsChartUI;
import com.eactive.ext.kjb.statistics.ui.ApiStatsSearch;
import com.eactive.ext.kjb.statistics.ui.ApiStatsUI;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.Expressions;
@Service
@Transactional
@@ -84,6 +89,113 @@ public class ApiStatsYearService
.fetch();
}
/**
* API명별 요약 통계 조회 (GROUP BY apiName)
*/
public Page<ApiStatsUI> selectSummaryList(ApiStatsSearch search, Pageable pageable) {
QApiStatsYear q = QApiStatsYear.apiStatsYear;
BooleanBuilder builder = buildSearchConditions(q, search);
// 전체 건수 조회
Long total = getJPAQueryFactory()
.select(q.apiName.countDistinct())
.from(q)
.where(builder)
.fetchOne();
// 페이징 적용하여 조회
List<ApiStatsUI> results = getJPAQueryFactory()
.select(Projections.fields(ApiStatsUI.class,
q.apiName,
q.totalCnt.sum().as("totalCnt"),
q.successCnt.sum().as("successCnt"),
q.timeoutCnt.sum().as("timeoutCnt"),
q.systemErrCnt.sum().as("systemErrCnt"),
q.bizErrCnt.sum().as("bizErrCnt"),
q.seq900TimeoutCnt.sum().as("seq900TimeoutCnt"),
q.seq900SystemErrCnt.sum().as("seq900SystemErrCnt"),
q.seq900BizErrCnt.sum().as("seq900BizErrCnt"),
q.minRespTime.min().castToNum(BigDecimal.class).as("minRespTime"),
q.maxRespTime.max().castToNum(BigDecimal.class).as("maxRespTime"),
// 가중 평균: SUM(avg * successCnt) / SUM(successCnt)
Expressions.cases()
.when(q.successCnt.sum().gt(0))
.then(q.avgRespTime.multiply(q.successCnt).sum()
.divide(q.successCnt.sum()).castToNum(BigDecimal.class))
.otherwise((BigDecimal) null)
.as("avgRespTime")))
.from(q)
.where(builder)
.groupBy(q.apiName)
.orderBy(q.apiName.asc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
// 소수점 3자리로 반올림
results.forEach(ui -> {
if (ui.getAvgRespTime() != null) {
ui.setAvgRespTime(ui.getAvgRespTime().setScale(3, RoundingMode.HALF_UP));
}
if (ui.getMinRespTime() != null) {
ui.setMinRespTime(ui.getMinRespTime().setScale(3, RoundingMode.HALF_UP));
}
if (ui.getMaxRespTime() != null) {
ui.setMaxRespTime(ui.getMaxRespTime().setScale(3, RoundingMode.HALF_UP));
}
});
return new PageImpl<>(results, pageable, total != null ? total.longValue() : 0);
}
/**
* API명별 요약 통계 전체 조회 (Excel용)
*/
public List<ApiStatsUI> selectSummaryListForExcel(ApiStatsSearch search) {
QApiStatsYear q = QApiStatsYear.apiStatsYear;
BooleanBuilder builder = buildSearchConditions(q, search);
List<ApiStatsUI> results = getJPAQueryFactory()
.select(Projections.fields(ApiStatsUI.class,
q.apiName,
q.totalCnt.sum().as("totalCnt"),
q.successCnt.sum().as("successCnt"),
q.timeoutCnt.sum().as("timeoutCnt"),
q.systemErrCnt.sum().as("systemErrCnt"),
q.bizErrCnt.sum().as("bizErrCnt"),
q.seq900TimeoutCnt.sum().as("seq900TimeoutCnt"),
q.seq900SystemErrCnt.sum().as("seq900SystemErrCnt"),
q.seq900BizErrCnt.sum().as("seq900BizErrCnt"),
q.minRespTime.min().castToNum(BigDecimal.class).as("minRespTime"),
q.maxRespTime.max().castToNum(BigDecimal.class).as("maxRespTime"),
Expressions.cases()
.when(q.successCnt.sum().gt(0))
.then(q.avgRespTime.multiply(q.successCnt).sum()
.divide(q.successCnt.sum()).castToNum(BigDecimal.class))
.otherwise((BigDecimal) null)
.as("avgRespTime")))
.from(q)
.where(builder)
.groupBy(q.apiName)
.orderBy(q.apiName.asc())
.fetch();
// 소수점 3자리로 반올림
results.forEach(ui -> {
if (ui.getAvgRespTime() != null) {
ui.setAvgRespTime(ui.getAvgRespTime().setScale(3, RoundingMode.HALF_UP));
}
if (ui.getMinRespTime() != null) {
ui.setMinRespTime(ui.getMinRespTime().setScale(3, RoundingMode.HALF_UP));
}
if (ui.getMaxRespTime() != null) {
ui.setMaxRespTime(ui.getMaxRespTime().setScale(3, RoundingMode.HALF_UP));
}
});
return results;
}
private BooleanBuilder buildSearchConditions(QApiStatsYear q, ApiStatsSearch search) {
BooleanBuilder builder = new BooleanBuilder();
@@ -63,6 +63,12 @@ public class ApiStatsDayController {
return ResponseEntity.ok(chartData);
}
@PostMapping(value = "/onl/kjb/statistics/apiStatsDayMan.json", params = "cmd=LIST_SUMMARY")
public ResponseEntity<GridResponse<ApiStatsUI>> selectSummaryList(ApiStatsSearch search, Pageable pageable) {
Page<ApiStatsUI> page = service.selectSummaryList(search, pageable);
return ResponseEntity.ok(new GridResponse<>(page));
}
@PostMapping(value = "/onl/kjb/statistics/apiStatsDayMan.json", params = "cmd=EXCEL_EXPORT")
public void exportToExcel(ApiStatsSearch search, HttpServletResponse response) throws IOException {
log.info("Excel export started - search: {}", search);
@@ -106,10 +112,55 @@ public class ApiStatsDayController {
}
}
@PostMapping(value = "/onl/kjb/statistics/apiStatsDayMan.json", params = "cmd=EXCEL_EXPORT_SUMMARY")
public void exportSummaryToExcel(ApiStatsSearch search, HttpServletResponse response) throws IOException {
log.info("Excel export (summary) started - search: {}", search);
try {
List<ApiStatsUI> dataList = service.selectSummaryListForExcel(search);
log.info("Summary data retrieved - count: {}", dataList.size());
if (dataList.isEmpty()) {
log.warn("No data found for export");
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
response.setContentType("application/json; charset=UTF-8");
response.getWriter().write("{\"message\":\"조회된 데이터가 없습니다.\"}");
response.getWriter().flush();
return;
}
String fileName = generateSummaryFileName(search);
log.info("Generating Excel file: {}", fileName);
excelExportService.exportApiStats(dataList, fileName, response);
log.info("Excel export (summary) completed successfully");
} catch (Exception e) {
log.error("Excel export (summary) failed - error: {}", e.getMessage(), e);
if (!response.isCommitted()) {
response.reset();
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.setContentType("application/json; charset=UTF-8");
response.getWriter().write("{\"message\":\"Excel 파일 생성 중 오류가 발생했습니다: " + e.getMessage() + "\"}");
response.getWriter().flush();
} else {
log.error("Cannot send error response - response already committed");
}
}
}
private String generateFileName(ApiStatsSearch search) {
String timeRange = StringUtils.isNotBlank(search.getSearchStartDateTime())
? search.getSearchStartDateTime()
: LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
return "API일별통계_" + timeRange + ".xlsx";
}
private String generateSummaryFileName(ApiStatsSearch search) {
String timeRange = StringUtils.isNotBlank(search.getSearchStartDateTime())
? search.getSearchStartDateTime()
: LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
return "API일별통계_요약_" + timeRange + ".xlsx";
}
}
@@ -63,6 +63,12 @@ public class ApiStatsHourController {
return ResponseEntity.ok(chartData);
}
@PostMapping(value = "/onl/kjb/statistics/apiStatsHourMan.json", params = "cmd=LIST_SUMMARY")
public ResponseEntity<GridResponse<ApiStatsUI>> selectSummaryList(ApiStatsSearch search, Pageable pageable) {
Page<ApiStatsUI> page = service.selectSummaryList(search, pageable);
return ResponseEntity.ok(new GridResponse<>(page));
}
@PostMapping(value = "/onl/kjb/statistics/apiStatsHourMan.json", params = "cmd=EXCEL_EXPORT")
public void exportToExcel(ApiStatsSearch search, HttpServletResponse response) throws IOException {
log.info("Excel export started - search: {}", search);
@@ -106,10 +112,55 @@ public class ApiStatsHourController {
}
}
@PostMapping(value = "/onl/kjb/statistics/apiStatsHourMan.json", params = "cmd=EXCEL_EXPORT_SUMMARY")
public void exportSummaryToExcel(ApiStatsSearch search, HttpServletResponse response) throws IOException {
log.info("Excel export (summary) started - search: {}", search);
try {
List<ApiStatsUI> dataList = service.selectSummaryListForExcel(search);
log.info("Summary data retrieved - count: {}", dataList.size());
if (dataList.isEmpty()) {
log.warn("No data found for export");
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
response.setContentType("application/json; charset=UTF-8");
response.getWriter().write("{\"message\":\"조회된 데이터가 없습니다.\"}");
response.getWriter().flush();
return;
}
String fileName = generateSummaryFileName(search);
log.info("Generating Excel file: {}", fileName);
excelExportService.exportApiStats(dataList, fileName, response);
log.info("Excel export (summary) completed successfully");
} catch (Exception e) {
log.error("Excel export (summary) failed - error: {}", e.getMessage(), e);
if (!response.isCommitted()) {
response.reset();
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.setContentType("application/json; charset=UTF-8");
response.getWriter().write("{\"message\":\"Excel 파일 생성 중 오류가 발생했습니다: " + e.getMessage() + "\"}");
response.getWriter().flush();
} else {
log.error("Cannot send error response - response already committed");
}
}
}
private String generateFileName(ApiStatsSearch search) {
String timeRange = StringUtils.isNotBlank(search.getSearchStartDateTime())
? search.getSearchStartDateTime()
: LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHH"));
return "API시간별통계_" + timeRange + ".xlsx";
}
private String generateSummaryFileName(ApiStatsSearch search) {
String timeRange = StringUtils.isNotBlank(search.getSearchStartDateTime())
? search.getSearchStartDateTime()
: LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHH"));
return "API시간별통계_요약_" + timeRange + ".xlsx";
}
}
@@ -63,6 +63,12 @@ public class ApiStatsMinuteController {
return ResponseEntity.ok(chartData);
}
@PostMapping(value = "/onl/kjb/statistics/apiStatsMinuteMan.json", params = "cmd=LIST_SUMMARY")
public ResponseEntity<GridResponse<ApiStatsUI>> selectSummaryList(ApiStatsSearch search, Pageable pageable) {
Page<ApiStatsUI> page = service.selectSummaryList(search, pageable);
return ResponseEntity.ok(new GridResponse<>(page));
}
@PostMapping(value = "/onl/kjb/statistics/apiStatsMinuteMan.json", params = "cmd=EXCEL_EXPORT")
public void exportToExcel(ApiStatsSearch search, HttpServletResponse response) throws IOException {
log.info("Excel export started - search: {}", search);
@@ -106,10 +112,55 @@ public class ApiStatsMinuteController {
}
}
@PostMapping(value = "/onl/kjb/statistics/apiStatsMinuteMan.json", params = "cmd=EXCEL_EXPORT_SUMMARY")
public void exportSummaryToExcel(ApiStatsSearch search, HttpServletResponse response) throws IOException {
log.info("Excel export (summary) started - search: {}", search);
try {
List<ApiStatsUI> dataList = service.selectSummaryListForExcel(search);
log.info("Summary data retrieved - count: {}", dataList.size());
if (dataList.isEmpty()) {
log.warn("No data found for export");
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
response.setContentType("application/json; charset=UTF-8");
response.getWriter().write("{\"message\":\"조회된 데이터가 없습니다.\"}");
response.getWriter().flush();
return;
}
String fileName = generateSummaryFileName(search);
log.info("Generating Excel file: {}", fileName);
excelExportService.exportApiStats(dataList, fileName, response);
log.info("Excel export (summary) completed successfully");
} catch (Exception e) {
log.error("Excel export (summary) failed - error: {}", e.getMessage(), e);
if (!response.isCommitted()) {
response.reset();
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.setContentType("application/json; charset=UTF-8");
response.getWriter().write("{\"message\":\"Excel 파일 생성 중 오류가 발생했습니다: " + e.getMessage() + "\"}");
response.getWriter().flush();
} else {
log.error("Cannot send error response - response already committed");
}
}
}
private String generateFileName(ApiStatsSearch search) {
String timeRange = StringUtils.isNotBlank(search.getSearchStartDateTime())
? search.getSearchStartDateTime()
: LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
return "API분단위통계_" + timeRange + ".xlsx";
}
private String generateSummaryFileName(ApiStatsSearch search) {
String timeRange = StringUtils.isNotBlank(search.getSearchStartDateTime())
? search.getSearchStartDateTime()
: LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
return "API분단위통계_요약_" + timeRange + ".xlsx";
}
}
@@ -63,6 +63,12 @@ public class ApiStatsMonthController {
return ResponseEntity.ok(chartData);
}
@PostMapping(value = "/onl/kjb/statistics/apiStatsMonthMan.json", params = "cmd=LIST_SUMMARY")
public ResponseEntity<GridResponse<ApiStatsUI>> selectSummaryList(ApiStatsSearch search, Pageable pageable) {
Page<ApiStatsUI> page = service.selectSummaryList(search, pageable);
return ResponseEntity.ok(new GridResponse<>(page));
}
@PostMapping(value = "/onl/kjb/statistics/apiStatsMonthMan.json", params = "cmd=EXCEL_EXPORT")
public void exportToExcel(ApiStatsSearch search, HttpServletResponse response) throws IOException {
log.info("Excel export started - search: {}", search);
@@ -106,10 +112,55 @@ public class ApiStatsMonthController {
}
}
@PostMapping(value = "/onl/kjb/statistics/apiStatsMonthMan.json", params = "cmd=EXCEL_EXPORT_SUMMARY")
public void exportSummaryToExcel(ApiStatsSearch search, HttpServletResponse response) throws IOException {
log.info("Excel export (summary) started - search: {}", search);
try {
List<ApiStatsUI> dataList = service.selectSummaryListForExcel(search);
log.info("Summary data retrieved - count: {}", dataList.size());
if (dataList.isEmpty()) {
log.warn("No data found for export");
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
response.setContentType("application/json; charset=UTF-8");
response.getWriter().write("{\"message\":\"조회된 데이터가 없습니다.\"}");
response.getWriter().flush();
return;
}
String fileName = generateSummaryFileName(search);
log.info("Generating Excel file: {}", fileName);
excelExportService.exportApiStats(dataList, fileName, response);
log.info("Excel export (summary) completed successfully");
} catch (Exception e) {
log.error("Excel export (summary) failed - error: {}", e.getMessage(), e);
if (!response.isCommitted()) {
response.reset();
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.setContentType("application/json; charset=UTF-8");
response.getWriter().write("{\"message\":\"Excel 파일 생성 중 오류가 발생했습니다: " + e.getMessage() + "\"}");
response.getWriter().flush();
} else {
log.error("Cannot send error response - response already committed");
}
}
}
private String generateFileName(ApiStatsSearch search) {
String timeRange = StringUtils.isNotBlank(search.getSearchStartDateTime())
? search.getSearchStartDateTime()
: YearMonth.now().format(DateTimeFormatter.ofPattern("yyyyMM"));
return "API월별통계_" + timeRange + ".xlsx";
}
private String generateSummaryFileName(ApiStatsSearch search) {
String timeRange = StringUtils.isNotBlank(search.getSearchStartDateTime())
? search.getSearchStartDateTime()
: YearMonth.now().format(DateTimeFormatter.ofPattern("yyyyMM"));
return "API월별통계_요약_" + timeRange + ".xlsx";
}
}
@@ -62,6 +62,12 @@ public class ApiStatsYearController {
return ResponseEntity.ok(chartData);
}
@PostMapping(value = "/onl/kjb/statistics/apiStatsYearMan.json", params = "cmd=LIST_SUMMARY")
public ResponseEntity<GridResponse<ApiStatsUI>> selectSummaryList(ApiStatsSearch search, Pageable pageable) {
Page<ApiStatsUI> page = service.selectSummaryList(search, pageable);
return ResponseEntity.ok(new GridResponse<>(page));
}
@PostMapping(value = "/onl/kjb/statistics/apiStatsYearMan.json", params = "cmd=EXCEL_EXPORT")
public void exportToExcel(ApiStatsSearch search, HttpServletResponse response) throws IOException {
log.info("Excel export started - search: {}", search);
@@ -105,10 +111,55 @@ public class ApiStatsYearController {
}
}
@PostMapping(value = "/onl/kjb/statistics/apiStatsYearMan.json", params = "cmd=EXCEL_EXPORT_SUMMARY")
public void exportSummaryToExcel(ApiStatsSearch search, HttpServletResponse response) throws IOException {
log.info("Excel export (summary) started - search: {}", search);
try {
List<ApiStatsUI> dataList = service.selectSummaryListForExcel(search);
log.info("Summary data retrieved - count: {}", dataList.size());
if (dataList.isEmpty()) {
log.warn("No data found for export");
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
response.setContentType("application/json; charset=UTF-8");
response.getWriter().write("{\"message\":\"조회된 데이터가 없습니다.\"}");
response.getWriter().flush();
return;
}
String fileName = generateSummaryFileName(search);
log.info("Generating Excel file: {}", fileName);
excelExportService.exportApiStats(dataList, fileName, response);
log.info("Excel export (summary) completed successfully");
} catch (Exception e) {
log.error("Excel export (summary) failed - error: {}", e.getMessage(), e);
if (!response.isCommitted()) {
response.reset();
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.setContentType("application/json; charset=UTF-8");
response.getWriter().write("{\"message\":\"Excel 파일 생성 중 오류가 발생했습니다: " + e.getMessage() + "\"}");
response.getWriter().flush();
} else {
log.error("Cannot send error response - response already committed");
}
}
}
private String generateFileName(ApiStatsSearch search) {
String timeRange = StringUtils.isNotBlank(search.getSearchStartDateTime())
? search.getSearchStartDateTime()
: String.valueOf(Year.now().getValue());
return "API연간통계_" + timeRange + ".xlsx";
}
private String generateSummaryFileName(ApiStatsSearch search) {
String timeRange = StringUtils.isNotBlank(search.getSearchStartDateTime())
? search.getSearchStartDateTime()
: String.valueOf(Year.now().getValue());
return "API연간통계_요약_" + timeRange + ".xlsx";
}
}
@@ -25,6 +25,7 @@ import com.eactive.eai.rms.data.entity.onl.kjb.statistics.ApiStatsDayService;
import com.eactive.eai.rms.data.entity.onl.kjb.statistics.QApiStatsDay;
import com.eactive.eai.rms.data.entity.onl.kjb.statistics.QApiStatsMonth;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.impl.JPAQueryFactory;
/**
@@ -129,11 +130,26 @@ public class DailyToMonthlyAggregationJob implements Job {
qd.seq900TimeoutCnt.sum().as("seq900TimeoutCnt"),
qd.seq900SystemErrCnt.sum().as("seq900SystemErrCnt"),
qd.seq900BizErrCnt.sum().as("seq900BizErrCnt"),
qd.avgRespTime.avg().castToNum(BigDecimal.class).as("avgRespTime"),
Expressions.cases()
.when(qd.successCnt.sum().gt(0))
.then(qd.avgRespTime.multiply(qd.successCnt).sum()
.divide(qd.successCnt.sum()).castToNum(BigDecimal.class))
.otherwise((BigDecimal) null)
.as("avgRespTime"),
qd.minRespTime.min().castToNum(BigDecimal.class).as("minRespTime"),
qd.maxRespTime.max().castToNum(BigDecimal.class).as("maxRespTime"),
qd.p50RespTime.avg().castToNum(BigDecimal.class).as("p50RespTime"),
qd.p95RespTime.avg().castToNum(BigDecimal.class).as("p95RespTime")))
Expressions.cases()
.when(qd.successCnt.sum().gt(0))
.then(qd.p50RespTime.multiply(qd.successCnt).sum()
.divide(qd.successCnt.sum()).castToNum(BigDecimal.class))
.otherwise((BigDecimal) null)
.as("p50RespTime"),
Expressions.cases()
.when(qd.successCnt.sum().gt(0))
.then(qd.p95RespTime.multiply(qd.successCnt).sum()
.divide(qd.successCnt.sum()).castToNum(BigDecimal.class))
.otherwise((BigDecimal) null)
.as("p95RespTime")))
.from(qd)
.where(qd.statTime.goe(startDate)
.and(qd.statTime.loe(endDate)))
@@ -24,6 +24,7 @@ import com.eactive.eai.rms.data.entity.onl.kjb.statistics.ApiStatsHourService;
import com.eactive.eai.rms.data.entity.onl.kjb.statistics.QApiStatsDay;
import com.eactive.eai.rms.data.entity.onl.kjb.statistics.QApiStatsHour;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.impl.JPAQueryFactory;
/**
@@ -125,11 +126,26 @@ public class HourlyToDailyAggregationJob implements Job {
qh.seq900TimeoutCnt.sum().as("seq900TimeoutCnt"),
qh.seq900SystemErrCnt.sum().as("seq900SystemErrCnt"),
qh.seq900BizErrCnt.sum().as("seq900BizErrCnt"),
qh.avgRespTime.avg().castToNum(BigDecimal.class).as("avgRespTime"),
Expressions.cases()
.when(qh.successCnt.sum().gt(0))
.then(qh.avgRespTime.multiply(qh.successCnt).sum()
.divide(qh.successCnt.sum()).castToNum(BigDecimal.class))
.otherwise((BigDecimal) null)
.as("avgRespTime"),
qh.minRespTime.min().castToNum(BigDecimal.class).as("minRespTime"),
qh.maxRespTime.max().castToNum(BigDecimal.class).as("maxRespTime"),
qh.p50RespTime.avg().castToNum(BigDecimal.class).as("p50RespTime"),
qh.p95RespTime.avg().castToNum(BigDecimal.class).as("p95RespTime")))
Expressions.cases()
.when(qh.successCnt.sum().gt(0))
.then(qh.p50RespTime.multiply(qh.successCnt).sum()
.divide(qh.successCnt.sum()).castToNum(BigDecimal.class))
.otherwise((BigDecimal) null)
.as("p50RespTime"),
Expressions.cases()
.when(qh.successCnt.sum().gt(0))
.then(qh.p95RespTime.multiply(qh.successCnt).sum()
.divide(qh.successCnt.sum()).castToNum(BigDecimal.class))
.otherwise((BigDecimal) null)
.as("p95RespTime")))
.from(qh)
.where(qh.statTime.goe(startDateTime)
.and(qh.statTime.loe(endDateTime)))
@@ -23,6 +23,7 @@ import com.eactive.eai.rms.data.entity.onl.kjb.statistics.ApiStatsMonthService;
import com.eactive.eai.rms.data.entity.onl.kjb.statistics.QApiStatsMonth;
import com.eactive.eai.rms.data.entity.onl.kjb.statistics.QApiStatsYear;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.impl.JPAQueryFactory;
/**
@@ -127,11 +128,26 @@ public class MonthlyToYearlyAggregationJob implements Job {
qm.seq900TimeoutCnt.sum().as("seq900TimeoutCnt"),
qm.seq900SystemErrCnt.sum().as("seq900SystemErrCnt"),
qm.seq900BizErrCnt.sum().as("seq900BizErrCnt"),
qm.avgRespTime.avg().castToNum(BigDecimal.class).as("avgRespTime"),
Expressions.cases()
.when(qm.successCnt.sum().gt(0))
.then(qm.avgRespTime.multiply(qm.successCnt).sum()
.divide(qm.successCnt.sum()).castToNum(BigDecimal.class))
.otherwise((BigDecimal) null)
.as("avgRespTime"),
qm.minRespTime.min().castToNum(BigDecimal.class).as("minRespTime"),
qm.maxRespTime.max().castToNum(BigDecimal.class).as("maxRespTime"),
qm.p50RespTime.avg().castToNum(BigDecimal.class).as("p50RespTime"),
qm.p95RespTime.avg().castToNum(BigDecimal.class).as("p95RespTime")))
Expressions.cases()
.when(qm.successCnt.sum().gt(0))
.then(qm.p50RespTime.multiply(qm.successCnt).sum()
.divide(qm.successCnt.sum()).castToNum(BigDecimal.class))
.otherwise((BigDecimal) null)
.as("p50RespTime"),
Expressions.cases()
.when(qm.successCnt.sum().gt(0))
.then(qm.p95RespTime.multiply(qm.successCnt).sum()
.divide(qm.successCnt.sum()).castToNum(BigDecimal.class))
.otherwise((BigDecimal) null)
.as("p95RespTime")))
.from(qm)
.where(qm.statTime.goe(startMonth)
.and(qm.statTime.loe(endMonth)))