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에서 계속