diff --git a/.gitignore b/.gitignore index db9bd29a..5970b8e8 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,7 @@ Thumbs.db .env.*.local application-local.yml application-secret.yml +metrics-collector/.env ### Docker (local testing) ### .dockerignore @@ -72,3 +73,8 @@ docker-compose.override.yml *.swo *~ !/CLAUDE.md + +### Metrics Collector ### +metrics-collector/venv/ +metrics-collector/*.pid +metrics-collector/wheels/ diff --git a/src/main/java/com/kamco/cd/kamcoback/common/enums/LayerType.java b/src/main/java/com/kamco/cd/kamcoback/common/enums/LayerType.java index f4fba751..4cff54f7 100644 --- a/src/main/java/com/kamco/cd/kamcoback/common/enums/LayerType.java +++ b/src/main/java/com/kamco/cd/kamcoback/common/enums/LayerType.java @@ -13,10 +13,9 @@ public enum LayerType implements EnumType { TILE("배경지도"), GEOJSON("객체데이터"), WMTS("타일레이어"), - WMS("지적도") - , KAMCO_WMS("국유인WMS") - , KAMCO_WMTS("국유인WMTS") - ; + WMS("지적도"), + KAMCO_WMS("국유인WMS"), + KAMCO_WMTS("국유인WMTS"); private final String desc; diff --git a/src/main/java/com/kamco/cd/kamcoback/layer/service/LayerService.java b/src/main/java/com/kamco/cd/kamcoback/layer/service/LayerService.java index 3372c7c7..a6849862 100644 --- a/src/main/java/com/kamco/cd/kamcoback/layer/service/LayerService.java +++ b/src/main/java/com/kamco/cd/kamcoback/layer/service/LayerService.java @@ -58,8 +58,8 @@ public class LayerService { @Transactional public UUID saveLayers(String type, LayerDto.AddReq dto) { LayerType layerType = - LayerType.from(type) - .orElseThrow(() -> new CustomApiException("BAD_REQUEST", HttpStatus.BAD_REQUEST)); + LayerType.from(type) + .orElseThrow(() -> new CustomApiException("BAD_REQUEST", HttpStatus.BAD_REQUEST)); switch (layerType) { case TILE, KAMCO_WMS, KAMCO_WMTS -> { @@ -169,21 +169,21 @@ public class LayerService { public List findLayerMapList(String type) { List layerMapDtoList = mapLayerCoreService.findLayerMapList(type); layerMapDtoList.forEach( - dto -> { - if (dto.getLayerType().equals("WMS")) { - dto.setUrl( - String.format( - "%s/%s/%s", - trimSlash(geoserverUrl), trimSlash(wmsPath), dto.getLayerType().toLowerCase())); - } else if (dto.getLayerType().equals("WMTS")) { - dto.setUrl( - String.format( - "%s/%s/%s", - trimSlash(geoserverUrl), - trimSlash(wmtsPath), - dto.getLayerType().toLowerCase())); - } - }); + dto -> { + if (dto.getLayerType().equals("WMS")) { + dto.setUrl( + String.format( + "%s/%s/%s", + trimSlash(geoserverUrl), trimSlash(wmsPath), dto.getLayerType().toLowerCase())); + } else if (dto.getLayerType().equals("WMTS")) { + dto.setUrl( + String.format( + "%s/%s/%s", + trimSlash(geoserverUrl), + trimSlash(wmtsPath), + dto.getLayerType().toLowerCase())); + } + }); return layerMapDtoList; } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/GpuMetricEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/GpuMetricEntity.java index 23f74a52..064553ac 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/GpuMetricEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/GpuMetricEntity.java @@ -11,37 +11,94 @@ import lombok.Getter; import lombok.Setter; import org.hibernate.annotations.ColumnDefault; +/** + * GPU 메트릭 엔티티 + * + *

서버의 GPU 성능 및 자원 사용량 메트릭 데이터를 저장하는 JPA 엔티티입니다. GPU 연산 사용률 및 메모리 사용량 등 GPU 리소스 모니터링 데이터를 관리합니다. + * + *

데이터 소스: nvidia-smi 명령어 또는 NVML (NVIDIA Management Library) + * + *

활용 사례: + * + *

+ */ @Getter @Setter @Entity @Table(name = "gpu_metrics") public class GpuMetricEntity { + /** 기본 키 (UUID, 자동 생성) */ @Id @ColumnDefault("gen_random_uuid()") @Column(name = "uuid", nullable = false) private UUID id; + /** 시퀀스 기반 보조 ID */ @NotNull @ColumnDefault("nextval('gpu_metrics_id_seq')") @Column(name = "id", nullable = false) private Integer id1; + /** 메트릭 수집 시각 (시간대 포함, 기본값: 현재 시각) */ @NotNull @ColumnDefault("now()") @Column(name = "\"timestamp\"", nullable = false) private OffsetDateTime timestamp; + /** 모니터링 대상 서버 이름 */ @NotNull @Column(name = "server_name", nullable = false, length = Integer.MAX_VALUE) private String serverName; + /** + * GPU 연산 사용률 (백분율) + * + *

GPU 코어의 연산 처리 활용도를 나타냅니다. + * + *

범위: 0.0 ~ 100.0 + * + *

예시: 85.5 = GPU가 85.5% 활용되어 연산 중 + * + *

데이터 소스: nvidia-smi의 'utilization.gpu' 또는 NVML의 nvmlDeviceGetUtilizationRates + * + *

참고: 높은 사용률(>90%)은 GPU가 충분히 활용되고 있음을 의미하며, 낮은 사용률은 병목 지점이 다른 곳(CPU, I/O)에 있을 수 있음 + */ @Column(name = "gpu_util") private Float gpuUtil; + /** + * GPU 메모리 사용량 (MB 단위) + * + *

현재 GPU에 할당되어 사용 중인 메모리 양 + * + *

예시: 10240.0 = 약 10GB의 GPU 메모리 사용 중 + * + *

데이터 소스: nvidia-smi의 'memory.used' 또는 NVML의 nvmlDeviceGetMemoryInfo + * + *

용도: 딥러닝 모델 크기, 배치 사이즈 최적화, OOM(Out Of Memory) 에러 예측 + */ @Column(name = "gpu_mem_used") private Float gpuMemUsed; + /** + * GPU 총 메모리 용량 (MB 단위) + * + *

GPU에 장착된 전체 메모리 용량 + * + *

예시: 16384.0 = 16GB VRAM 장착 + * + *

데이터 소스: nvidia-smi의 'memory.total' 또는 NVML의 nvmlDeviceGetMemoryInfo + * + *

계산식: 메모리 사용률(%) = (gpuMemUsed / gpuMemTotal) × 100 + * + *

활용: 여유 메모리 = gpuMemTotal - gpuMemUsed + */ @Column(name = "gpu_mem_total") private Float gpuMemTotal; } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/SystemMetricEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/SystemMetricEntity.java index 05e5bb02..27e8d67b 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/SystemMetricEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/SystemMetricEntity.java @@ -11,48 +11,101 @@ import lombok.Getter; import lombok.Setter; import org.hibernate.annotations.ColumnDefault; +/** + * 시스템 메트릭 엔티티 + * + *

서버 시스템의 성능 메트릭 데이터를 저장하는 JPA 엔티티입니다. CPU 및 메모리 사용량 등 시스템 리소스 모니터링 데이터를 관리합니다. + * + *

데이터 소스: Linux sar 명령어 또는 /proc/meminfo 파일 + * + *

활용 사례: + * + *

+ */ @Getter @Setter @Entity @Table(name = "system_metrics") public class SystemMetricEntity { + /** 기본 키 (UUID, 자동 생성) */ @Id @ColumnDefault("gen_random_uuid()") @Column(name = "uuid", nullable = false) private UUID id; + /** 시퀀스 기반 보조 ID */ @NotNull @ColumnDefault("nextval('system_metrics_id_seq')") @Column(name = "id", nullable = false) private Integer id1; + /** 메트릭 수집 시각 (시간대 포함) */ @NotNull @Column(name = "\"timestamp\"", nullable = false) private OffsetDateTime timestamp; + /** 모니터링 대상 서버 이름 */ @NotNull @Column(name = "server_name", nullable = false, length = Integer.MAX_VALUE) private String serverName; + /** 사용자 프로세스가 사용한 CPU 사용률 (%) - 응용 프로그램 실행 */ @Column(name = "cpu_user") private Float cpuUser; + /** 시스템 프로세스가 사용한 CPU 사용률 (%) - 커널 작업 */ @Column(name = "cpu_system") private Float cpuSystem; + /** I/O 대기로 소모된 CPU 사용률 (%) - 디스크/네트워크 대기 */ @Column(name = "cpu_iowait") private Float cpuIowait; + /** 유휴 상태 CPU 사용률 (%) - 사용 가능한 여유 CPU */ @Column(name = "cpu_idle") private Float cpuIdle; + /** + * 사용 가능한 여유 메모리 (KB 단위) + * + *

시스템에서 즉시 사용 가능한 물리 메모리 양 + * + *

예시: 4194304 = 약 4GB의 여유 메모리 + * + *

데이터 소스: /proc/meminfo의 MemFree + */ @Column(name = "kbmemfree") private Long kbmemfree; + /** + * 현재 사용 중인 메모리 (KB 단위) + * + *

시스템이 현재 할당하여 사용 중인 물리 메모리 양 + * + *

예시: 8388608 = 약 8GB의 사용 중인 메모리 + * + *

계산: MemTotal - MemFree + */ @Column(name = "kbmemused") private Long kbmemused; + /** + * 메모리 사용률 (백분율) + * + *

전체 메모리 대비 사용 중인 메모리 비율 + * + *

계산식: (kbmemused / (kbmemused + kbmemfree)) × 100 + * + *

예시: 66.7 = 전체 메모리의 66.7% 사용 중 + * + *

관계식: 총 메모리 = kbmemused + kbmemfree + */ @Column(name = "memused") private Float memused; }