1. Overview & IDEA - HW monitoring 2. Problem & PoC 3. DATA Design 4. Publisher 5. Database & logger 6. Visualization 7. ToBeContinue…?
Continue
우선 이전에는 MAC에서 본것이지만 ubuntu화면에서 명령어는 아래와 같은 프로그램을 보여준다.
top
Parser
그리고 이전에 코드2. Problem & PoC를 보게되면 코드는 크게 2가지 부분으로 나눠져 있다.
-
top process를 실행시키고 1초마다 출력하게 하면서 cpu, memory, process의 정보를 가져온다.
try {
lineNumber = 0;
p = Runtime.getRuntime().exec("top -b -n 1");
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((temp = br.readLine()) != null) {
if (lineNumber < 2) {
lineNumber++;
continue; }
String[] temp_str = temp.split("\\s+");
// PARSING
if (lineNumber == 2) { // parsing CPU
System.out.println(Arrays.toString(temp_str));
if (containsString(List.of(temp_str),"100")) {
lineNumber++;
continue; }
cpuDetail = new TotalCpuDetail(Float.parseFloat(temp_str[1]), Float.parseFloat(temp_str[3]));
// System.out.println(Arrays.toString(temp_str));
// System.out.println(cpuDetail.toString());
} else if (lineNumber == 3) { // parsing PhysMem
memDetail = new TotalMemDetail(Float.parseFloat(temp_str[7]), Float.parseFloat(temp_str[5]));
} else if (lineNumber > 6) { // parsing ProcessDetail;
if (Float.parseFloat(temp_str[9]) >= 1.0 ) {
TopProcessDetail topProcessDetail = new TopProcessDetail(Integer.parseInt(temp_str[1]), temp_str[12], Float.parseFloat(temp_str[9]), temp_str[11], Float.parseFloat(temp_str[10]), temp_str[8]);
topRateProcess.add(topProcessDetail);
}
}
lineNumber++;
}
p.waitFor();
p.destroy();
} catch (Exception e) {
throw new RuntimeException(e);
}
-
df라는 현재 디스크를 관리하는 창을 실행시키고 현재 disk정보를 가져오는 것이다.
// DF COMMAND HANDLER FOR DISK INFO
try {
p = Runtime.getRuntime().exec("df -h");
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
br.readLine(); // firstline like "Filesystem/Size/Used/Avail/Use%/Mounted on"
String[] tempDisk = br.readLine().split("\\s+");
String readDisk = tempDisk[2].substring(0, tempDisk[2].length()-1);
String writeDisk = tempDisk[3].substring(0, tempDisk[3].length()-1);
diskDetail = new TotalDiskDetail(Float.parseFloat(readDisk), Float.parseFloat(writeDisk));
p.waitFor();
p.destroy();
} catch (Exception e) {
throw new RuntimeException(e);
}
DATA Design
여기서 조금 설명을 첨언해야하는 경우인데 데이터를 string으로 보내는게 아니라 객체로 만들어서 출력을 하게 했는데 구조는 다음과 같다
HardWareUsageDAO
/ | \
TotalCpuDtail ... TotalMemDetail ... TotalDiskDetail
처음에 이렇게 계획을 한 이유는 객체로 데이터들을 핸들링 하게 되면 추후 유지관리에 이점이 있을 것이라 생각을 해서 데이터구조를 내가 짜고 우찬이에게 git을 통해 넘겨주는 방식으로 진행을 했다. 하지만 돌아봐서 생각을 해보면 문제있는데 아래와 같다.
- 데이터 구조가 계속 바뀌면 대응을 하기가 너무 어렵다.
- git을 통해서 아무리 협업을 한다고 하지만 변화될 수 있는 포인트가 너무 많고 interface처럼 약속을 하고 구현을 해도 변화에 대응을 일일이 해야하는 어려움이 존재한다.
- 만약 운영하던 도중 다른 정보를 추가하고 싶다면 또 일일이 객체를 만들어야하고 이에 맞춰서 파싱해야하는 비효율성이 분명히 존재한다.
- 직렬화 과정에서 조금 어려움이 있었다.
- 처음해보는 상황이었기 때문에 kafka로 직렬화 할때 kafka에서 역직렬화를 할때가 문제가 되었었는데, 기본적으로 json이나 stringSerializer를 사용하면 되는 것을 따로 만들어서 직렬화를 해줘야 했기 때문에 도움은 되었지만 그 공수에 비해 효과가 크지 않았던 기억이있다.
- 다만 보안의 측면에서는 도움이 될 수도 있다.
- 이전처럼 아무나 막 사용하는 string을 보내면 이상한 데이터들이 흘러들어올 여지가 있는데 (현재 kafka에서는 보안 프로토콜을 넣어 놓지 않았기 때문에) 이렇게 객체로 만들게 되면 다른 사람들이 함부로 보낼 수 조차 없으니 잘 프로그래밍하면 의미가 있을 수 있었을 것같다. 약간에 아쉬움이 있지만 그래도 진행을 해보자
jar 파일 실행
아래 코드를 통해서 파일을 EC2로 내보내고
scp -i {pemkey path} {file} {serverName}@{ip} {filePath}
아래 코드로 실행을 한다.
java -jar {file}.jar
아래와 같은 line들을 출력할 수 있다!
여기까지 하는데 참 고생이 많았다!! 이제 producing할 정보를 잡아올 수 있게 된것이다. 이제 KAFKA 세팅을 하고 이 정보들을 카프카에 넣는 과정 그리고 다시 시각화 하는 과정이 남았다!!!! 0.7/3정도 한거 같네!!!
->다음편4. Publisher에서 계속