Merge branch 'develop' into feat/infer_dev_260211
# Conflicts: # src/main/java/com/kamco/cd/kamcoback/common/inference/utils/GeoJsonValidator.java
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -60,6 +60,7 @@ Thumbs.db
|
|||||||
.env.*.local
|
.env.*.local
|
||||||
application-local.yml
|
application-local.yml
|
||||||
application-secret.yml
|
application-secret.yml
|
||||||
|
metrics-collector/.env
|
||||||
|
|
||||||
### Docker (local testing) ###
|
### Docker (local testing) ###
|
||||||
.dockerignore
|
.dockerignore
|
||||||
@@ -72,3 +73,8 @@ docker-compose.override.yml
|
|||||||
*.swo
|
*.swo
|
||||||
*~
|
*~
|
||||||
!/CLAUDE.md
|
!/CLAUDE.md
|
||||||
|
|
||||||
|
### Metrics Collector ###
|
||||||
|
metrics-collector/venv/
|
||||||
|
metrics-collector/*.pid
|
||||||
|
metrics-collector/wheels/
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ public enum LayerType implements EnumType {
|
|||||||
TILE("배경지도"),
|
TILE("배경지도"),
|
||||||
GEOJSON("객체데이터"),
|
GEOJSON("객체데이터"),
|
||||||
WMTS("타일레이어"),
|
WMTS("타일레이어"),
|
||||||
WMS("지적도");
|
WMS("지적도"),
|
||||||
|
KAMCO_WMS("국유인WMS"),
|
||||||
|
KAMCO_WMTS("국유인WMTS");
|
||||||
|
|
||||||
private final String desc;
|
private final String desc;
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.HashSet;
|
import java.util.*;
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
@@ -151,7 +147,7 @@ public class GeoJsonValidator {
|
|||||||
Set<String> foundUnique = new HashSet<>();
|
Set<String> foundUnique = new HashSet<>();
|
||||||
|
|
||||||
// 중복된 scene_id 목록 (샘플 로그 출력용이라 순서 유지 가능한 LinkedHashSet 사용)
|
// 중복된 scene_id 목록 (샘플 로그 출력용이라 순서 유지 가능한 LinkedHashSet 사용)
|
||||||
Set<String> duplicates = new LinkedHashSet<>();
|
// Set<String> duplicates = new LinkedHashSet<>();
|
||||||
|
|
||||||
// scene_id가 null 또는 blank인 feature의 개수 (데이터 이상)
|
// scene_id가 null 또는 blank인 feature의 개수 (데이터 이상)
|
||||||
int nullIdCount = 0;
|
int nullIdCount = 0;
|
||||||
@@ -168,48 +164,24 @@ public class GeoJsonValidator {
|
|||||||
// "geometry": {...}
|
// "geometry": {...}
|
||||||
// }
|
// }
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
|
|
||||||
int sampleIdx = 0;
|
|
||||||
|
|
||||||
for (JsonNode feature : features) {
|
for (JsonNode feature : features) {
|
||||||
JsonNode props = feature.get("properties");
|
JsonNode props = feature.get("properties");
|
||||||
|
|
||||||
// properties가 있고 scene_id가 null이 아니면 텍스트로 읽음
|
// properties가 있고 scene_id가 null이 아니면 텍스트로 읽음
|
||||||
// 없으면 null 처리
|
// 없으면 null 처리
|
||||||
String sceneId =
|
String sceneId =
|
||||||
(props != null && props.hasNonNull("scene_id"))
|
(props != null && props.hasNonNull("scene_id")) ? props.get("scene_id").asText() : null;
|
||||||
? props.get("scene_id").asText().trim()
|
|
||||||
: null;
|
|
||||||
|
|
||||||
log.info("========== sceneId : {}", sceneId);
|
|
||||||
|
|
||||||
if (sampleIdx < 5) {
|
|
||||||
log.info(
|
|
||||||
"[DEBUG] feature sample idx={}, propsExists={}, sceneId={}",
|
|
||||||
sampleIdx,
|
|
||||||
props != null,
|
|
||||||
sceneId);
|
|
||||||
sampleIdx++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// scene_id가 없거나 빈값이면 "정상적으로 도엽번호가 들어오지 않은 feature"로 카운트
|
// scene_id가 없거나 빈값이면 "정상적으로 도엽번호가 들어오지 않은 feature"로 카운트
|
||||||
if (sceneId == null || sceneId.isBlank()) {
|
if (sceneId == null || sceneId.isBlank()) {
|
||||||
log.info("========== sceneId 가 없어 continue");
|
|
||||||
nullIdCount++; // 도엽번호가 없으면 증가
|
nullIdCount++; // 도엽번호가 없으면 증가
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// foundUnique.add(sceneId)가 false면 "이미 같은 값이 있었다"는 뜻 => 중복
|
// foundUnique.add(sceneId)가 false면 "이미 같은 값이 있었다"는 뜻 => 중복
|
||||||
boolean added = foundUnique.add(sceneId);
|
// if (!foundUnique.add(sceneId)) {
|
||||||
|
// duplicates.add(sceneId);
|
||||||
if (sampleIdx <= 5) {
|
// }
|
||||||
log.info("[DEBUG] sceneId={}, added={}", sceneId, added);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!added) {
|
|
||||||
log.info("========== foundUnique add가 안되어 duplicates 에 add");
|
|
||||||
duplicates.add(sceneId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========================================================
|
// =========================================================
|
||||||
@@ -237,38 +209,33 @@ public class GeoJsonValidator {
|
|||||||
// =========================================================
|
// =========================================================
|
||||||
log.info(
|
log.info(
|
||||||
"""
|
"""
|
||||||
===== GeoJSON Validation =====
|
===== GeoJSON Validation =====
|
||||||
file: {}
|
file: {}
|
||||||
features(total): {}
|
features(total): {}
|
||||||
requested(unique): {}
|
requested(unique): {}
|
||||||
found(unique scene_id): {}
|
found(unique scene_id): {}
|
||||||
scene_id null/blank: {}
|
scene_id null/blank: {}
|
||||||
duplicates(scene_id): {}
|
duplicates(scene_id): {}
|
||||||
missing(requested - found): {}
|
missing(requested - found): {}
|
||||||
extra(found - requested): {}
|
extra(found - requested): {}
|
||||||
==============================
|
==============================
|
||||||
""",
|
""",
|
||||||
geojsonPath,
|
geojsonPath,
|
||||||
featureCount, // 중복 포함한 전체 feature 수
|
featureCount, // 중복 포함한 전체 feature 수
|
||||||
requested.size(), // 요청 도엽 유니크 수
|
requested.size(), // 요청 도엽 유니크 수
|
||||||
foundUnique.size(), // GeoJSON에서 발견된 scene_id 유니크 수
|
foundUnique.size(), // GeoJSON에서 발견된 scene_id 유니크 수
|
||||||
nullIdCount, // scene_id가 비어있는 feature 수
|
nullIdCount, // scene_id가 비어있는 feature 수
|
||||||
duplicates.size(), // 중복 scene_id 종류 수
|
0, // 중복 scene_id 종류 수
|
||||||
missing.size(), // 요청했지만 빠진 도엽 수
|
missing.size(), // 요청했지만 빠진 도엽 수
|
||||||
extra.size()); // 요청하지 않았는데 들어온 도엽 수
|
extra.size()); // 요청하지 않았는데 들어온 도엽 수
|
||||||
|
|
||||||
// 중복/누락/추가 항목은 전체를 다 찍으면 로그 폭발하므로 샘플만
|
// 중복/누락/추가 항목은 전체를 다 찍으면 로그 폭발하므로 샘플만
|
||||||
if (!duplicates.isEmpty()) {
|
// if (!duplicates.isEmpty())
|
||||||
log.warn("duplicates sample: {}", duplicates.stream().limit(20).toList());
|
// log.warn("duplicates sample: {}", duplicates.stream().limit(20).toList());
|
||||||
}
|
|
||||||
|
|
||||||
if (!missing.isEmpty()) {
|
if (!missing.isEmpty()) log.warn("missing sample: {}", missing.stream().limit(50).toList());
|
||||||
log.warn("missing sample: {}", missing.stream().limit(50).toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!extra.isEmpty()) {
|
if (!extra.isEmpty()) log.warn("extra sample: {}", extra.stream().limit(50).toList());
|
||||||
log.warn("extra sample: {}", extra.stream().limit(50).toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================
|
// =========================================================
|
||||||
// 6) 실패 조건 판정
|
// 6) 실패 조건 판정
|
||||||
@@ -283,12 +250,12 @@ public class GeoJsonValidator {
|
|||||||
// - 요청 문법은 맞지만(파일은 있고 JSON도 읽힘),
|
// - 요청 문법은 맞지만(파일은 있고 JSON도 읽힘),
|
||||||
// 내용(정합성)이 요구사항을 만족하지 못하는 경우에 적합.
|
// 내용(정합성)이 요구사항을 만족하지 못하는 경우에 적합.
|
||||||
// =========================================================
|
// =========================================================
|
||||||
if (!missing.isEmpty() || !extra.isEmpty() || !duplicates.isEmpty() || nullIdCount > 0) {
|
if (!missing.isEmpty() || !extra.isEmpty() || nullIdCount > 0) {
|
||||||
throw new ResponseStatusException(
|
throw new ResponseStatusException(
|
||||||
HttpStatus.UNPROCESSABLE_ENTITY,
|
HttpStatus.UNPROCESSABLE_ENTITY,
|
||||||
String.format(
|
String.format(
|
||||||
"GeoJSON validation failed: missing=%d, extra=%d, duplicates=%d, nullId=%d",
|
"GeoJSON validation failed: missing=%d, extra=%d, duplicates=%d, nullId=%d",
|
||||||
missing.size(), extra.size(), duplicates.size(), nullIdCount));
|
missing.size(), extra.size(), 0, nullIdCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 모든 조건을 통과하면 정상
|
// 모든 조건을 통과하면 정상
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ public class ExternalJarRunner {
|
|||||||
* @param mode
|
* @param mode
|
||||||
* <p>MERGED - batch-ids 에 해당하는 **모든 데이터를 하나의 Shapefile로 병합 생성,
|
* <p>MERGED - batch-ids 에 해당하는 **모든 데이터를 하나의 Shapefile로 병합 생성,
|
||||||
* <p>MAP_IDS - 명시적으로 전달한 map-ids만 대상으로 Shapefile 생성,
|
* <p>MAP_IDS - 명시적으로 전달한 map-ids만 대상으로 Shapefile 생성,
|
||||||
* <p>RESOLVE - batch-ids 기준으로 **JAR 내부에서 map_ids를 조회**한 뒤 Shapefile 생성
|
* <p>RESOLVE - batch-ids 기준으로 **JAR 내부에서 map_ids를 조회**한 뒤 Shapefile 생성 java -jar
|
||||||
|
* build/libs/shp-exporter.jar --spring.profiles.active=prod
|
||||||
*/
|
*/
|
||||||
public void run(String jarPath, String batchIds, String inferenceId, String mapIds, String mode) {
|
public void run(String jarPath, String batchIds, String inferenceId, String mapIds, String mode) {
|
||||||
List<String> args = new ArrayList<>();
|
List<String> args = new ArrayList<>();
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public class LayerService {
|
|||||||
.orElseThrow(() -> new CustomApiException("BAD_REQUEST", HttpStatus.BAD_REQUEST));
|
.orElseThrow(() -> new CustomApiException("BAD_REQUEST", HttpStatus.BAD_REQUEST));
|
||||||
|
|
||||||
switch (layerType) {
|
switch (layerType) {
|
||||||
case TILE -> {
|
case TILE, KAMCO_WMS, KAMCO_WMTS -> {
|
||||||
return mapLayerCoreService.saveTile(dto);
|
return mapLayerCoreService.saveTile(dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,37 +11,94 @@ import lombok.Getter;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.hibernate.annotations.ColumnDefault;
|
import org.hibernate.annotations.ColumnDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPU 메트릭 엔티티
|
||||||
|
*
|
||||||
|
* <p>서버의 GPU 성능 및 자원 사용량 메트릭 데이터를 저장하는 JPA 엔티티입니다. GPU 연산 사용률 및 메모리 사용량 등 GPU 리소스 모니터링 데이터를 관리합니다.
|
||||||
|
*
|
||||||
|
* <p>데이터 소스: nvidia-smi 명령어 또는 NVML (NVIDIA Management Library)
|
||||||
|
*
|
||||||
|
* <p>활용 사례:
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>AI/ML 학습 모니터링: 딥러닝 작업 중 GPU 활용도 추적
|
||||||
|
* <li>리소스 최적화: GPU 메모리 부족 또는 유휴 상태 감지
|
||||||
|
* <li>용량 계획: GPU 추가 필요 시점 예측
|
||||||
|
* <li>알림 설정: gpuUtil > 95% 또는 gpuMemUsed/gpuMemTotal > 90% 시 경고
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "gpu_metrics")
|
@Table(name = "gpu_metrics")
|
||||||
public class GpuMetricEntity {
|
public class GpuMetricEntity {
|
||||||
|
|
||||||
|
/** 기본 키 (UUID, 자동 생성) */
|
||||||
@Id
|
@Id
|
||||||
@ColumnDefault("gen_random_uuid()")
|
@ColumnDefault("gen_random_uuid()")
|
||||||
@Column(name = "uuid", nullable = false)
|
@Column(name = "uuid", nullable = false)
|
||||||
private UUID id;
|
private UUID id;
|
||||||
|
|
||||||
|
/** 시퀀스 기반 보조 ID */
|
||||||
@NotNull
|
@NotNull
|
||||||
@ColumnDefault("nextval('gpu_metrics_id_seq')")
|
@ColumnDefault("nextval('gpu_metrics_id_seq')")
|
||||||
@Column(name = "id", nullable = false)
|
@Column(name = "id", nullable = false)
|
||||||
private Integer id1;
|
private Integer id1;
|
||||||
|
|
||||||
|
/** 메트릭 수집 시각 (시간대 포함, 기본값: 현재 시각) */
|
||||||
@NotNull
|
@NotNull
|
||||||
@ColumnDefault("now()")
|
@ColumnDefault("now()")
|
||||||
@Column(name = "\"timestamp\"", nullable = false)
|
@Column(name = "\"timestamp\"", nullable = false)
|
||||||
private OffsetDateTime timestamp;
|
private OffsetDateTime timestamp;
|
||||||
|
|
||||||
|
/** 모니터링 대상 서버 이름 */
|
||||||
@NotNull
|
@NotNull
|
||||||
@Column(name = "server_name", nullable = false, length = Integer.MAX_VALUE)
|
@Column(name = "server_name", nullable = false, length = Integer.MAX_VALUE)
|
||||||
private String serverName;
|
private String serverName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPU 연산 사용률 (백분율)
|
||||||
|
*
|
||||||
|
* <p>GPU 코어의 연산 처리 활용도를 나타냅니다.
|
||||||
|
*
|
||||||
|
* <p>범위: 0.0 ~ 100.0
|
||||||
|
*
|
||||||
|
* <p>예시: 85.5 = GPU가 85.5% 활용되어 연산 중
|
||||||
|
*
|
||||||
|
* <p>데이터 소스: nvidia-smi의 'utilization.gpu' 또는 NVML의 nvmlDeviceGetUtilizationRates
|
||||||
|
*
|
||||||
|
* <p>참고: 높은 사용률(>90%)은 GPU가 충분히 활용되고 있음을 의미하며, 낮은 사용률은 병목 지점이 다른 곳(CPU, I/O)에 있을 수 있음
|
||||||
|
*/
|
||||||
@Column(name = "gpu_util")
|
@Column(name = "gpu_util")
|
||||||
private Float gpuUtil;
|
private Float gpuUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPU 메모리 사용량 (MB 단위)
|
||||||
|
*
|
||||||
|
* <p>현재 GPU에 할당되어 사용 중인 메모리 양
|
||||||
|
*
|
||||||
|
* <p>예시: 10240.0 = 약 10GB의 GPU 메모리 사용 중
|
||||||
|
*
|
||||||
|
* <p>데이터 소스: nvidia-smi의 'memory.used' 또는 NVML의 nvmlDeviceGetMemoryInfo
|
||||||
|
*
|
||||||
|
* <p>용도: 딥러닝 모델 크기, 배치 사이즈 최적화, OOM(Out Of Memory) 에러 예측
|
||||||
|
*/
|
||||||
@Column(name = "gpu_mem_used")
|
@Column(name = "gpu_mem_used")
|
||||||
private Float gpuMemUsed;
|
private Float gpuMemUsed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPU 총 메모리 용량 (MB 단위)
|
||||||
|
*
|
||||||
|
* <p>GPU에 장착된 전체 메모리 용량
|
||||||
|
*
|
||||||
|
* <p>예시: 16384.0 = 16GB VRAM 장착
|
||||||
|
*
|
||||||
|
* <p>데이터 소스: nvidia-smi의 'memory.total' 또는 NVML의 nvmlDeviceGetMemoryInfo
|
||||||
|
*
|
||||||
|
* <p>계산식: 메모리 사용률(%) = (gpuMemUsed / gpuMemTotal) × 100
|
||||||
|
*
|
||||||
|
* <p>활용: 여유 메모리 = gpuMemTotal - gpuMemUsed
|
||||||
|
*/
|
||||||
@Column(name = "gpu_mem_total")
|
@Column(name = "gpu_mem_total")
|
||||||
private Float gpuMemTotal;
|
private Float gpuMemTotal;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,48 +11,101 @@ import lombok.Getter;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.hibernate.annotations.ColumnDefault;
|
import org.hibernate.annotations.ColumnDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 시스템 메트릭 엔티티
|
||||||
|
*
|
||||||
|
* <p>서버 시스템의 성능 메트릭 데이터를 저장하는 JPA 엔티티입니다. CPU 및 메모리 사용량 등 시스템 리소스 모니터링 데이터를 관리합니다.
|
||||||
|
*
|
||||||
|
* <p>데이터 소스: Linux sar 명령어 또는 /proc/meminfo 파일
|
||||||
|
*
|
||||||
|
* <p>활용 사례:
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>용량 계획: 메모리 추가 필요 시점 예측
|
||||||
|
* <li>성능 모니터링: 메모리 부족 상황 감지
|
||||||
|
* <li>트렌드 분석: 시간대별 메모리 사용 패턴 파악
|
||||||
|
* <li>알림 설정: memused > 90% 시 경고
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "system_metrics")
|
@Table(name = "system_metrics")
|
||||||
public class SystemMetricEntity {
|
public class SystemMetricEntity {
|
||||||
|
|
||||||
|
/** 기본 키 (UUID, 자동 생성) */
|
||||||
@Id
|
@Id
|
||||||
@ColumnDefault("gen_random_uuid()")
|
@ColumnDefault("gen_random_uuid()")
|
||||||
@Column(name = "uuid", nullable = false)
|
@Column(name = "uuid", nullable = false)
|
||||||
private UUID id;
|
private UUID id;
|
||||||
|
|
||||||
|
/** 시퀀스 기반 보조 ID */
|
||||||
@NotNull
|
@NotNull
|
||||||
@ColumnDefault("nextval('system_metrics_id_seq')")
|
@ColumnDefault("nextval('system_metrics_id_seq')")
|
||||||
@Column(name = "id", nullable = false)
|
@Column(name = "id", nullable = false)
|
||||||
private Integer id1;
|
private Integer id1;
|
||||||
|
|
||||||
|
/** 메트릭 수집 시각 (시간대 포함) */
|
||||||
@NotNull
|
@NotNull
|
||||||
@Column(name = "\"timestamp\"", nullable = false)
|
@Column(name = "\"timestamp\"", nullable = false)
|
||||||
private OffsetDateTime timestamp;
|
private OffsetDateTime timestamp;
|
||||||
|
|
||||||
|
/** 모니터링 대상 서버 이름 */
|
||||||
@NotNull
|
@NotNull
|
||||||
@Column(name = "server_name", nullable = false, length = Integer.MAX_VALUE)
|
@Column(name = "server_name", nullable = false, length = Integer.MAX_VALUE)
|
||||||
private String serverName;
|
private String serverName;
|
||||||
|
|
||||||
|
/** 사용자 프로세스가 사용한 CPU 사용률 (%) - 응용 프로그램 실행 */
|
||||||
@Column(name = "cpu_user")
|
@Column(name = "cpu_user")
|
||||||
private Float cpuUser;
|
private Float cpuUser;
|
||||||
|
|
||||||
|
/** 시스템 프로세스가 사용한 CPU 사용률 (%) - 커널 작업 */
|
||||||
@Column(name = "cpu_system")
|
@Column(name = "cpu_system")
|
||||||
private Float cpuSystem;
|
private Float cpuSystem;
|
||||||
|
|
||||||
|
/** I/O 대기로 소모된 CPU 사용률 (%) - 디스크/네트워크 대기 */
|
||||||
@Column(name = "cpu_iowait")
|
@Column(name = "cpu_iowait")
|
||||||
private Float cpuIowait;
|
private Float cpuIowait;
|
||||||
|
|
||||||
|
/** 유휴 상태 CPU 사용률 (%) - 사용 가능한 여유 CPU */
|
||||||
@Column(name = "cpu_idle")
|
@Column(name = "cpu_idle")
|
||||||
private Float cpuIdle;
|
private Float cpuIdle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 사용 가능한 여유 메모리 (KB 단위)
|
||||||
|
*
|
||||||
|
* <p>시스템에서 즉시 사용 가능한 물리 메모리 양
|
||||||
|
*
|
||||||
|
* <p>예시: 4194304 = 약 4GB의 여유 메모리
|
||||||
|
*
|
||||||
|
* <p>데이터 소스: /proc/meminfo의 MemFree
|
||||||
|
*/
|
||||||
@Column(name = "kbmemfree")
|
@Column(name = "kbmemfree")
|
||||||
private Long kbmemfree;
|
private Long kbmemfree;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 현재 사용 중인 메모리 (KB 단위)
|
||||||
|
*
|
||||||
|
* <p>시스템이 현재 할당하여 사용 중인 물리 메모리 양
|
||||||
|
*
|
||||||
|
* <p>예시: 8388608 = 약 8GB의 사용 중인 메모리
|
||||||
|
*
|
||||||
|
* <p>계산: MemTotal - MemFree
|
||||||
|
*/
|
||||||
@Column(name = "kbmemused")
|
@Column(name = "kbmemused")
|
||||||
private Long kbmemused;
|
private Long kbmemused;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 메모리 사용률 (백분율)
|
||||||
|
*
|
||||||
|
* <p>전체 메모리 대비 사용 중인 메모리 비율
|
||||||
|
*
|
||||||
|
* <p>계산식: (kbmemused / (kbmemused + kbmemfree)) × 100
|
||||||
|
*
|
||||||
|
* <p>예시: 66.7 = 전체 메모리의 66.7% 사용 중
|
||||||
|
*
|
||||||
|
* <p>관계식: 총 메모리 = kbmemused + kbmemfree
|
||||||
|
*/
|
||||||
@Column(name = "memused")
|
@Column(name = "memused")
|
||||||
private Float memused;
|
private Float memused;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user