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

가을을 맞아 카카오프렌즈는 단체로 소풍을 떠났다. 즐거운 시간을 보내고 마지막에 단체사진을 찍기 위해 카메라 앞에 일렬로 나란히 섰다. 그런데 각자가 원하는 배치가 모두 달라 어떤 순서로 설지 정하는데 시간이 오래 걸렸다. 네오는 프로도와 나란히 서기를 원했고, 튜브가 뿜은 불을 맞은 적이 있던 라이언은 튜브에게서 적어도 세 칸 이상 떨어져서 서기를 원했다. 사진을 찍고 나서 돌아오는 길에, 무지는 모두가 원하는 조건을 만족하면서도 다르게 서는 방법이 있지 않았을까 생각해보게 되었다. 각 프렌즈가 원하는 조건을 입력으로 받았을 때 모든 조건을 만족할 수 있도록 서는 경우의 수를 계산하는 프로그램을 작성해보자.

 

입력 형식

입력은 조건의 개수를 나타내는 정수n과n개의 원소로 구성된 문자열 배열data로 주어진다.data의 원소는 각 프렌즈가 원하는 조건이N~F=0과 같은 형태의 문자열로 구성되어 있다. 제한조건은 아래와 같다.

  • 1 <= n <= 100
  • data의 원소는 다섯 글자로 구성된 문자열이다. 각 원소의 조건은 다음과 같다.
    • 첫 번째 글자와 세 번째 글자는 다음 8개 중 하나이다.{A, C, F, J, M, N, R, T}각각 어피치, 콘, 프로도, 제이지, 무지, 네오, 라이언, 튜브를 의미한다. 첫 번째 글자는 조건을 제시한 프렌즈, 세 번째 글자는 상대방이다. 첫 번째 글자와 세 번째 글자는 항상 다르다.
    • 두 번째 글자는 항상~이다.
    • 네 번째 글자는 다음 3개 중 하나이다.{=, <, >}각각 같음, 미만, 초과를 의미한다.
    • 다섯 번째 글자는0이상6이하의 정수의 문자형이며, 조건에 제시되는 간격을 의미한다. 이때 간격은 두 프렌즈 사이에 있는 다른 프렌즈의 수이다.

출력 형식

모든 조건을 만족하는 경우의 수를 리턴한다.

 

예제 입출력

2 ["N~F=0", "R~T>2"] 3648
2 ["M~C<2", "C~M>1"] 0

예제에 대한 설명

첫 번째 예제는 문제에 설명된 바와 같이, 네오는 프로도와의 간격이 0이기를 원하고 라이언은 튜브와의 간격이 2보다 크기를 원하는 상황이다.

두 번째 예제는 무지가 콘과의 간격이 2보다 작기를 원하고, 반대로 콘은 무지와의 간격이 1보다 크기를 원하는 상황이다. 이는 동시에 만족할 수 없는 조건이므로 경우의 수는 0이다.


모든 조건을 만족하는지 확인하기 위해서는 완전 탐색을 해야한다고 생각했고,

8개의 캐릭터가 줄을 설 수 있는 방법은 8! = 40320 가지가 나와서 충분히 완전 탐색을 하면 되겠다라고 생각했다.

 

DFS(깊이 우선 탐색)으로  순서(01234567 ~ 76543210)를 정하고, 조건들을 확인하고 모든 조건을 만족하면 경우의 수 1을 리턴한다

 

순서를 정할때는 문자열(숫자)로 저장하고, 각 문자(숫자)는  ID 배열의 인덱스이다

입력(조건)을 받을 때는 캐릭터들의 이니셜을 문자 타입으로 받기 때문에, Map 타입을 통해 캐릭터 이니셜과 현재 위치(인덱스)를 매핑해줬다

 

캐릭터들의 위치를 배열로 저장하게 된다면, 입력 조건을 확인할 때마다 2개의 캐릭터의 위치를 확인하기 위해서 O(N)의 시간복잡도를 가지지만, Map 타입을 사용하게 된다면 O(1) 시간복잡도만으로 위치를 찾을 수 있기 때문에 좀 더 효율적이지 않을까 생각했다

 

내 코드 진단 & 생각

 

- 캐릭터들의 순서가 정해졌는지 저장하는 boolean 배열 객체를 dfs 실행마다 생성하여 다음 dfs 함수로 넘기지 않는다. (당연히 메모리 낭비니까?..)   전역변수(boolean 배열 b)로 선언하여 true/false 변경하며 백트래킹을 사용함. 그래도 전역 변수를 사용하지 않고 solution 함수에 boolean 배열 객체를 선언하여 dfs 매개 변수에 추가했으면 좀 더 깔끔한 코드가 되지 않았을까?

 

- Map도 전역 변수로 선언하여, dfs 안에서 객체 생성을 하지 않고, clear()를 통해 재사용했는데 위 생각처럼 dfs 매개 변수에 추가하면 더 좋은 코드가 됐을 것 같다. (ID 배열도 마찬가지).  그런데 dfs 안에서 Map 객체를 생성했더라도 Map 데이터  쌍 ('A',0), ('C',1) 들도 map.put 할 때마다 기본형 타입이 아닌 객체로 저장되니  이러나 저러나 3가지 방식 모두 메모리 상으론 비슷하지 않을까?

 

- 백준 사이트 같았으면  결과값(answer)도 전역으로 선언하고,  void dfs() 해서 풀었을텐데, 프로그래머스는 제출 방식이  다르다보니 int dfs()로 경우의 수를 리턴하여 answer에 더하는 방식으로 풀어봤다. 

 

 

 

import java.util.HashMap;
import java.util.Map;

class Solution {

	char[] ID = { 'A', 'C', 'F', 'J', 'M', 'N', 'R', 'T' };
	boolean[] b = new boolean[8];
	Map<Character, Integer> map = new HashMap<Character, Integer>();

	int dfs(String[] data, int depth, String order) {

		if (depth == 8) {
			map.clear();

			for (int i = 0; i < order.length(); i++) {
				map.put(ID[order.charAt(i) - '0'], i);
			}

			for (int i = 0; i < data.length; i++) {
				int dist = Math.abs(map.get(data[i].charAt(0)) - map.get(data[i].charAt(2))) - 1;
				int cpVal = data[i].charAt(4) - '0';
				char sign = data[i].charAt(3);
				if (sign == '>') {
					if (dist <= cpVal)
						return 0;
				} else if (sign == '<') {
					if (dist >= cpVal)
						return 0;
				} else {
					if (dist != cpVal)
						return 0;
				}
			}

			return 1;
		}

		int ret = 0;

		for (int i = 0; i < 8; i++) {
			if (b[i])
				continue;
			b[i] = true;
			ret += dfs(data, depth + 1, order + i);
			b[i] = false;
		}

		return ret;
	}

	public int solution(int n, String[] data) {
		int answer = 0;

		answer += dfs(data, 0, "");

		return answer;
	}
}

Docker 설치하기

https://www.docker.com/get-started/

 

Developers - Docker

Docker Hub The world’s leading service for finding and sharing container images with your team and the Docker community. For developers and those experimenting with Docker, Docker Hub is your starting point into Docker containers. Create an account and s

www.docker.com

시스템에 맞게 설치

윈도우인 경우 WSL(Windows Subsystem for Linux)을 설치해야 진행이 가능하다. WSL을 통해 윈도우에서 리눅스 커널을 사용할 수 있음

 

 

 

npm init -y  project init

npm i express

 

Dockerfile

ex. Layer 0 (Base Image) -> Layer 1 (line 6) -> Layer 2 (line 10) -> Layer 3 (ex. build)

Docker는 Layer 0 ~ N 순으로 실행되는데,  변경된 내용이 없으면 업데이트하지 않는다고 함.

package*.json 파일은 npm install * 과 같이 의존성 목록을 추가해야 파일이 수정되는거에 비해, 프로젝트를 하면서 index.js 파일은 자주 업데이트가 되기 때문에. line 6보다 10을 아래쪽에 설정하여 docker container 구축 속도를 단축시킴

 

docker build -f Dockerfile -t fun-docker .

-f : 어떤 Dockerfile을 사용할지 명시

-t : Docker Image 별칭을 부여

docker images

로컬에 만들어진 이미지를 확인

 

docker run -d -p 8080:8080 fun-docker

-d stands for detached: to run a container in a background. 백그라운드에서 실행

-p is port publishing: maps a port on the container to a port on the host. 포트를 지정

8080:8080 -> localhost port : docker container port . 포트를 연결시켜준다

 

docker ps

현재 실행중인 컨테이너들의 리스트를 확인할 수 있음

 

docker logs 'CONTAINER ID'

컨테이너의 로그를 확인할 수 있음. 

docker 응용 프로그램에서도 확인 가능

Docker Image -> Docker Hub  Push

docker images  -  REPOSITORY(fun-docker), TAG(latest)  확인

docker tag fun-docker:latest user/docker-example:latest

docker login - docker 계정 정보를 입력하여 로그인

docker push user/docker-example:latest

docker hub 사이트에서 확인

 

 

docker run -dp 8080:8080 'tpwls8122/gocker-example'

 

 

참고 사이트

https://www.youtube.com/watch?v=LXJhA3VWXFA&list=LL&index=1 

https://docs.docker.com/get-started/

 

Orientation and setup

 

docs.docker.com

 

'Docker & k8s' 카테고리의 다른 글

Docker-Compose를 통한 Node, Redis 환경 구성하기  (0) 2023.09.03

1. 데이터베이스 (MySQL 연결하기)

호스팅관리 - 기본관리 - 서비스 사용현황 - MySQL 외부 IP 접근설정

사용하는 컴퓨터의 공인 IP를 설정 ( 네이버 IP주소 검색 )

 

HeidiSQL 설치
호스팅 관리 - 서비스 접속관리 - MySQL 웹어드민

DB 호스트명 : 접속 URL ( /WebMysql 제외 )

사용자 : 아이디

암호 : 설정한 DB 비밀번호

 

[호스팅 계정에 phpMyAdmin 직접 설치하여 접속]

Filezilla 또는 웹FTP를 이용해서 하는 방법이 있는데, 제가 선택한 서비스로는 사용할 수 없는지 Filezilla에서 연결이 안되더라고요. ( 자주 묻는 질문에서 git으로 배포하라고 나와 있는데, 이 방법은 사용 못하는 것 같습니다. )

-> Git 명령어를 통해 앱 관리를 하시면 됩니다. 

 

 

2. 서버 구축하기

2-1. 앱 생성관리 메뉴에서 앱 생성

2-2. Public key 관리 메뉴에서 Public Key 등록 ( 카페24 public key 생성 매뉴얼 )

C:\Users\hostname\.ssh - id_rsa ( 유형 : PUB 파일 ) 내용을 복사 Public Key에 입력

Public Key 이름은 아무 내용이나 적어도 상관 X

 

Public key를 등록한 후,  위 캡처에서 [Key 할당] 버튼을 통해 앱에 등록해주시면 됩니다.

2-3-1. Git 명령어

# 프로젝트 폴더 접속 후, git 초기화
$ git init
# 원격 저장소 설정. 일반적으로 origin 또는 원하는 원격 저장소 이름
# git remote add <name> <url>
$ git remote add origin <Git URL>
# 원격 저장소 확인
$ git remote -v

# cafe24 앱에 소스 배포
# git push <remote> <branch>. `git branch` 명령어를 통해 현재 branch 확인
$ git push origin master

 

2-3-2. 소스 배포하기 (Sourcetree 설치)

설정을 눌러 원격 저장소 경로를 등록 ( 경로는 앱 생성/관리 - 앱 리스트 - 저장소 주소가 적혀있습니다. )

 

$ git push cafe24(원격 저장소 이름) master

비밀번호는 Public Key 생성 시, 설정한 비밀번호 입력

 

서버에 소스 배포를 완료했습니다. 앱 생성/관리 - 앱 리스트에서 앱을 실행 (앱 재실행하여 소스를 반영)

 

😊 서버 구축 완료 

 

🤦‍♂️ 중요

1. node.js 호스팅은 일반적인 웹호스팅과는 달리 FTP를 통한 파일 업로드를 지원하지 않는다. (git 통해 소스 배포)

2. 앱 기본 실행 파일명은 web.js 로 설정

3. 소스에서 경로 설정 ( /home/hosting_users/ID/apps/ID_ID/ ) 

 - ./ 또는 / 이런 식으로 사용하면 경로를 인식하지 못하였음

4. git commit 시, node_modules 파일 반드시 포함

5. 소스 배포 이후, 앱  중지 -> 실행을 통해 배포한 소스. 서버에 적용

 

지인의 부탁으로, 책임감을 가지고 Node Express + Cafe24 서비스를 통해 API 서버를 배포하였다.

작은 회사이기도 하고, 트래픽이 낮은 프로젝트라서 가격이 저렴한 Cafe24 호스팅 서비스를 이용하였다.

 

서버 원격 접속이나 FTP 접속을 지원하지 않아, Git을 통해 앱을 관리해야한다거나 Cafe24 사이트에서 지원하는 [로그 보기] 버튼으로 서버 모니터링을 하기에 불편함이 있었다.

 

설명이 잘되어 있는 여러 블로그들을 참고했지만, 그럼에도 막히는 부분들이 역시나 있었다. 

하지만 문제를 해결하면서 새로운 것들을 배울 수 있었고, 무엇보다도 내가 처음 배포한 서버가 문제없이 돌아간다는 점에서 많은 성취감을 느낄 수 있었다. 

 

 

Help - Eclipse Marketplace - theme 검색

원하는 테마를 다운로드한다. 나는 Darkset Dark Theme

다운로드가 완료되면 이클립스 재시작

원하는 Theme 선택 - Next
Workbench, Editors 맘에 드는 걸로 선택

테마 변경 완료

Window - Preferences - theme 검색

테마(속성) 변경

 

'이것저것' 카테고리의 다른 글

hosts 파일 수정하기  (0) 2020.11.07
[VSCODE] Terminal 실행  (0) 2020.05.02
vscode c++ 코드스타일 바꾸기  (0) 2019.05.22
[VSCODE] 글씨 폰트 설정  (0) 2019.05.18
알고리즘 c++ 하는방법  (0) 2019.05.17

www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html

Java SE Development Kit 8 Downloads 

 

시스템 환경 확인
환경에 맞는 설치 파일 다운로드

환경에 맞는 실행 파일을 다운로드, 실행하여 Next 클릭 클릭하여 Java를 다운로드한다.

 

CMD - java 입력

1. CMD에서 명령어 java를 입력해보면 설치된 것을 확인

2. java -version을 입력하여 버전을 확인

3. javac 입력했을 때, 내부 또는 외부 명령?? 라는 글자만 나올 것이다. 환경 설정을 해주자

 

시스템 - 고급 시스템 설정 - 고급 탭 - 환경 변수 - 시스템 변수 - Path - 편집
시스템 변수 - Path - 편집

자바 설치를 할 때, 별다른 경로를 설정하지 않았다면 Program Files 폴더에 설치가 되었을 것이다. bin폴더의 절대 경로를 추가하여 준다. 

다른 블로그들을 보면 bin 경로를 JAVA_HOME이라는 변수에 넣어서 사용하는 법도 있다. 아무거나 쓰자.

 

CMD - javac 입력

Java 환경 구축 완료!

host 파일 위치 : C:\Windows\System32\drivers\etc

 

구글에서 검색해서 나오는 방법은

  1. 메모장을 관리자 권한으로 실행 후, hosts 파일 수정
  2. 백신 프로그램 설정 수정

 

물론 이 방법도 있지만, 안될 때도 있더라. 

 

아무리해도 관리자 권한을 취득하지 못할 때도 있었음.

 

컴퓨터관리 - Administrator 속성 - 계정 사용 안함 체크 해제

 

  1. 로그아웃 한다.
  2. 관리자 계정으로 윈도우 접속 ( Administrator )
  3. hosts 파일 수정

'이것저것' 카테고리의 다른 글

이클립스 테마 변경하기  (0) 2020.11.14
[VSCODE] Terminal 실행  (0) 2020.05.02
vscode c++ 코드스타일 바꾸기  (0) 2019.05.22
[VSCODE] 글씨 폰트 설정  (0) 2019.05.18
알고리즘 c++ 하는방법  (0) 2019.05.17

✔ ELK Stack 란?


"ELK"는 Elasticsearch, Logstash 및 Kibana, 이 오픈 소스 프로젝트 세 개의 머리글자입니다. 오픈소스이기 때문에 무료로 사용 가능하다고 합니다.


1. Elastic Search ( Port : 9200 )

  • Apache Lucene 기반의 Java 오픈소스 분산 검색 엔진이다.

 

  • Elastic Search를 통해 루씬 라이브러리를 단독으로 사용할 수 있게 되었으며, 방대한 양의 데이터를 신속하게, 거의 실시간(NRT, Near Real Time)으로 저장, 검색, 분석할 수 있다.

 

  • 오픈소스의 장점처럼 전문가들이 버그에 빠르게 대응한다.

 

  • Document 간의 조인을 수행할 수 없다. ( 두 번 이상의 쿼리로 해결은 가능하다고 한다. )

 

  • 트랜잭션이 제공되지 않는다.

 

 

2. Logstash ( Port : 5000 )

  • 다양한 소스 (DB, csv 파일 등)의 로그 또는 트랜잭션 데이터를 수집, 집계, 파싱하여 Elastic Search에 전달한다.

 

  • Input을 받아 커스텀 가능한 Filters로 가공하여 Output으로 내보내는 역할을 수행한다.

 

Logstash.conf 파일의 구성

input {
	...
}
filter {
	...
}
output {
	...
}

Logstash Pipeline

 

 

3. Kibana ( Port : 5601 )

  • Elastic Search와 함께 작동하도록 설계된 오픈 소스 분석 및 시각화 플랫폼이다.

 

  • Elastic Search 색인에 저장된 데이터를 검색해보고 상호 작용할 수 있다.

 

  • 고급 데이터 분석을 쉽게 수행하고 다양한 차트, 테이블 및 맵에서 데이터를 시각화할 수 있다.

 

Kibana


✔ ELK Stack의 특징

장점

  • 강력한 유연성과 호환성 : 엘라스틱 서치, 로그스태시, 키바나는 각각 데이터의 쿼리(검색), 수집, 시각화를 담당한다. 용도별로 분리하여 발전하는 솔루션이기에 구조적 안정성은 물론 다른 시스템과도 유연한 호환성을 가진다.

 

  • 자유 스키마 : JSON 방식의 Key-Value 형식의 데이터를 사용하므로 형식에 자유롭다.

 

  • 인덱스 와일드카드 지원 : 관계형 데이터베이스로 치면 테이블(Table)에 해당하는 개념인 인덱스(Index)의 Union 또는 Join이 경우에 따라 와일드 카드(*) 표기 하나로 끝날 수도 있다.

 

  • 확장(Scale-out) 가능 데이터베이스 : 처음부터 확장을 고려하여 만들어졌기 때문에, 여러대의 서버를 엮어서 성능 향상을 기대할 수 있는 클러스터 방식을 구성할 때 관계형 데이터베이스보다 상대적으로 관련 정보에 쉽게 접근이 가능하다.

 

  • 데이터 처리 절차를 '레거시 코딩'보단 개별 설정으로 가능 : 데이터 처리 절차를 프로그래밍 언어를 이용한 코딩으로 명시한다면, 향후 유지보수가 용이하지 않고 불필요한 종속성이 높아지는 문제가 있지만 Logstash를 포함하는 ELK Stack 구성 시 유연성 확보가 가능하다.

 

  • 사전에 준비된 시각화 도구와 부가기능 : 데이터를 시각화하여 보여주기 위한 사용자 인터페이스를 내보낼 프로그램을 따로 작성하지 않아도, 이미 사전에 준비된 시각화 도구를 가진 Kibana가 마우스 몇번 조작하면 거진 다 알아서 해준다. 그 외 데이터베이스 관리자를 위한 부가기능이 포함되어 있다.

 

  • 실시간 데이터 처리 : 메시지 큐(Message Queue, MQ)와 결합하면 강력한 실시간 (Realtime) 데이터 수집 및 처리 시스템이 된다.

 

단점

  • 초기 데이터 구성 및 이관 문제

 

  • 커널 변수의 불필요한 사용

 

  • 시간대 (Timezone) 처리


 

나무위키 참조 : namu.wiki/w/ELK?from=ELK%28%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4%29

 

ELK - 나무위키

이 저작물은 CC BY-NC-SA 2.0 KR에 따라 이용할 수 있습니다. (단, 라이선스가 명시된 일부 문서 및 삽화 제외) 기여하신 문서의 저작권은 각 기여자에게 있으며, 각 기여자는 기여하신 부분의 저작권

namu.wiki


ELK Stack 환경구축

✔ OS 지원 매트릭스 : www.elastic.co/support/matrix

✔ 사이트 참조 : lindarex.github.io/elastic-stack/ubuntu-elastic-stack-installation/

  • Java 설치
  • Elastic Search 설치
  • Logstash 설치
  • Kibana 설치

Localhost에서 3개의 서비스를 구성한다면, 별도 설정할 필요없이 서로 바인딩이 된다.


Elastic Search  VS  Relational Database (RDB, 관계형 데이터베이스)

RDB에서는 Document ( Row를 뜻한다. ) 중심이라면 Elastic Search에서는 텍스트 중심이다.

만약 텍스트 A를 찾는다고 한다면, RDB에서는 Document 하나하나 확인하면서 A가 있는지 찾지만, Elastic Search에서는 검색하는 순간 데이터를 찾을 수 있다. ( 시간복잡도 O(1) )

 

검색 속도면에서는 엘라스틱 서치가 빠르지만, 다른 테이블과 조합할 수 없고 ( 가능은 하지만, 두 번 질의를 해야하는 문제가 발생한다고 한다. ), 데이터 트랜잭션을 지원하지 않는 단점이 있다. 하지만 관계형 데이터베이스에서는 테이블 조합과 트랜잭션을 지원한다는 장점이 있다.


Elastic Search API 예제

인덱스 생성
curl -XPUT http://localhost:9200/classes?pretty

매핑 생성
curl -H 'Content-Type:application/json' -XPOST 'http://localhost:9200/classes/class/_mapping?include_type_name=true&pretty' -d @classes-mapping.json
 
데이터 생성
curl -H 'Content-Type:application/json' -XPOST http://localhost:9200/_bulk?pretty --data-binary @classes.json
 
인덱스 확인 and 매핑 확인
curl -XGET localhost:9200/classes/?pretty
 
데이터 조회
curl -XGET localhost:9200/classes/class/1?pretty
 
데이터 검색
curl -XGET 'localhost:9200/classes/class/_search?q=major:"music"&pretty'
 
데이터 수정 (1)
curl -H 'Content-Type:application/json' -XPOST http://localhost:9200/classes/class/1/ -d '{"title" : "Algorithm","professor" : "John"}'
 
데이터 수정 (2)
curl -H 'Content-Type:application/json' -XPUT http://localhost:9200/classes/class/1/ -d '{"title" : "ELK Stack","professor" : "Sejin"}'
 
인덱스 삭제
curl -XDELETE http://localhost:9200/classes

참조

  • -H 'Content-Type:application/json' : ElasticSearch 6 버전 이후부터는 head 값까지 상세히 적어줘야한다고함
  • string은 mapping type에서 사용할 수 없다. 버전 5.0부터 text와 keyword로 분리되었다. 
  • mapping.json POST할 때, include_type_name=true 옵션 추가 필요

Elastic Stack 실습

 

✔ 페이스북 주식 데이터 분석하기

 

1. 주식 데이터 (.csv) 다운로드 받기 

finance.yahoo.com/quote/FB/history?period1=1420070400&period2=1590883200&interval=1d&filter=history&frequency=1d&includeAdjustedClose=true

 

2. Logstash 환경 설정 파일 생성 ( logstash-stock.conf )

input {
    file {
        path => "/home/sejin/Documents/FB.csv"
        start_position => "beginning"
        sincedb_path => "/dev/null"
    }
}
filter {
    csv {
        separator => ","
        columns => ["Date","Open","High","Low","Close","Adj Close","Volume"]
    }  
    mutate {convert => ["Open", "float"]}
    mutate {convert => ["High", "float"]}
    mutate {convert => ["Low", "float"]}
    mutate {convert => ["Close", "float"]}
}
output {
    elasticsearch {
        hosts => "localhost"
        index => "stock"
    }
    stdout {}
}

 

3. Logstash 서비스를 통해 Elastic Search로 데이터 전달

/usr/share/logstash/bin/logstash -f /home/sejin/Documents/logstash-stock.conf

 

4. Kibana를 통한 로그 분석

Kibana Dashboard


참조 사이트

무료 강의 참조

www.inflearn.com/course/elk-%EC%8A%A4%ED%83%9D-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B6%84%EC%84%9D/dashboard

 

매핑 타입 text, keyword 참조

esbook.kimjmin.net/07-settings-and-mappings/7.2-mappings/7.2.1

 

개념 참조

www.youtube.com/watch?v=MWItWo67F14&ab_channel=%EA%B0%9C%EB%B0%9C%ED%95%98%EB%8A%94%EB%82%A8%EC%9E%90

Visual Studio Code를 다시 설치하고, 코드를 실행하였을 때,

 

Terminal (터미널) 이 아닌 Output (출력) 에 실행 결과가 표시된다.

 

 

Code Runner 확장 프로그램 설치하고, 설정 ( Ctrl + , ) 에서 Code-runner: Run In Terminal 설정을 변경한다.

'이것저것' 카테고리의 다른 글

이클립스 테마 변경하기  (0) 2020.11.14
hosts 파일 수정하기  (0) 2020.11.07
vscode c++ 코드스타일 바꾸기  (0) 2019.05.22
[VSCODE] 글씨 폰트 설정  (0) 2019.05.18
알고리즘 c++ 하는방법  (0) 2019.05.17

Requests can only be made in the LoggedIn state, not the Connecting state


 

Sql Server Configuration Manager 접속

  • SQL Server 네트워크 구성 - SQLEXPRESS에 대한 프로토콜 - TCP/IP 사용으로 변경
  • 속성을 클릭하여 [IP주소] 탭 맨아래 쪽 IPAll - TCP포트 - 1433 으로 설정

 

MSSQL를 처음 설치할 때, 포트를 막기 때문에 발생하는 현상임. 포트를 열어 접속이 가능하도록 설정하여 해결

 

var { Connection, Request } = require("tedious");

var config = {
  server: "localhost",
  authentication: {
    type: "default",
    options: {
      userName: "dev",
      password: "dev"
    }
  },
  options: {
    trustServerCertificate: false,
    encrypt: false,
    database: "vue_project"
    // port: 1433
  }
};

/* detail err msg
 connection.on("debug", function(err) {
   console.log("debug : ", err);
 });
*/

const connection = new Connection(config);
// Attempt to connect and execute queries if connection goes through
connection.on("connect", err => {
  if (err) {
    console.error(err.message);
  } else {
    queryDatabase();
  }
});

function queryDatabase() {
  console.log("Reading rows from the Table...");

  const request = new Request(`SELECT * FROM USR_INFO`, (err, rowCount) => {
    if (err) {
      console.error(err.message);
    } else {
      console.log(`${rowCount} row(s) returned`);
    }
  });

  request.on("row", columns => {
    columns.forEach(column => {
      console.log("%s\t%s", column.metadata.colName, column.value);
    });
  });

  connection.execSql(request);
}

 

 


 

[MSSQL] 호스트 localhost, 포트 1433에 대한 TCP/IP 연결에 실패했습니다.

오랜만에 MSSQL을 재설치 했더니 아래와 같은 오류가 뜹니다.설치 할 때마다 검색하는거 같아서 아예 ...

blog.naver.com

 

+ Recent posts