- 수집할 매트릭 정보와 프로메테우스 Url 정보 입력: Prometheus가 설치되어있는 주소와 포트번호, 수집할 매트릭 정보의 key 값들을 각각의 독립적인 변수에 저장
String prometheusUrl = "http://133.186.215.103:9090";
String promQLQueryCpu = "libvirt_domain_info_cpu_time_seconds_total";
String promQLQueryMemory = "libvirt_domain_info_memory_usage_bytes";
String promQLQueryVirtualCpu = "libvirt_domain_info_virtual_cpus";
- 시간 범위 설정: startTime과 endTime를 사용하여 현재 시간으로부터 1시간 전까지의 데이터를 수집하도록 설정
→ 24시간 동안의 데이터를 수집하려면 startTime을 현재 시간에서 24시간 (24 * 3600000 밀리초) 전으로 설정
long endTime = System.currentTimeMillis(); // 현재 시간
long startTime = endTime - 3600000; // 60분 전 (* N을 통해 수집하고자 하는 시간 늘릴 수 있음)
- PromQL
RestTemplate restTemplate = new RestTemplate();
String prometheusQueryURLCpu = prometheusUrl + "/api/v1/query_range?query=" + promQLQueryCpu +
"&start=" + startTime / 1000 + "&end=" + endTime / 1000 + "&step=60"; // step=60은 1분 간격
- /api/v1/query_range: Prometheus API 엔드포인트 중 하나로, 범위를 지정하여 메트릭 데이터를 가져올 수 있다.
- promQLQueryCpu: 수집할 메트릭 이름
- startTime 및 endTime: startTime과 endTime의 값을 초 단위로 변환하여 URL에 포함
→ 밀리초에서 초 단위로 값을 변경해야하므로, 나누기 1000
- step=60: 데이터의 간격(step)을 설정
→ 60으로 설정되어 있으므로 1분 간격으로 데이터를 수집
- HTTP 요청: RestTemplate을 사용하여 Prometheus 서버로 HTTP GET 요청을 보내고, 서버로부터 반환된 응답을 받아온다.
ResponseEntity<String> responseCpu = restTemplate.getForEntity(prometheusQueryURLCpu, String.class);
- Status code 확인: HTTP 요청이 성공적으로 처리되었는지 확인하고, getBody()를 사용하여 응답 데이터를 문자열로 추출
if (responseCpu.getStatusCode().is2xxSuccessful()) {
String resultCpu = responseCpu.getBody();
}
- Parsing
ObjectMapper objectMapper = new ObjectMapper();
try {
JsonNode rootNodeCpu = objectMapper.readTree(resultCpu);
JsonNode dataNodeCpu = rootNodeCpu.get("data");
JsonNode resultNodeCpu = dataNodeCpu.get("result");
.
.
.
- ObjectMapper는 Jackson 라이브러리의 일부로, JSON 데이터를 Java 객체로 변환
- objectMapper.readTree(resultCpu): resultCpu 문자열을 JSON 구조로 파싱
- rootNodeCpu.get("data"): JsonNode 객체에서 "data" 필드를 찾아 해당 하위 노드를 반환
- dataNodeCpu.get("result"): "data" 하위 노드에서 "result" 필드를 찾아 그 내용을 추출
→ "result" 필드는 실제 메트릭 데이터를 포함하고 있는 노드
- 완성코드
package openstack.eco_stack.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.ResponseEntity;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
import java.util.List;
@Slf4j
public class PrometheusDataFetcher {
public static void main(String[] args) {
// Prometheus 서버 URL 및 수집할 매트릭 key
String prometheusUrl = "http://133.186.215.103:9090";
String promQLQueryCpu = "libvirt_domain_info_cpu_time_seconds_total";
String promQLQueryMemory = "libvirt_domain_info_memory_usage_bytes";
String promQLQueryVirtualCpu = "libvirt_domain_info_virtual_cpus";
long endTime = System.currentTimeMillis(); // 현재 시간
long startTime = endTime - 3600000; // 60분 전 (* N을 통해 수집하고자 하는 시간 늘릴 수 있음)
// PromQL
RestTemplate restTemplate = new RestTemplate();
String prometheusQueryURLCpu = prometheusUrl + "/api/v1/query_range?query=" + promQLQueryCpu +
"&start=" + startTime / 1000 + "&end=" + endTime / 1000 + "&step=60"; // step=60은 1분 간격
String prometheusQueryURLMemory = prometheusUrl + "/api/v1/query_range?query=" + promQLQueryMemory +
"&start=" + startTime / 1000 + "&end=" + endTime / 1000 + "&step=60"; // step=60은 1분 간격
String prometheusQueryURLVirtualCpu = prometheusUrl + "/api/v1/query_range?query=" + promQLQueryVirtualCpu +
"&start=" + startTime / 1000 + "&end=" + endTime / 1000 + "&step=60"; // step=60은 1분 간격
ResponseEntity<String> responseCpu = restTemplate.getForEntity(prometheusQueryURLCpu, String.class);
ResponseEntity<String> responseMemory = restTemplate.getForEntity(prometheusQueryURLMemory, String.class);
ResponseEntity<String> responseVirtualCpu = restTemplate.getForEntity(prometheusQueryURLVirtualCpu, String.class);
// 결과를 저장할 리스트
List<String> resultLines = new ArrayList<>();
// 출력
if (responseCpu.getStatusCode().is2xxSuccessful() && responseMemory.getStatusCode().is2xxSuccessful() && responseVirtualCpu.getStatusCode().is2xxSuccessful()) {
String resultCpu = responseCpu.getBody();
String resultMemory = responseMemory.getBody();
String resultVirtualCpu = responseVirtualCpu.getBody();
// JSON 파싱을 위한 ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
try {
JsonNode rootNodeCpu = objectMapper.readTree(resultCpu);
JsonNode dataNodeCpu = rootNodeCpu.get("data");
JsonNode resultNodeCpu = dataNodeCpu.get("result");
JsonNode rootNodeMemory = objectMapper.readTree(resultMemory);
JsonNode dataNodeMemory = rootNodeMemory.get("data");
JsonNode resultNodeMemory = dataNodeMemory.get("result");
JsonNode rootNodeVirtualCpu = objectMapper.readTree(resultVirtualCpu);
JsonNode dataNodeVirtualCpu = rootNodeVirtualCpu.get("data");
JsonNode resultNodeVirtualCpu = dataNodeVirtualCpu.get("result");
for (int i = 0; i < resultNodeCpu.size(); i++) {
// projectId 필드를 가져오기
String projectIdCpu = resultNodeCpu.get(i).get("metric").get("projectId").asText();
String projectIdMemory = resultNodeMemory.get(i).get("metric").get("projectId").asText();
String projectIdVirtualCpu = resultNodeVirtualCpu.get(i).get("metric").get("projectId").asText();
StringBuilder message = new StringBuilder();
message.append("Project ID: ").append(projectIdCpu).append("\n");
JsonNode valuesNodeCpu = resultNodeCpu.get(i).get("values");
JsonNode valuesNodeMemory = resultNodeMemory.get(i).get("values");
JsonNode valuesNodeVirtualCpu = resultNodeVirtualCpu.get(i).get("values");
// CPU TIME 출력
message.append("CPU TIME: ");
for (JsonNode valueNode : valuesNodeCpu) {
double cpuTime = valueNode.get(1).asDouble();
message.append(cpuTime).append(", ");
}
message.append("\n");
// VIRTUAL CPU 출력
message.append("VIRTUAL CPU: ");
for (JsonNode valueNode : valuesNodeVirtualCpu) {
double virtualCpu = valueNode.get(1).asDouble();
message.append(virtualCpu).append(", ");
}
message.append("\n");
// MEMORY USAGE 출력
message.append("MEMORY USAGE: ");
for (JsonNode valueNode : valuesNodeMemory) {
double memoryUsage = valueNode.get(1).asDouble();
message.append(memoryUsage).append(", ");
}
message.append("\n");
resultLines.add(message.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
} else {
System.err.println("HTTP 요청 실패: " + responseCpu.getStatusCode() + ", " + responseMemory.getStatusCode() + ", " + responseVirtualCpu.getStatusCode());
}
// 결과 출력
for (String line : resultLines) {
log.info(line);
}
}
}