Slack은 미래의 업무가 이루어지는 곳입니다

Slack은 여러분의 팀과 소통할 새로운 방법입니다. 이메일보다 빠르고, 더 조직적이며, 훨씬 안전합니다.

slack.com

 

Create an app
Craete New App - From Scratch - App Name, workspace 설정
Webhook URL을 생성

Webhook URL 생성이 끝났으면,  컴퓨터(서버)의 CPU 사용률을 확인하고  Slack API를 호출합시다

Slack 메시지 확인

 

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import javax.net.ssl.HttpsURLConnection;

public class Main {
	
	static String slackWebhookURL = "WebhookURL";
	static String os = System.getProperty("os.name").toLowerCase().trim();
	static String userName = System.getProperty("user.name");
	static String computerName = "";
	static String serverAlias = "HOME";

	static String getHostName() throws UnknownHostException {
		return InetAddress.getLocalHost().getHostName();
	}

	static String getServerIp() {
		InetAddress local = null;
		try {
			local = InetAddress.getLocalHost();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}

		if (local == null) {
			return "";
		} else {
			String ip = local.getHostAddress();
			return ip;
		}
	}

	static String getNow() {
		LocalDateTime now = LocalDateTime.now();
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
		return now.format(formatter);
	}

	static boolean isDigit(String s) {
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (!(c >= '0' && c <= '9'))
				return false;
		}
		return true;
	}

	static void post(String slackUrl, Map<String, String> map) throws Exception {
		URL url = new URL(slackUrl);
		HttpsURLConnection con = (HttpsURLConnection) url.openConnection();

		con.setRequestMethod("POST");
		con.setRequestProperty("Content-Type", "application/json);utf-8");
		con.setRequestProperty("Accept", "application/json");
		con.setDoOutput(true);

		String jsonString = "{";

		int size = map.size();
		for (String key : map.keySet()) {
			size--;
			jsonString += "\"" + key + "\":\"" + map.get(key) + "\"";
			if (size > 0)
				jsonString += ",";
		}
		jsonString += "}";

		try (OutputStream os = con.getOutputStream()) {
			byte[] input = jsonString.getBytes("utf-8");
			os.write(input, 0, input.length);
		}

		try (BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"))) {
			/*
			 * StringBuilder response = new StringBuilder(); String responsLine = null;
			 * while ((responsLine = br.readLine()) != null) {
			 * response.append(responsLine.trim()); }
			 * System.out.println(response.toString());
			 */
		}

	}

	static Process runTheCommand(String os, String command) {
		Process process = null;
		try {
			if (os.contains("win")) {
				process = Runtime.getRuntime().exec("cmd /c " + command);
			} else if (os.contains("mac")) {

			} else if (os.contains("linux")) {
				process = new ProcessBuilder("/bin/bash", "-c", command).start();
			} else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {

			} else if (os.contains("sunos")) {

			} else {

			}
		} catch (Exception e) {
			System.err.println("Error Message : " + e.getMessage());
		}
		return process;
	}

	// GET CPU usage
	static void getCpuUsage() throws Exception {
		double cpuUsage = -1;

		if (os.contains("win")) {
			Process p = runTheCommand(os, "wmic cpu get loadpercentage");

			BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
			String line = null;

			while ((line = br.readLine().trim()) != null) {
				// java 1.8 <= line.chars().allMatch(Character::isDigit)
				if (!"".equals(line) && isDigit(line)) {
					cpuUsage = Integer.parseInt(line);
					break;
				}
			}

			br.close();
		} else if (os.contains("mac")) {

		} else if (os.contains("linux")) {
			Process p = runTheCommand(os, "mpstat");
			BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
			String line = null;
			for (int i = 0; i < 4 && ((line = br.readLine().trim()) != null); i++) {
				if (i == 3) {
					String[] tmp = line.split("\\s+");
					cpuUsage = (100 - Double.parseDouble(tmp[tmp.length - 1]));
					cpuUsage = (int) (cpuUsage * 100) / 100.0;
				}
			}
		} else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {
		
		} else if (os.contains("sunos")) {

		} else {

		}

		if (cpuUsage >= 0) { // Sends slack message when CPU usage exceeds a certain level

			String emoticon = ":white_circle:";
			if (cpuUsage >= 80)
				emoticon = ":red_circle:";
			else if (cpuUsage >= 70)
				emoticon = ":large_orange_circle:";
			else if (cpuUsage >= 60)
				emoticon = ":large_yellow_circle:";
			else if (cpuUsage >= 40)
				emoticon = ":large_green_circle:";
			else if (cpuUsage >= 5)
				emoticon = ":large_blue_circle:";

			Map<String, String> map = new HashMap<String, String>();
			map.put("text",
					emoticon + " " + getNow() + " | " + os + " | " + getServerIp() + " | [" + computerName + " / "
							+ userName + ("".equals(serverAlias) ? "" : " / " + serverAlias) + "] | "
							+ "CPU Usage is " + cpuUsage + "%");
			post(slackWebhookURL, map);
		}
		System.out.println(getNow() + " . CPU Usage : " + cpuUsage + "\n");
	}

	public static void main(String args[]) throws Exception {
		System.out.println("OS : " + os);
		computerName = getHostName();

		Timer timer = new Timer();
		TimerTask timerCPU = new TimerTask() {
			@Override
			public void run() {
				try {
					getCpuUsage();
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
			}
		};

		timer.schedule(timerCPU, 1000, 5000);
	}

}

- 처음에는 무한 루프(while true) + Thread.sleep 사용했었는데 (CPU 부하 거의 없음), 보다 더 깔끔하게 Java 타이머 기능을 활용하여, 모니터링 할 수 있도록 구현했습니다

- 리눅스 모니터링은 sysstat 패키지 설치해서 mpstat 명령어로 CPU 사용률 확인했습니다. 원래는 top 명령어로 확인이 가능한데, null 값을 리턴하여 패키지를 활용했습니다

- 리눅스 서버에서 한글 깨짐 현상이 발생하네요. 언어팩 귀찮으니 그냥 Slack 메시지 영어로 변경

 

마지막 말

회사에서 시스템 문제가 발생할때마다, 서버 원격 접속해서 확인하는게 귀찮아서 Slack 알림으로 빠르게 확인할 수 있도록 만들어보았습니다. CPU 말고도  디스크 용량, 메모리(RAM) 사용률 모니터링도 개발하면 업무가 좀 더 편해질 것 같습니다 ㅎㅎ 많이 부족한 코드지만 slack api 사용해보고 싶은 분들에게 조금이나마 도움이 되었으면 좋겠습니다.

 

 

🔹윈도우 서버 모니터링 시작하기 (Main.java)

명령 프롬프트(CMD) 실행

cd [Main.java가 있는 폴더]

javac ./Main.java    -  컴파일

java Main  -  실행

 * java 파일 실행만 하면 되니, 다른 시스템도 동일할 거 같아요

 

🔹Slack 이모티콘 사용

채팅에 이모티콘을 선택하고, 마우스 커서를 올려두면 문자열을 확인할 수 있습니다

🔹App 이미지 변경

Settings - Basic Information - Display Information 에서 App 이미지 변경 가능할 수 있습니다

'JAVA' 카테고리의 다른 글

[JAVA] POST multipart/form-data 요청하기  (0) 2022.07.09
[윈도우] JAVA 1.8 설치  (0) 2020.11.14
[JAVA] 문자열 수식 계산하기  (0) 2019.05.13

+ Recent posts