@page "/monitoring" @attribute [Authorize] @inject HttpClient Http QuantEngine - 데이터 수집 모니터링
데이터 수집 모니터링 실시간 수집 작업 상태 및 에러 추적
진행 중인 작업 @RunningCount 완료 @CompletedCount 실패 @FailedCount 대기 중 @PendingCount
@if (RecentRuns.Count == 0) { 최근 실행 기록이 없습니다. } else { 실행 ID 시작 시간 종료 시간 상태 수집된 항목 작업 @context.RunId @context.StartTime.ToString("yyyy-MM-dd HH:mm:ss") @(context.EndTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "-") @context.Status @context.ItemCount 상세 }
@if (Errors.Count == 0) { 에러가 없습니다. } else { @foreach (var error in Errors) {
@error.Message @error.Timestamp.ToString("yyyy-MM-dd HH:mm:ss")
Run ID: @error.RunId @error.StackTrace
}
}
@foreach (var ticker in CollectionStatus) {
@ticker.Ticker @(ticker.IsSuccessful ? "성공" : "실패")
마지막 수집: @ticker.LastCollectionTime.ToString("yyyy-MM-dd HH:mm:ss") 데이터 포인트: @(ticker.DataPointCount)개
}
@code { // Status counts private int RunningCount = 2; private int CompletedCount = 156; private int FailedCount = 8; private int PendingCount = 5; // Recent runs private List RecentRuns = new(); // Errors private List Errors = new(); // Collection status private List CollectionStatus = new(); protected override async Task OnInitializedAsync() { await LoadData(); } private async Task LoadData() { // Load recent runs RecentRuns = new List { new RunModel { RunId = "RUN-2026-07-05-001", StartTime = DateTime.Now.AddMinutes(-45), EndTime = DateTime.Now.AddMinutes(-40), Status = "완료", ItemCount = 142 }, new RunModel { RunId = "RUN-2026-07-05-002", StartTime = DateTime.Now.AddMinutes(-30), EndTime = null, Status = "진행 중", ItemCount = 87 }, new RunModel { RunId = "RUN-2026-07-04-012", StartTime = DateTime.Now.AddHours(-8).AddMinutes(-15), EndTime = DateTime.Now.AddHours(-8).AddMinutes(-5), Status = "완료", ItemCount = 189 } }; // Load errors Errors = new List { new ErrorModel { RunId = "RUN-2026-07-04-011", Message = "API Rate Limit Exceeded", StackTrace = "Exception at CollectionService.FetchData()", Timestamp = DateTime.Now.AddHours(-2) }, new ErrorModel { RunId = "RUN-2026-07-03-015", Message = "Connection Timeout", StackTrace = "Exception at HttpClient.GetAsync()", Timestamp = DateTime.Now.AddHours(-5) } }; // Load collection status CollectionStatus = new List { new CollectionStatusModel { Ticker = "005930", IsSuccessful = true, LastCollectionTime = DateTime.Now.AddMinutes(-2), DataPointCount = 1450 }, new CollectionStatusModel { Ticker = "000660", IsSuccessful = true, LastCollectionTime = DateTime.Now.AddMinutes(-5), DataPointCount = 1203 }, new CollectionStatusModel { Ticker = "051910", IsSuccessful = false, LastCollectionTime = DateTime.Now.AddHours(-1), DataPointCount = 945 } }; await Task.CompletedTask; } private Color GetStatusColor(string status) => status switch { "완료" => Color.Success, "진행 중" => Color.Info, "실패" => Color.Error, _ => Color.Warning }; private async Task ViewRunDetails(RunModel run) { // View details dialog await Task.CompletedTask; } private class RunModel { public string RunId { get; set; } public DateTime StartTime { get; set; } public DateTime? EndTime { get; set; } public string Status { get; set; } public int ItemCount { get; set; } } private class ErrorModel { public string RunId { get; set; } public string Message { get; set; } public string StackTrace { get; set; } public DateTime Timestamp { get; set; } } private class CollectionStatusModel { public string Ticker { get; set; } public bool IsSuccessful { get; set; } public DateTime LastCollectionTime { get; set; } public int DataPointCount { get; set; } } }