모던 대시보드 패치
- ApexCharts 기반 실시간 모니터링 대시보드 - 어댑터/배치/서버/소켓/트랜잭션 모니터링 컴포넌트 - 처리량 계산 및 데이터 매핑 서비스
This commit is contained in:
@@ -0,0 +1,680 @@
|
||||
<%@ page language="java" contentType="text/html; charset=utf-8"%>
|
||||
|
||||
<!-- 인터페이스 로그 조회 모달 -->
|
||||
<div id="interfaceLogDetailModal" class="modal modal-modern">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h2 class="modal-title">인터페이스 로그 조회</h2>
|
||||
<span class="close-modal">×</span>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<!-- 인터페이스 정보 요약 -->
|
||||
<div class="interface-info-summary">
|
||||
<div class="info-card">
|
||||
<div class="info-header">
|
||||
<span class="info-label">인터페이스 ID</span>
|
||||
<span class="info-value" id="detail-interface-id">-</span>
|
||||
</div>
|
||||
<div class="info-content">
|
||||
<div class="info-row">
|
||||
<span class="info-label">발생시간</span>
|
||||
<span class="info-value" id="detail-error-time">-</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">인스턴스</span>
|
||||
<span class="info-value" id="detail-instance-name">-</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-card">
|
||||
<div class="info-header">
|
||||
<span class="info-label">오류 메시지</span>
|
||||
</div>
|
||||
<div class="info-content">
|
||||
<div class="error-message" id="detail-error-message">-</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 로그 리스트 -->
|
||||
<div class="log-list-container">
|
||||
<div class="log-list-header">
|
||||
<h3>관련 거래 로그</h3>
|
||||
<div class="log-search-controls">
|
||||
<div class="time-range-selector">
|
||||
<span>조회 시간:</span>
|
||||
<select id="log-time-range">
|
||||
<option value="1" selected>±1분</option>
|
||||
<option value="5">±5분</option>
|
||||
<option value="10">±10분</option>
|
||||
<option value="30">±30분</option>
|
||||
</select>
|
||||
</div>
|
||||
<button class="btn btn-primary refresh-logs-btn">
|
||||
<i class="bi bi-arrow-clockwise"></i> 새로고침
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="log-table-container">
|
||||
<table class="log-table" id="log-grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="narrow-column">처리번호</th>
|
||||
<th>거래키</th>
|
||||
<th>업무구분</th>
|
||||
<th>서비스명</th>
|
||||
<th>수신시간</th>
|
||||
<th>처리시간</th>
|
||||
<th>상태</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="log-grid-body">
|
||||
<!-- 로그 데이터가 동적으로 추가됩니다 -->
|
||||
<tr>
|
||||
<td colspan="7" class="empty-message">조회 버튼을 클릭하여 관련 로그를 검색하세요.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary close-modal-btn">닫기</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
/* 모달 기본 스타일 */
|
||||
.modal-modern {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
|
||||
.modal-modern .modal-content {
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
margin: 2% auto;
|
||||
padding: 0;
|
||||
width: 95%;
|
||||
max-width: 1200px;
|
||||
border: none;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
|
||||
animation: modalSlideUp 0.3s;
|
||||
}
|
||||
|
||||
@keyframes modalSlideUp {
|
||||
from {opacity: 0; transform: translateY(30px);}
|
||||
to {opacity: 1; transform: translateY(0);}
|
||||
}
|
||||
|
||||
.modal-modern .modal-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 1.5rem 2rem;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 16px 16px 0 0;
|
||||
}
|
||||
|
||||
.modal-modern .modal-title {
|
||||
margin: 0;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.modal-modern .close-modal {
|
||||
color: #aaa;
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.modal-modern .close-modal:hover {
|
||||
color: #333;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.modal-modern .modal-body {
|
||||
padding: 1.5rem 2rem;
|
||||
max-height: 75vh;
|
||||
overflow-y: auto;
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.modal-modern .modal-footer {
|
||||
padding: 1.2rem 2rem;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 1rem;
|
||||
border-radius: 0 0 16px 16px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/* 인터페이스 정보 요약 스타일 */
|
||||
.interface-info-summary {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 2fr;
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.info-card {
|
||||
background-color: #fff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.info-header {
|
||||
padding: 1rem;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.info-header .info-label {
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.info-header .info-value {
|
||||
font-weight: 600;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.info-content {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.info-row:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.info-row .info-label {
|
||||
color: #666;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.info-row .info-value {
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
padding: 0.5rem;
|
||||
background-color: rgba(220, 53, 69, 0.1);
|
||||
border-radius: 6px;
|
||||
color: #dc3545;
|
||||
font-family: monospace;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
max-height: 100px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* 로그 리스트 스타일 */
|
||||
.log-list-container {
|
||||
background-color: #fff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.log-list-header {
|
||||
padding: 1rem;
|
||||
background-color: #f8f9fa;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.log-list-header h3 {
|
||||
margin: 0;
|
||||
font-size: 1.2rem;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.log-search-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.time-range-selector {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.time-range-selector select {
|
||||
padding: 0.25rem 0.5rem;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.log-table-container {
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.log-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.log-table th {
|
||||
top: 0;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
padding: 0.75rem;
|
||||
text-align: left;
|
||||
font-weight: 800;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.log-table td {
|
||||
padding: 0.75rem;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.log-table tbody tr:hover {
|
||||
background-color: rgba(0, 0, 0, 0.03);
|
||||
}
|
||||
|
||||
.log-table .empty-message {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
color: #888;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* 로딩 인디케이터 */
|
||||
.loading-indicator {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
border: 4px solid rgba(0, 0, 0, 0.1);
|
||||
border-radius: 50%;
|
||||
border-top: 4px solid #007bff;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* 버튼 스타일 */
|
||||
.btn {
|
||||
padding: 0.5rem 1rem;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-weight: 500;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: #0069d9;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background-color: #6c757d;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background-color: #5a6268;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
/* 오류 상태 표시 */
|
||||
.table-status-badge {
|
||||
display: inline-block;
|
||||
padding: 0.25rem 0.5rem;
|
||||
border-radius: 4px;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
min-width: 60px;
|
||||
}
|
||||
|
||||
.table-status-error {
|
||||
background-color: #dc3545;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.table-status-normal {
|
||||
background-color: #28a745;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.log-table th.narrow-column {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.highlight-row {
|
||||
background-color: rgba(0, 123, 255, 0.1);
|
||||
}
|
||||
|
||||
/* 반응형 설정 */
|
||||
@media (max-width: 992px) {
|
||||
.interface-info-summary {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.modal-modern .modal-content {
|
||||
width: 98%;
|
||||
margin: 1% auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
// 모달 요소
|
||||
const modal = document.getElementById('interfaceLogDetailModal');
|
||||
const closeButtons = modal.querySelectorAll('.close-modal, .close-modal-btn');
|
||||
const refreshButton = modal.querySelector('.refresh-logs-btn');
|
||||
const timeRangeSelect = document.getElementById('log-time-range');
|
||||
|
||||
// 데이터 상태
|
||||
let currentInterfaceId = '';
|
||||
let currentErrorTime = '';
|
||||
let currentInstanceName = '';
|
||||
let currentErrorMessage = '';
|
||||
let currentServiceType = '';
|
||||
|
||||
// 모달 닫기 이벤트
|
||||
closeButtons.forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
modal.style.display = 'none';
|
||||
});
|
||||
});
|
||||
|
||||
// 모달 외부 클릭 시 닫기
|
||||
window.addEventListener('click', (event) => {
|
||||
if (event.target === modal) {
|
||||
modal.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
// 새로고침 버튼 이벤트
|
||||
refreshButton.addEventListener('click', () => {
|
||||
loadInterfaceLogs();
|
||||
});
|
||||
|
||||
// 로그 시간대 변경 이벤트
|
||||
timeRangeSelect.addEventListener('change', () => {
|
||||
loadInterfaceLogs();
|
||||
});
|
||||
|
||||
// 인터페이스 로그 로드 함수
|
||||
function loadInterfaceLogs() {
|
||||
if (!currentInterfaceId || !currentErrorTime) {
|
||||
showEmptyLogGrid("인터페이스 정보가 올바르지 않습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 로딩 표시
|
||||
showLoadingLogGrid();
|
||||
|
||||
// 시간 범위 계산
|
||||
const timeRangeMinutes = parseInt(timeRangeSelect.value);
|
||||
const errorDate = parseErrorDateTime(currentErrorTime);
|
||||
|
||||
if (!errorDate) {
|
||||
showEmptyLogGrid("시간 형식이 올바르지 않습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 시작 시간과 종료 시간 계산 (±timeRangeMinutes 분)
|
||||
const startTime = new Date(errorDate.getTime() - timeRangeMinutes * 60 * 1000);
|
||||
const endTime = new Date(errorDate.getTime() + timeRangeMinutes * 60 * 1000);
|
||||
|
||||
// API 호출 시간 형식으로 변환 (YYYYMMDDHHMMSS)
|
||||
const startTimeStr = formatDateTimeForApi(startTime);
|
||||
const endTimeStr = formatDateTimeForApi(endTime);
|
||||
|
||||
// ModernDashboardApi를 사용하여 로그 데이터 가져오기
|
||||
ModernDashboardApi.getInterfaceLogs(
|
||||
currentInterfaceId,
|
||||
startTimeStr,
|
||||
endTimeStr,
|
||||
currentServiceType,
|
||||
function(response) {
|
||||
if (response && response.rows) {
|
||||
updateLogGrid(response.rows);
|
||||
} else {
|
||||
showEmptyLogGrid("조회된 로그가 없습니다.");
|
||||
}
|
||||
},
|
||||
function(xhr, status, error) {
|
||||
console.error("로그 데이터 로드 실패:", error);
|
||||
showEmptyLogGrid("로그 데이터를 불러오는 중 오류가 발생했습니다.");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// 로그 그리드 업데이트
|
||||
function updateLogGrid(logs) {
|
||||
const tbody = document.getElementById('log-grid-body');
|
||||
|
||||
if (!logs || logs.length === 0) {
|
||||
showEmptyLogGrid("조회된 로그가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
let html = '';
|
||||
|
||||
logs.forEach(log => {
|
||||
const isError = log.ERRYN === 'Y';
|
||||
|
||||
// 시간 형식 변환 (YYYYMMDDHHMMSS -> YYYY-MM-DD HH:MM:SS)
|
||||
const recvTime = formatDateTime(log.MSGDPSTYMS_TMP);
|
||||
const procTime = formatDateTime(log.MSGPRCSSYMS);
|
||||
|
||||
html += '<tr>' +
|
||||
'<td>' + (log.LOGPRCSSSERNO || '-') + '</td>' +
|
||||
'<td>' + (log.KEYMGTMSGCTNT || '-') + '</td>' +
|
||||
'<td>' + (log.EAIBZWKDSTCD_TMP || '-') + '</td>' +
|
||||
'<td>' + (log.EAISVCNAME || '-') + '</td>' +
|
||||
'<td>' + (recvTime || '-') + '</td>' +
|
||||
'<td>' + (procTime || '-') + '</td>' +
|
||||
'<td><span class="table-status-badge ' + (isError ? 'table-status-error' : 'table-status-normal') + '">' +
|
||||
(isError ? '오류' : '정상') + '</span>' +
|
||||
'<input type="hidden" value="' + (log.EAISVCSERNO_TMP || '') + '"></td>' +
|
||||
'</tr>';
|
||||
});
|
||||
|
||||
tbody.innerHTML = html;
|
||||
|
||||
// 현재 인터페이스 ID를 포함한 행 강조 표시
|
||||
highlightRows(currentInterfaceId);
|
||||
}
|
||||
|
||||
// 특정 인터페이스 ID를 포함한 행 강조 표시
|
||||
function highlightRows(interfaceId) {
|
||||
if (!interfaceId) return;
|
||||
|
||||
const tbody = document.getElementById('log-grid-body');
|
||||
const rows = tbody.querySelectorAll('tr');
|
||||
|
||||
rows.forEach(row => {
|
||||
const cells = row.querySelectorAll('td');
|
||||
if (cells.length > 1) {
|
||||
const keyCell = cells[1].textContent;
|
||||
if (keyCell && keyCell.includes(interfaceId)) {
|
||||
row.classList.add('highlight-row');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 로딩 중 표시
|
||||
function showLoadingLogGrid() {
|
||||
const tbody = document.getElementById('log-grid-body');
|
||||
tbody.innerHTML =
|
||||
'<tr>' +
|
||||
'<td colspan="7">' +
|
||||
'<div class="loading-indicator">' +
|
||||
'<div class="loading-spinner"></div>' +
|
||||
'</div>' +
|
||||
'</td>' +
|
||||
'</tr>';
|
||||
}
|
||||
|
||||
// 빈 그리드 표시
|
||||
function showEmptyLogGrid(message) {
|
||||
const tbody = document.getElementById('log-grid-body');
|
||||
tbody.innerHTML =
|
||||
'<tr>' +
|
||||
'<td colspan="7" class="empty-message">' + (message || '조회된 데이터가 없습니다.') + '</td>' +
|
||||
'</tr>';
|
||||
}
|
||||
|
||||
// 시간 문자열 파싱 (예: "0312 10:52:32.009")
|
||||
function parseErrorDateTime(dateTimeStr) {
|
||||
try {
|
||||
if (!dateTimeStr) return new Date();
|
||||
|
||||
// "0312 10:52:32.009" 형식 처리
|
||||
if (dateTimeStr.includes(' ') && dateTimeStr.length >= 16) {
|
||||
const datePart = dateTimeStr.split(' ')[0]; // "0312"
|
||||
const timePart = dateTimeStr.split(' ')[1].split('.')[0]; // "10:52:32"
|
||||
|
||||
const month = parseInt(datePart.substring(0, 2));
|
||||
const day = parseInt(datePart.substring(2, 4));
|
||||
|
||||
const timeParts = timePart.split(':');
|
||||
const hour = parseInt(timeParts[0]);
|
||||
const minute = parseInt(timeParts[1]);
|
||||
const second = parseInt(timeParts[2]);
|
||||
|
||||
// 현재 연도 사용
|
||||
const currentYear = new Date().getFullYear();
|
||||
return new Date(currentYear, month - 1, day, hour, minute, second);
|
||||
}
|
||||
|
||||
// 기존 "2023-03-12 15:30:45" 형식 처리 (이전 코드 유지)
|
||||
const parts = dateTimeStr.split(/[- :]/);
|
||||
if (parts.length >= 6) {
|
||||
return new Date(parts[0], parts[1] - 1, parts[2], parts[3], parts[4], parts[5]);
|
||||
}
|
||||
return new Date();
|
||||
} catch (e) {
|
||||
console.error("날짜 파싱 오류:", e);
|
||||
return new Date();
|
||||
}
|
||||
}
|
||||
|
||||
// API 호출용 날짜 형식 변환 (YYYYMMDDHHMMSS)
|
||||
function formatDateTimeForApi(date) {
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
const hours = String(date.getHours()).padStart(2, '0');
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||
const seconds = String(date.getSeconds()).padStart(2, '0');
|
||||
|
||||
return '' + year + month + day + hours + minutes + seconds;
|
||||
}
|
||||
|
||||
// 화면 표시용 날짜 형식 변환 (YYYY-MM-DD HH:MM:SS)
|
||||
function formatDateTime(dateTimeStr) {
|
||||
if (!dateTimeStr || dateTimeStr.length < 14) return '';
|
||||
|
||||
const year = dateTimeStr.substr(0, 4);
|
||||
const month = dateTimeStr.substr(4, 2);
|
||||
const day = dateTimeStr.substr(6, 2);
|
||||
const hour = dateTimeStr.substr(8, 2);
|
||||
const minute = dateTimeStr.substr(10, 2);
|
||||
const second = dateTimeStr.substr(12, 2);
|
||||
|
||||
return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second;
|
||||
}
|
||||
|
||||
// 모달 열기 함수 (전역 스코프에 노출)
|
||||
window.openInterfaceLogDetailModal = function(interfaceId, errorTime, instanceName, errorMessage, serviceType) {
|
||||
// 데이터 설정
|
||||
currentInterfaceId = interfaceId || '';
|
||||
currentErrorTime = errorTime || '';
|
||||
currentInstanceName = instanceName || '';
|
||||
currentErrorMessage = errorMessage || '';
|
||||
currentServiceType = serviceType || '';
|
||||
|
||||
// 조회 기준 일/시 분리해서 표시
|
||||
let formattedErrorTime = currentErrorTime;
|
||||
if (currentErrorTime && currentErrorTime.includes(' ')) {
|
||||
const datePart = currentErrorTime.split(' ')[0]; // "0312"
|
||||
const timePart = currentErrorTime.split(' ')[1]; // "10:52:32.009"
|
||||
|
||||
// 월/일 형식으로 변환
|
||||
const month = datePart.substring(0, 2);
|
||||
const day = datePart.substring(2, 4);
|
||||
|
||||
formattedErrorTime = month + '월 ' + day + '일 ' + timePart;
|
||||
}
|
||||
|
||||
// UI 업데이트
|
||||
document.getElementById('detail-interface-id').textContent = currentInterfaceId;
|
||||
document.getElementById('detail-error-time').textContent = formattedErrorTime;
|
||||
document.getElementById('detail-instance-name').textContent = currentInstanceName;
|
||||
document.getElementById('detail-error-message').textContent = currentErrorMessage;
|
||||
|
||||
// 모달 표시
|
||||
modal.style.display = 'block';
|
||||
|
||||
// 로그 데이터 로드
|
||||
loadInterfaceLogs();
|
||||
};
|
||||
})();
|
||||
</script>
|
||||
Reference in New Issue
Block a user