Merge remote-tracking branch 'z-eactive/feature/modern-dashboard' into devs/dashboard

This commit is contained in:
Rinjae
2025-11-19 14:39:21 +09:00
7 changed files with 80 additions and 261 deletions
@@ -26,6 +26,8 @@
priorityMap.put("FEP", 2);
priorityMap.put("CGW", 3);
priorityMap.put("FGW", 4);
priorityMap.put("APIGW", 5);
priorityMap.put("BAP", 6);
Map<String,List<DataSourceType>> sortedMap = serverTypeMap.entrySet().stream()
.sorted(Comparator.comparingInt(e -> priorityMap.getOrDefault(e.getKey(), Integer.MAX_VALUE)))
@@ -29,6 +29,8 @@
priorityMap.put("FEP", 2);
priorityMap.put("CGW", 3);
priorityMap.put("FGW", 4);
priorityMap.put("APIGW", 5);
priorityMap.put("BAP", 6);
Map<String,List<DataSourceType>> sortedMap = serverTypeMap.entrySet().stream()
.sorted(Comparator.comparingInt(e -> priorityMap.getOrDefault(e.getKey(), Integer.MAX_VALUE)))
@@ -126,9 +126,9 @@
</script>
<style>
/* 1번 줄 (4:3:1 비율) - 서버 상태, 배치 처리 상태, 피크 처리 성능 */
/* 1번 줄 (5:3 비율) - 서버 상태, 배치 처리 상태 */
.first-row {
grid-template-columns: 4fr 3fr 1fr;
grid-template-columns: 5fr 3fr;
}
/* 2번 줄 (1:1 비율) - 거래 처리 집계, 실시간 트랜잭션 현황 */
@@ -177,9 +177,9 @@
<!-- 헤더 영역 -->
<jsp:include page="components/dashboard-header.jsp" />
<!-- 1번 줄 (4:3:1 비율) - 서버 상태, 배치 처리 상태, 피크 처리 성능 -->
<!-- 1번 줄 (5:3 비율) - 서버 상태, 배치 처리 상태 -->
<div class="dashboard-row first-row">
<!-- 서버 상태 섹션 (4/8 비율) -->
<!-- 서버 상태 섹션 (5/8 비율) -->
<div class="server-container">
<jsp:include page="components/dashboard-servers.jsp">
<jsp:param name="serverTypeMap" value="<%= serverTypeMap %>" />
@@ -192,9 +192,9 @@
</div>
<!-- 피크 처리 성능 섹션 (1/8 비율) -->
<div class="peak-container">
<%--<div class="peak-container">
<jsp:include page="components/dashboard-peak.jsp" />
</div>
</div>--%>
</div>
<!-- 2번 줄 (1:1 비율) - 거래 처리 집계, 실시간 트랜잭션 현황 -->
@@ -31,7 +31,6 @@ import com.eactive.eai.agent.command.Command;
import com.eactive.eai.data.entity.onl.server.EAIServer;
import com.eactive.eai.rms.data.entity.onl.property.PropertyService;
import com.eactive.eai.rms.data.entity.onl.server.EAIServerService;
import com.eactive.eai.rms.onl.common.util.K8sUtil;
/**
* 1. 기능 : 등록된 EAI Server 에 Command를 broadcast
@@ -222,6 +222,12 @@ public class ModernDashboardController {
@RequestMapping(path = "/modern-dashboard-api.do", params = "type=adapter-status")
@ResponseBody
public Map<String, Object> getAdapterStatus(@RequestParam(required = false) String serverName) {
// TODO: 디버그 완료 후 삭제
System.out.println("========================================");
System.out.println("[Dashboard Debug] getAdapterStatus API CALLED!");
System.out.println("========================================");
log.error("[Dashboard Debug] getAdapterStatus API CALLED - serverName: " + serverName);
Map<String, Object> response = new HashMap<>();
try {
// 서버 타입 목록 가져오기 (특정 서버 이름이 제공된 경우 해당 서버만 포함)
@@ -245,20 +251,64 @@ public class ModernDashboardController {
}
}
// TODO: 디버그 완료 후 아래 디버그 로그 전체 삭제 (라인 254-299)
// [Dashboard Debug] Check server list size
System.out.println("[Dashboard Debug] getAdapterStatus: Found " + (servers == null ? 0 : servers.size()) + " servers to check.");
log.error("[Dashboard Debug] getAdapterStatus: Found " + (servers == null ? 0 : servers.size()) + " servers to check.");
List<Map<String, Object>> serverAdapters = new ArrayList<>();
for (DataSourceType server : servers) {
System.out.println("[Dashboard Debug] Loop for server: " + server.getName());
log.error("[Dashboard Debug] Loop for server: " + server.getName());
// 서버 컨텍스트 설정
DataSourceContextHolder.setDataSourceType(server);
// 서버에 대한 인스턴스 목록 조회
System.out.println("[Dashboard Debug] Calling getEaiServerIpListDB...");
List<Map<String, String>> ipList = eaiServerInfoService.getEaiServerIpListDB();
System.out.println("[Dashboard Debug] Call to getEaiServerIpListDB finished. IP list size: " + (ipList == null ? 0 : ipList.size()));
log.error("[Dashboard Debug] Call to getEaiServerIpListDB finished. IP list size: " + (ipList == null ? 0 : ipList.size()));
// 어댑터 상태 목록 조회 (개별 인스턴스별 상태)
List<AdaptersVO> adaptersList = dashboardService.findAdapterStatusList(ipList);
System.out.println("[Dashboard Debug] adaptersList size: " + (adaptersList == null ? "null" : adaptersList.size()));
log.error("[Dashboard Debug] adaptersList size: " + (adaptersList == null ? "null" : adaptersList.size()));
// 어댑터별 상태 코드 로깅
if (adaptersList != null) {
for (int i = 0; i < adaptersList.size(); i++) {
AdaptersVO vo = adaptersList.get(i);
String debugMsg = "[Dashboard Debug] Adapter[" + i + "] - Host: " + vo.getHostName() +
", Instance: " + vo.getInstanceName() +
", Socket(3): " + vo.getSocket(3) +
", Socket2(3): " + vo.getSocket2(3) +
", Http(3): " + vo.getHttp(3) +
", Socket counts: [" + vo.getSocket(0) + "," + vo.getSocket(1) + "," + vo.getSocket(2) + "]" +
", Socket2 counts: [" + vo.getSocket2(0) + "," + vo.getSocket2(1) + "," + vo.getSocket2(2) + "]" +
", Http counts: [" + vo.getHttp(0) + "," + vo.getHttp(1) + "," + vo.getHttp(2) + "]";
System.out.println(debugMsg);
log.error(debugMsg);
}
}
// 어댑터 상태 집계 정보 생성
AdapterStatusSummaryContainerDTO summaryContainer = dataMapper.fromAdaptersVOList(adaptersList);
String socketSummary = "[Dashboard Debug] Summary - Socket: error=" + summaryContainer.getAdapterSummary("Socket").getErrorCount() +
", warning=" + summaryContainer.getAdapterSummary("Socket").getWarningCount() +
", normal=" + summaryContainer.getAdapterSummary("Socket").getNormalCount() +
", inactive=" + summaryContainer.getAdapterSummary("Socket").getInactiveCount() +
", overall=" + summaryContainer.getAdapterSummary("Socket").getOverallStatus();
String httpSummary = "[Dashboard Debug] Summary - HTTP: error=" + summaryContainer.getAdapterSummary("HTTP").getErrorCount() +
", warning=" + summaryContainer.getAdapterSummary("HTTP").getWarningCount() +
", normal=" + summaryContainer.getAdapterSummary("HTTP").getNormalCount() +
", inactive=" + summaryContainer.getAdapterSummary("HTTP").getInactiveCount() +
", overall=" + summaryContainer.getAdapterSummary("HTTP").getOverallStatus();
System.out.println(socketSummary);
System.out.println(httpSummary);
log.error(socketSummary);
log.error(httpSummary);
// TODO: 여기까지 디버그 로그 삭제
// 기존 방식의 어댑터 상태 정보도 함께 제공 (하위 호환성 유지)
AdaptersVO adaptersVO = dashboardService.findAdapterStatusTotalList(ipList);
@@ -5,11 +5,9 @@ import com.eactive.eai.rms.common.datasource.DataSourceContextHolder;
import com.eactive.eai.rms.common.datasource.DataSourceType;
import com.eactive.eai.rms.common.datasource.DataSourceTypeManager;
import com.eactive.eai.rms.common.util.CommonUtil;
import com.eactive.eai.rms.data.entity.onl.property.PropertyService;
import com.eactive.eai.rms.onl.common.service.DashboardTargetService;
import com.eactive.eai.rms.onl.common.service.EaiServerInfoService;
import com.eactive.eai.rms.onl.dashboard.repository.Dashboard2Repository;
import com.eactive.eai.rms.onl.tracking.vo.DbStaticsVo;
import com.eactive.eai.rms.onl.tracking.vo.MemStaticsVo;
import com.eactive.eai.rms.onl.vo.EAIEngineStatusVo;
import org.apache.log4j.Logger;
@@ -17,7 +15,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;
@@ -46,10 +43,6 @@ public class Dashboard2RepositoryService {
@Qualifier("dashboard2Repository")
private Dashboard2Repository dashboardRepository;
@Autowired
@Qualifier("propertyService")
private PropertyService propertyService;
// hostNames, instNames 초기화 여부
private boolean isInitHostInstName = false;
@@ -59,15 +52,6 @@ public class Dashboard2RepositoryService {
private boolean isInitTargetService = false;
private String dashTargetService = "" ;
// K8S 사용여부
private String agentMode;
@PostConstruct
public void init(){
// K8S 관련 로직 비활성화. DB 조회로 인한 오류를 막기 위해 agentMode를 항상 ""로 설정
this.agentMode = "";
}
public void initTargetService() {
if( isInitTargetService == false ) {
dashTargetService = getTargetService();
@@ -86,12 +70,7 @@ public class Dashboard2RepositoryService {
* ( 날짜가 변경선을 지난 경우 등에 해당한다. )
*/
public void initMemTrRepository() {
if("K8S".equalsIgnoreCase(this.agentMode)){
dashboardRepository.initRepository();
} else {
dashboardRepository.initMemTrRepository();
}
dashboardRepository.initMemTrRepository();
initHostInstNames(true, null);
initEaiSevrDstcd(true);
}
@@ -123,11 +102,6 @@ public class Dashboard2RepositoryService {
dashboardRepository.setInstNames(host, list);
}
public void setDataSourceInstNames(String host, Map<String, List<String>> putData ) {
dashboardRepository.setDataSourceInstNames(host, putData);
}
/**
* Repository 에 주어진 서비스를 키로 하여 메모리 거래현황 맵을 추가한다.
* @param service
@@ -137,7 +111,6 @@ public class Dashboard2RepositoryService {
dashboardRepository.setItsmDashTranInfo(service, map);
}
public void setItsmDashPeakdayInfo(String service, HashMap<String,String> map) {
dashboardRepository.setItsmDashPeakdayInfo(service, map);
}
@@ -151,10 +124,6 @@ public class Dashboard2RepositoryService {
return dashboardRepository.getItsmDashTranInfo(service);
}
public HashMap<String,String> getItsmDashPeakdayInfo(String service) {
return dashboardRepository.getItsmDashPeakdayInfo(service);
}
/**
* Repository 에 주어진 서비스를 키로 하여 메모리 거래현황 맵을 추가한다.
* @param service
@@ -194,39 +163,10 @@ public class Dashboard2RepositoryService {
dashboardRepository.setItsmDashTranInfoBatch2(batchCount2) ;
}
public void setItsmDashEaiBatchErrorList(HashMap<String,HashMap<String,String>> eaiBatchErrorList) {
dashboardRepository.setItsmDashEaiBatchErrorList(eaiBatchErrorList);
}
public void setItsmDashFepBatchErrorList(HashMap<String,HashMap<String,String>> fepBatchErrorList) {
dashboardRepository.setItsmDashFepBatchErrorList(fepBatchErrorList);
}
/**
* 주어진 서비스명으로 메모리에서 읽어온 맵을 리턴한다.
* @param service
* @return
*/
public List getItsmDashHourTranList(String service) {
return dashboardRepository.itsmDashHourTranList(service);
}
public List getItsmDashDayTranList(String service) {
return dashboardRepository.itsmDashDayTranList(service);
}
public HashMap<String, HashMap<String, String>> getItsmDashBizErrorMap() {
return dashboardRepository.itsmDashBizErrorMap();
}
public HashMap<String, HashMap<String, String>> getItsmDashTimeoutErrorMap() {
return dashboardRepository.itsmDashTimeoutErrorMap();
}
public HashMap<String, HashMap<String, String>> getItsmDashConnectErrorMap() {
return dashboardRepository.itsmDashConnectErrorMap();
}
public HashMap<String, HashMap<String, String>> getAllDashErrorMap() {
HashMap<String, HashMap<String, String>> result = new HashMap<>();
@@ -240,19 +180,6 @@ public class Dashboard2RepositoryService {
return result;
}
public HashMap<String,String> getItsmDashServerInstTotalProcMap(String service) {
return dashboardRepository.itsmDashServerInstTotalProcMap(service);
}
public String getItsmDashTranInfoBatch() {
return dashboardRepository.getItsmDashTranInfoBatch() ;
}
public String getItsmDashTranInfoBatch2() {
return dashboardRepository.getItsmDashTranInfoBatch2() ;
}
/**
* 대시보드타겟 서비스가 ALL 인경우 EAI 서버구분코드값을 정할때,
@@ -278,6 +205,10 @@ public class Dashboard2RepositoryService {
eaiSevrDstcd = DataSourceTypeManager.FEP ; // FEP
} else if( DataSourceTypeManager.OPA.equals(dataSourceType.getName()) ) {
eaiSevrDstcd = DataSourceTypeManager.OPA ; // OPA
} else if( DataSourceTypeManager.APIGW.equals(dataSourceType.getName()) ) {
eaiSevrDstcd = DataSourceTypeManager.APIGW ; // APIGW
} else if( DataSourceTypeManager.BAP.equals(dataSourceType.getName()) ) {
eaiSevrDstcd = DataSourceTypeManager.BAP ; // BAP
} else {
return map;
}
@@ -327,24 +258,6 @@ public class Dashboard2RepositoryService {
isInitEAISevrDstcd = true ;
}
/**
* 해당 서비스의 EAISvcName,EAISevrDstcd 맵을 리턴한다.
* @param dataSourceType
* @return
*/
public HashMap<String,String> getEAISevrDstcdMap(DataSourceType dataSourceType) {
return dashboardRepository.getRepoEAIServrDstcd(dataSourceType.getName());
}
/**
* 주어진 host 명이 포함된 DB 에서 읽어온 EAI서비스코드,서버구분코드 맵을 리턴한다.
* @param host
* @return
*/
public HashMap<String,String> getRepoEAIServrDstcdByHost(String host) {
return dashboardRepository.getRepoEAIServrDstcdByHost(host);
}
public DataSourceType getServiceTypeByHost(String host) {
return dashboardRepository.getServiceTypeByHost(host);
}
@@ -521,53 +434,6 @@ public class Dashboard2RepositoryService {
return totalVo;
}
/**
* 서비스별, 호스트별 거래건수 객체를 맵에 추가한다.
* @param service
* @param host
* @param vo
*/
public void setTradeVo(String service, String host, DbStaticsVo vo) {
dashboardRepository.setTradeVo(service, host, vo);
}
/**
* 주어진 서비스,호스트 에 대한 거래건수 객체를 리턴한다.
* @param service
* @param host
* @return
*/
public DbStaticsVo getTradeVo(String service, String host) {
return dashboardRepository.getTradeVo(service, host);
}
/**
* 주어진 서비스에 에 대한 거래건수 리스트를 리턴한다.
* @param service
* @return
*/
public List<DbStaticsVo> getTradeVo(String service) {
return dashboardRepository.getTradeVo(service);
}
/**
* 주어진 서비스에 대한 거래건수 의 합을 리턴한다.
* @param service
* @return
*/
public DbStaticsVo getTotalVo(String service) {
return dashboardRepository.getTotalVo(service);
}
public String getMaxProcTime() {
return dashboardRepository.getMaxProcTime();
}
public void setMaxProcTime( String fulltime ) {
dashboardRepository.setMaxProcTime( fulltime );
}
public void initHostAlive() {
if( dashboardRepository.isInitHostRepository() ) {
@@ -620,9 +486,6 @@ public class Dashboard2RepositoryService {
public List<String> getHostNames(String service) {
return dashboardRepository.getHostNames(service);
}
public List<String> getInstNames(String host) {
return dashboardRepository.getInstNames(host);
}
public boolean isHostAlive(String ipaddress, String port) {
return dashboardRepository.isHostAlive(ipaddress, port);
@@ -632,14 +495,6 @@ public class Dashboard2RepositoryService {
return dashboardRepository.isHostAlive(ipaddress);
}
public String getHostAlive(String ipaddress, String port) {
if( isHostAlive(ipaddress, port) ) {
return "1" ;
} else {
return "0" ;
}
}
// 해당 IP 의 인스턴스중 한개만 살아 있어도 true
public String getHostAlive( String ipaddress ) {
if( isHostAlive(ipaddress) ) {
@@ -649,12 +504,10 @@ public class Dashboard2RepositoryService {
}
}
public void setHostAlive(String ipaddress, String port, boolean alive) {
dashboardRepository.setHostAlive(ipaddress, port, alive);
}
public void setPeakTps(String service, String val) {
dashboardRepository.setPeakTps(service, val);
}
@@ -823,105 +676,12 @@ public class Dashboard2RepositoryService {
return targetSvc ;
}
// 주어진 데이터소스명을 기준으로 hostname list를 리턴한다.
public List<Map<String,String>> getDatasourceByHost(String datasourcName){
return dashboardRepository.getDatasourceByHost(datasourcName);
}
public MemStaticsVo getDashboardMemTradeVoByService(String datasourceName) {
MemStaticsVo totalVo = new MemStaticsVo();
List<MemStaticsVo> list = dashboardRepository.getDashboardMemTradeVoByService(datasourceName);
for( MemStaticsVo memStaticsVo : list ){
totalVo.add(memStaticsVo);
}
return totalVo;
}
// agent mode 가 k8s 일 경우 신규 프로세스를 아닐 경우 기존 프로세스를 수행한다.
public MemStaticsVo getMemTradeVoByService(String service){
MemStaticsVo memStaticsVo;
if("K8S".equalsIgnoreCase(this.agentMode)){
memStaticsVo = this.getDashboardMemTradeVoByService(service);
} else {
memStaticsVo = this.getDefaultMemTradeVoByService(service);
}
return memStaticsVo;
return this.getDefaultMemTradeVoByService(service);
}
// agent mode 가 k8s 일 경우 신규 프로세스를 아닐 경우 기존 프로세스를 수행한다.
public void initHostInstNames(boolean isForceOverwrite, EAIEngineStatusVo vo){
if("K8S".equalsIgnoreCase(this.agentMode)){
this.initDashboardHostInstNames(isForceOverwrite, vo);
} else {
this.initDefaultHostInstNames(isForceOverwrite);
}
}
public void initDashboardHostInstNames( boolean isForceOverwrite , EAIEngineStatusVo engineStatusVo) {
if( isForceOverwrite == false ) {
if( isInitHostInstName == true ) {
return ;
}
}
if( engineStatusVo == null ){
return;
}
List<Map<String,String>> listTmp;
List<String> hostList;
List<DataSourceType> serverTypes;
serverTypes = DataSourceTypeManager.getOnlineDataSourceTypes();
// GW 추가
if( DataSourceTypeManager.getDataSourceType("FGW") != null ){
serverTypes.add(DataSourceTypeManager.getDataSourceType("FGW"));
}
if( DataSourceTypeManager.getDataSourceType("CGW") != null ){
serverTypes.add(DataSourceTypeManager.getDataSourceType("CGW"));
}
for (DataSourceType d : serverTypes){
try {
DataSourceContextHolder.setDataSourceType(d);
String dataSource = engineStatusVo.getService().toUpperCase();
if( d.getName().equals(dataSource) ){
hostList = dashboardRepository.getHostNames(d.getName());
if(hostList == null){
hostList = new ArrayList<String>();
}
String host = engineStatusVo.getHostName();
String inst = engineStatusVo.getInstanceName();
hostList.add(host);
Map<String,List<String>> mapDataSourceInst = dashboardRepository.getDatasourceInstListByHostNm(host);
List<String> l = mapDataSourceInst.get(d.getName());
if( l == null ) {
l = new ArrayList<String>();
}
l.add( inst );
l = CommonUtil.getDistinctList(l, true);
mapDataSourceInst.put(d.getName(), l);
List<String> hostSide = CommonUtil.getDistinctList(hostList, true);
setHostNames(d.getName(), hostSide);
setDataSourceInstNames(host, mapDataSourceInst);
}
}
catch(Exception e) {
logger.warn("Fail to get DataSourceType = " + d.getJndiName(), e);
}
}
isInitHostInstName = true ;
this.initDefaultHostInstNames(isForceOverwrite);
}
}
@@ -8,17 +8,17 @@ import com.eactive.eai.rms.common.datasource.DataSourceTypeManager;
public class MemStaticsVo {
public final int MAX_LINE = 5 ; // MCI/MCU/EAI/FEP/OPA
public final int MAX_LINE = 7 ; // MCI/MCU/EAI/FEP/OPA/APIGW/BAP
public final int IN = 0 ;
public final int OUT = 1 ;
private String hostName ; // host name
private String instName ; // instance name
public int procs[] = {0,0,0,0,0};
public int timeouts[] = {0,0,0,0,0};
public int errors[] = {0,0,0,0,0};
public int serrors[] = {0,0,0,0,0};
public int procs[] = {0,0,0,0,0,0,0};
public int timeouts[] = {0,0,0,0,0,0,0};
public int errors[] = {0,0,0,0,0,0,0};
public int serrors[] = {0,0,0,0,0,0,0};
public static int getPos(DataSourceType dataSourceType) {
if( DataSourceTypeManager.MCI.equals(dataSourceType.getName()) ) { // MCI 대면
@@ -36,6 +36,12 @@ public class MemStaticsVo {
if( DataSourceTypeManager.OPA.equals(dataSourceType.getName()) ) { // OPA
return 4 ;
}
if( DataSourceTypeManager.APIGW.equals(dataSourceType.getName()) ) { // APIGW
return 5 ;
}
if( DataSourceTypeManager.BAP.equals(dataSourceType.getName()) ) { // BAP
return 6 ;
}
return -1 ;
}