Skip to content

Commit fa1454e

Browse files
authored
Merge pull request #85 from Sysone-Final/feature/SYSONE-73-monitoring
fix:메트릭 수정 loadavg
2 parents 5949f59 + d7c2150 commit fa1454e

14 files changed

Lines changed: 223 additions & 187 deletions

src/main/java/org/example/finalbe/domains/equipment/domain/Equipment.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99
import java.math.BigDecimal;
1010
import java.time.LocalDate;
1111

12-
/**
13-
* 장비 엔티티
14-
*/
1512
@Entity
1613
@Table(name = "equipment", indexes = {
1714
@Index(name = "idx_equipment_company_id", columnList = "company_id")
@@ -28,7 +25,6 @@ public class Equipment extends BaseTimeEntity {
2825
@Column(name = "equipment_id")
2926
private Long id;
3027

31-
// ========== 회사 정보 ==========
3228
@Column(name = "company_id")
3329
private Long companyId;
3430

@@ -42,7 +38,6 @@ public class Equipment extends BaseTimeEntity {
4238
@Column(name = "equipment_type", length = 50)
4339
private EquipmentType type;
4440

45-
// 랙을 선택적으로 설정할 수 있도록 nullable = true로 변경
4641
@Column(name = "start_unit", nullable = true)
4742
private Integer startUnit;
4843

@@ -83,6 +78,10 @@ public class Equipment extends BaseTimeEntity {
8378
@Column(name = "power_consumption", precision = 10, scale = 2)
8479
private BigDecimal powerConsumption;
8580

81+
// ✅ 네트워크 대역폭 추가 (단위: Mbps)
82+
@Column(name = "network_bandwidth_mbps")
83+
private Integer networkBandwidthMbps;
84+
8685
@Enumerated(EnumType.STRING)
8786
@Column(name = "status", nullable = false, length = 50)
8887
private EquipmentStatus status;
@@ -93,7 +92,6 @@ public class Equipment extends BaseTimeEntity {
9392
@Column(name = "notes", length = 1000)
9493
private String notes;
9594

96-
// ========== 모니터링 설정 필드 ==========
9795
@Column(name = "monitoring_enabled")
9896
private Boolean monitoringEnabled;
9997

@@ -120,7 +118,6 @@ public class Equipment extends BaseTimeEntity {
120118
@Builder.Default
121119
private DelYN delYn = DelYN.N;
122120

123-
// 랙을 선택적으로 설정할 수 있도록 nullable = true로 변경
124121
@ManyToOne(fetch = FetchType.LAZY)
125122
@JoinColumn(name = "rack_id", nullable = true)
126123
private Rack rack;
@@ -195,4 +192,11 @@ public Long getRackId() {
195192
return rack != null ? rack.getId() : null;
196193
}
197194

195+
/**
196+
* ✅ 네트워크 대역폭 반환 (Mbps 단위)
197+
* null이면 기본값 1000Mbps (1Gbps) 반환
198+
*/
199+
public Integer getNetworkBandwidthMbpsOrDefault() {
200+
return networkBandwidthMbps != null ? networkBandwidthMbps : 1000;
201+
}
198202
}

src/main/java/org/example/finalbe/domains/history/service/EquipmentHistoryRecorder.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,6 @@ private Map<String, Object> buildSnapshot(Equipment equipment) {
280280
snapshot.put("manufacturer", equipment.getManufacturer());
281281
snapshot.put("serialNumber", equipment.getSerialNumber());
282282
snapshot.put("ipAddress", equipment.getIpAddress());
283-
snapshot.put("powerConsumption", equipment.getPowerConsumption());
284283
return snapshot;
285284
}
286285

src/main/java/org/example/finalbe/domains/monitoring/dto/DataCenterStatisticsDto.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ public class DataCenterStatisticsDto {
4141
private Double maxCpuUsage; // 최대 CPU 사용률 (%)
4242
private Double minCpuUsage; // 최소 CPU 사용률 (%)
4343
private Double avgLoadAvg1; // 평균 Load Average (1분)
44+
private Double avgLoadAvg5;
45+
private Double avgLoadAvg15;
4446

4547
// 메모리 통계 (평균)
4648
private Double avgMemoryUsage; // 평균 메모리 사용률 (%)

src/main/java/org/example/finalbe/domains/monitoring/dto/RackStatisticsDto.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public class RackStatisticsDto {
2222
private CpuStats cpuStats;
2323
private MemoryStats memoryStats;
2424
private DiskStats diskStats;
25+
private SystemLoadStats systemLoadStats;
2526
private NetworkStats networkStats;
2627

2728
@Getter
@@ -122,4 +123,20 @@ public static class TopEquipment {
122123
private String equipmentName;
123124
private Double value;
124125
}
126+
127+
// RackStatisticsDto.java에 inner class 추가
128+
129+
@Getter
130+
@Builder
131+
@NoArgsConstructor
132+
@AllArgsConstructor
133+
public static class SystemLoadStats {
134+
private Double avgLoadAvg1; // 평균 1분 부하
135+
private Double avgLoadAvg5; // 평균 5분 부하
136+
private Double avgLoadAvg15; // 평균 15분 부하
137+
private Double maxLoadAvg1; // 최대 1분 부하
138+
private Double maxLoadAvg5; // 최대 5분 부하
139+
private Double maxLoadAvg15; // 최대 15분 부하
140+
private Integer equipmentCount; // 측정 장비 수
141+
}
125142
}

src/main/java/org/example/finalbe/domains/monitoring/dto/ServerRoomStatisticsDto.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ public class ServerRoomStatisticsDto {
3232
private Double maxCpuUsage; // 최대 CPU 사용률 (%)
3333
private Double minCpuUsage; // 최소 CPU 사용률 (%)
3434
private Double avgLoadAvg1; // 평균 Load Average (1분)
35-
35+
private Double avgLoadAvg5;
36+
private Double avgLoadAvg15;
3637
// 메모리 통계 (평균)
3738
private Double avgMemoryUsage; // 평균 메모리 사용률 (%)
3839
private Double maxMemoryUsage; // 최대 메모리 사용률 (%)

src/main/java/org/example/finalbe/domains/monitoring/repository/SystemMetricRepository.java

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -420,20 +420,21 @@ List<SystemMetric> findRecentMetrics(
420420
);
421421

422422

423-
/**
424-
* 여러 장비의 평균 CPU 통계 조회
425-
*/
423+
// SystemMetricRepository.java
424+
426425
@Query(value = """
427-
SELECT
428-
AVG(100 - cpu_idle) as avgCpuUsage,
429-
MAX(100 - cpu_idle) as maxCpuUsage,
430-
MIN(100 - cpu_idle) as minCpuUsage,
431-
AVG(load_avg1) as avgLoadAvg1,
432-
COUNT(DISTINCT equipment_id) as equipmentCount
433-
FROM system_metrics
434-
WHERE equipment_id IN :equipmentIds
435-
AND generate_time BETWEEN :startTime AND :endTime
436-
""", nativeQuery = true)
426+
SELECT
427+
AVG(100 - cpu_idle) as avgCpuUsage,
428+
MAX(100 - cpu_idle) as maxCpuUsage,
429+
MIN(100 - cpu_idle) as minCpuUsage,
430+
AVG(load_avg1) as avgLoadAvg1,
431+
AVG(load_avg5) as avgLoadAvg5,
432+
AVG(load_avg15) as avgLoadAvg15,
433+
COUNT(DISTINCT equipment_id) as equipmentCount
434+
FROM system_metrics
435+
WHERE equipment_id IN :equipmentIds
436+
AND generate_time BETWEEN :startTime AND :endTime
437+
""", nativeQuery = true)
437438
Map<String, Object> getAverageCpuStatsByEquipmentIds(
438439
@Param("equipmentIds") List<Long> equipmentIds,
439440
@Param("startTime") LocalDateTime startTime,

src/main/java/org/example/finalbe/domains/monitoring/service/DataCenterMonitoringService.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,22 @@ public DataCenterStatisticsDto calculateDataCenterStatistics(Long dataCenterId)
122122
.average()
123123
.orElse(0.0);
124124

125+
126+
Double avgLoadAvg5 = serverRoomStats.stream()
127+
.map(ServerRoomStatisticsDto::getAvgLoadAvg5)
128+
.filter(val -> val != null)
129+
.mapToDouble(Double::doubleValue)
130+
.average()
131+
.orElse(0.0);
132+
133+
134+
Double avgLoadAvg15 = serverRoomStats.stream()
135+
.map(ServerRoomStatisticsDto::getAvgLoadAvg15)
136+
.filter(val -> val != null)
137+
.mapToDouble(Double::doubleValue)
138+
.average()
139+
.orElse(0.0);
140+
125141
// 5. 메모리 통계 집계
126142
Double avgMemoryUsage = serverRoomStats.stream()
127143
.map(ServerRoomStatisticsDto::getAvgMemoryUsage)
@@ -317,7 +333,6 @@ public DataCenterStatisticsDto calculateDataCenterStatistics(Long dataCenterId)
317333
.mapToInt(Integer::intValue)
318334
.sum();
319335

320-
// ❌ 10. 전력 통계 집계 - 삭제됨
321336

322337
// 11. 서버실별 요약 생성
323338
List<DataCenterStatisticsDto.ServerRoomSummaryDto> serverRoomSummaries = serverRoomStats.stream()
@@ -353,6 +368,8 @@ public DataCenterStatisticsDto calculateDataCenterStatistics(Long dataCenterId)
353368
.maxCpuUsage(maxCpuUsage)
354369
.minCpuUsage(minCpuUsage)
355370
.avgLoadAvg1(avgLoadAvg1)
371+
.avgLoadAvg5(avgLoadAvg5)
372+
.avgLoadAvg15(avgLoadAvg15)
356373
// 메모리 통계
357374
.avgMemoryUsage(avgMemoryUsage)
358375
.maxMemoryUsage(maxMemoryUsage)

src/main/java/org/example/finalbe/domains/monitoring/service/RackMonitoringService.java

Lines changed: 121 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -37,43 +37,6 @@ public class RackMonitoringService {
3737
private static final double DISK_WARNING_THRESHOLD = 70.0;
3838
private static final double DISK_CRITICAL_THRESHOLD = 90.0;
3939

40-
public RackStatisticsDto calculateRackStatistics(Long rackId) {
41-
log.debug("📊 랙 통계 계산 시작: rackId={}", rackId);
42-
43-
Rack rack = rackRepository.findById(rackId)
44-
.orElseThrow(() -> new IllegalArgumentException("랙을 찾을 수 없습니다: " + rackId));
45-
46-
LocalDateTime now = LocalDateTime.now();
47-
List<Equipment> equipments = equipmentRepository.findByRackIdAndDelYn(rackId, DelYN.N);
48-
49-
if (equipments.isEmpty()) {
50-
log.debug("⚠️ 랙에 활성 장비가 없습니다: rackId={}", rackId);
51-
return createEmptyStatistics(rack, now);
52-
}
53-
54-
List<Long> equipmentIds = equipments.stream()
55-
.map(Equipment::getId)
56-
.collect(Collectors.toList());
57-
58-
RackStatisticsDto.EnvironmentStats environmentStats = getEnvironmentStats(rackId);
59-
RackStatisticsDto.RackSummary rackSummary = calculateRackSummary(equipments, equipmentIds);
60-
RackStatisticsDto.CpuStats cpuStats = calculateCpuStats(equipments, equipmentIds);
61-
RackStatisticsDto.MemoryStats memoryStats = calculateMemoryStats(equipments, equipmentIds);
62-
RackStatisticsDto.DiskStats diskStats = calculateDiskStats(equipments, equipmentIds);
63-
RackStatisticsDto.NetworkStats networkStats = calculateNetworkStats(equipments, equipmentIds);
64-
65-
return RackStatisticsDto.builder()
66-
.rackId(rackId)
67-
.rackName(rack.getRackName())
68-
.timestamp(now)
69-
.environment(environmentStats)
70-
.rackSummary(rackSummary)
71-
.cpuStats(cpuStats)
72-
.memoryStats(memoryStats)
73-
.diskStats(diskStats)
74-
.networkStats(networkStats)
75-
.build();
76-
}
7740

7841
private RackStatisticsDto.EnvironmentStats getEnvironmentStats(Long rackId) {
7942
EnvironmentMetric metric = metricCache.getEnvironmentMetric(rackId).orElse(null);
@@ -451,6 +414,126 @@ private AggregatedNetworkMetric aggregateNicMetrics(List<NetworkMetric> nicMetri
451414
return result;
452415
}
453416

417+
418+
419+
private static class AggregatedNetworkMetric {
420+
double rxUsage = 0.0;
421+
double txUsage = 0.0;
422+
double inBytesPerSec = 0.0;
423+
double outBytesPerSec = 0.0;
424+
long inPktsTot = 0L;
425+
long outPktsTot = 0L;
426+
long inErrorPktsTot = 0L;
427+
long outErrorPktsTot = 0L;
428+
long inDiscardPktsTot = 0L;
429+
long outDiscardPktsTot = 0L;
430+
}
431+
432+
// RackMonitoringService.java
433+
434+
public RackStatisticsDto calculateRackStatistics(Long rackId) {
435+
log.debug("📊 랙 통계 계산 시작: rackId={}", rackId);
436+
437+
Rack rack = rackRepository.findById(rackId)
438+
.orElseThrow(() -> new IllegalArgumentException("랙을 찾을 수 없습니다: " + rackId));
439+
440+
LocalDateTime now = LocalDateTime.now();
441+
List<Equipment> equipments = equipmentRepository.findByRackIdAndDelYn(rackId, DelYN.N);
442+
443+
if (equipments.isEmpty()) {
444+
log.debug("⚠️ 랙에 활성 장비가 없습니다: rackId={}", rackId);
445+
return createEmptyStatistics(rack, now);
446+
}
447+
448+
List<Long> equipmentIds = equipments.stream()
449+
.map(Equipment::getId)
450+
.collect(Collectors.toList());
451+
452+
RackStatisticsDto.EnvironmentStats environmentStats = getEnvironmentStats(rackId);
453+
RackStatisticsDto.RackSummary rackSummary = calculateRackSummary(equipments, equipmentIds);
454+
RackStatisticsDto.CpuStats cpuStats = calculateCpuStats(equipments, equipmentIds);
455+
RackStatisticsDto.SystemLoadStats systemLoadStats = calculateSystemLoadStats(equipments, equipmentIds); // ✅ 추가
456+
RackStatisticsDto.MemoryStats memoryStats = calculateMemoryStats(equipments, equipmentIds);
457+
RackStatisticsDto.DiskStats diskStats = calculateDiskStats(equipments, equipmentIds);
458+
RackStatisticsDto.NetworkStats networkStats = calculateNetworkStats(equipments, equipmentIds);
459+
460+
return RackStatisticsDto.builder()
461+
.rackId(rackId)
462+
.rackName(rack.getRackName())
463+
.timestamp(now)
464+
.environment(environmentStats)
465+
.rackSummary(rackSummary)
466+
.cpuStats(cpuStats)
467+
.systemLoadStats(systemLoadStats) // ✅ 추가
468+
.memoryStats(memoryStats)
469+
.diskStats(diskStats)
470+
.networkStats(networkStats)
471+
.build();
472+
}
473+
474+
// ✅ 새로운 메서드 추가
475+
private RackStatisticsDto.SystemLoadStats calculateSystemLoadStats(
476+
List<Equipment> equipments, List<Long> equipmentIds) {
477+
478+
List<SystemMetric> metrics = new ArrayList<>();
479+
for (Long equipmentId : equipmentIds) {
480+
metricCache.getSystemMetric(equipmentId).ifPresent(metrics::add);
481+
}
482+
483+
if (metrics.isEmpty()) {
484+
return RackStatisticsDto.SystemLoadStats.builder().equipmentCount(0).build();
485+
}
486+
487+
// 1분 평균 부하
488+
double avgLoadAvg1 = metrics.stream()
489+
.filter(m -> m.getLoadAvg1() != null)
490+
.mapToDouble(SystemMetric::getLoadAvg1)
491+
.average()
492+
.orElse(0.0);
493+
494+
double maxLoadAvg1 = metrics.stream()
495+
.filter(m -> m.getLoadAvg1() != null)
496+
.mapToDouble(SystemMetric::getLoadAvg1)
497+
.max()
498+
.orElse(0.0);
499+
500+
// 5분 평균 부하
501+
double avgLoadAvg5 = metrics.stream()
502+
.filter(m -> m.getLoadAvg5() != null)
503+
.mapToDouble(SystemMetric::getLoadAvg5)
504+
.average()
505+
.orElse(0.0);
506+
507+
double maxLoadAvg5 = metrics.stream()
508+
.filter(m -> m.getLoadAvg5() != null)
509+
.mapToDouble(SystemMetric::getLoadAvg5)
510+
.max()
511+
.orElse(0.0);
512+
513+
// 15분 평균 부하
514+
double avgLoadAvg15 = metrics.stream()
515+
.filter(m -> m.getLoadAvg15() != null)
516+
.mapToDouble(SystemMetric::getLoadAvg15)
517+
.average()
518+
.orElse(0.0);
519+
520+
double maxLoadAvg15 = metrics.stream()
521+
.filter(m -> m.getLoadAvg15() != null)
522+
.mapToDouble(SystemMetric::getLoadAvg15)
523+
.max()
524+
.orElse(0.0);
525+
526+
return RackStatisticsDto.SystemLoadStats.builder()
527+
.avgLoadAvg1(avgLoadAvg1)
528+
.avgLoadAvg5(avgLoadAvg5)
529+
.avgLoadAvg15(avgLoadAvg15)
530+
.maxLoadAvg1(maxLoadAvg1)
531+
.maxLoadAvg5(maxLoadAvg5)
532+
.maxLoadAvg15(maxLoadAvg15)
533+
.equipmentCount(metrics.size())
534+
.build();
535+
}
536+
454537
private RackStatisticsDto createEmptyStatistics(Rack rack, LocalDateTime now) {
455538
return RackStatisticsDto.builder()
456539
.rackId(rack.getId())
@@ -465,22 +548,10 @@ private RackStatisticsDto createEmptyStatistics(Rack rack, LocalDateTime now) {
465548
.activeEquipmentTypes(Collections.emptyList())
466549
.build())
467550
.cpuStats(RackStatisticsDto.CpuStats.builder().equipmentCount(0).build())
551+
.systemLoadStats(RackStatisticsDto.SystemLoadStats.builder().equipmentCount(0).build()) // ✅ 추가
468552
.memoryStats(RackStatisticsDto.MemoryStats.builder().equipmentCount(0).build())
469553
.diskStats(RackStatisticsDto.DiskStats.builder().equipmentCount(0).build())
470554
.networkStats(RackStatisticsDto.NetworkStats.builder().equipmentCount(0).build())
471555
.build();
472556
}
473-
474-
private static class AggregatedNetworkMetric {
475-
double rxUsage = 0.0;
476-
double txUsage = 0.0;
477-
double inBytesPerSec = 0.0;
478-
double outBytesPerSec = 0.0;
479-
long inPktsTot = 0L;
480-
long outPktsTot = 0L;
481-
long inErrorPktsTot = 0L;
482-
long outErrorPktsTot = 0L;
483-
long inDiscardPktsTot = 0L;
484-
long outDiscardPktsTot = 0L;
485-
}
486557
}

0 commit comments

Comments
 (0)