ELK스택 기본사용법 - ② Kibana
저번 시간에 이어 이번에는 ELK 스택의 Kibana를 활용하는 방법을 정리해 보았다.
학습한 내용과 사진, 코드는 모두 다음의 강의에서 참고하였다!🙌
참고한 강의 (플레이리스트)
↓
https://www.youtube.com/watch?v=3iA-ncqAqYE&list=PLVNY1HnUlO24LCsgOxR_eK2Yi4sOgH9Pg&index=19
github : 강의 참고 자료
↓
https://github.com/minsuk-heo/BigData
GitHub - minsuk-heo/BigData
Contribute to minsuk-heo/BigData development by creating an account on GitHub.
github.com
이전 블로그 (ElasticSearch)
↓
https://dodop-blog.tistory.com/410
ELK스택 기본사용법 - ① ElasticSearch
ELK (Elastic search, Logstash, Kibana) 스택에 대해서 들어보기는 했지만 어떻게 동작하는지 몰라서 간단한 강의를 듣고 실습해 보았다! 학습한 내용과 사진, 코드는 모두 다음의 강의에서 참고하였다!
dodop-blog.tistory.com
Kibana
Kibana는 HTML과 Javascript 엔진으로 분석 결과를 시각화 할 때 사용되며 ElasticSearch에서 받아온 데이터를 시각화 하는데 쓰여진다.
설치하기
macOS를 사용하고 있어 brew 명령어를 이용하여 설치를 진행하였다.
참고사이트
↓
https://logz.io/blog/brew-install-elasticsearch-mac/
Use Brew to Install Elasticsearch on Mac OS X | Logz.io
Use Homebrew to brew install Elasticsearch on Mac, along with the rest of the ELK Stack—Kibana, Filebeat, Metricbeat, and Logstash—with this tutorial
logz.io
$ brew install elastic/tap/kibana-full
설치가 끝나면 저장 위치도 함께 확인할 수 있다. 나의 경우는 다음과 같았다.
/opt/homebrew/etc/kibana/
여기서 실행 전에 먼저 config 설정을 통해서 server host와 ElasticSearch URL을 지정해준다.
$ vi /opt/homebrew/etc/kibana/kibana.yml
# Specifies the address to which the Kibana server will bind. IP addresses and host names are both valid values.
# The default is 'localhost', which usually means remote machines will not be able to connect.
# To allow connections from remote users, set this parameter to a non-loopback address.
server.host: "localhost"
# The URLs of the Elasticsearch instances to use for all your queries.
elasticsearch.hosts: ["http://localhost:9200"]
설정이 완료되면 키바나를 다음 명령어로 실행할 수 있다.
$ brew services start elastic/tap/kibana-full
실행시 나오는 문구로 실행 URL을 다음과 같이 확인할 수 있다. (초기 5601번 포트에서 실행)
http://localhost:5601
인덱스 받아오기
먼저 ElasticSearch를 통해서 Kibana에서 시각화 해 줄 데이터 넣는다.
% curl -X POST 'http://localhost:9200/_bulk?pretty' -H 'Content-Type: application/json' --data-binary @bulk_basketball.js
{
"took" : 84,
"errors" : false,
"items" : [
{
"index" : {
"_index" : "basketball",
"_type" : "record",
"_id" : "1",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 4,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "basketball",
"_type" : "record",
"_id" : "2",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 5,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "basketball",
"_type" : "record",
"_id" : "3",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 6,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "basketball",
"_type" : "record",
"_id" : "4",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 7,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "basketball",
"_type" : "record",
"_id" : "5",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 8,
"_primary_term" : 2,
"status" : 201
}
},
{
"index" : {
"_index" : "basketball",
"_type" : "record",
"_id" : "6",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 9,
"_primary_term" : 2,
"status" : 201
}
},
{
"index" : {
"_index" : "basketball",
"_type" : "record",
"_id" : "7",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 10,
"_primary_term" : 2,
"status" : 201
}
},
{
"index" : {
"_index" : "basketball",
"_type" : "record",
"_id" : "8",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 11,
"_primary_term" : 2,
"status" : 201
}
},
{
"index" : {
"_index" : "basketball",
"_type" : "record",
"_id" : "9",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 12,
"_primary_term" : 2,
"status" : 201
}
},
{
"index" : {
"_index" : "basketball",
"_type" : "record",
"_id" : "10",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 13,
"_primary_term" : 2,
"status" : 201
}
},
{
"index" : {
"_index" : "basketball",
"_type" : "record",
"_id" : "11",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 14,
"_primary_term" : 2,
"status" : 201
}
},
{
"index" : {
"_index" : "basketball",
"_type" : "record",
"_id" : "12",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 15,
"_primary_term" : 2,
"status" : 201
}
},
{
"index" : {
"_index" : "basketball",
"_type" : "record",
"_id" : "13",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 16,
"_primary_term" : 2,
"status" : 201
}
},
{
"index" : {
"_index" : "basketball",
"_type" : "record",
"_id" : "14",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 17,
"_primary_term" : 2,
"status" : 201
}
},
{
"index" : {
"_index" : "basketball",
"_type" : "record",
"_id" : "15",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 18,
"_primary_term" : 2,
"status" : 201
}
},
{
"index" : {
"_index" : "basketball",
"_type" : "record",
"_id" : "16",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 19,
"_primary_term" : 2,
"status" : 201
}
}
]
}
그 다음 Kibana 사이트 (http://localhost:5601) 에 접속하여 입력한 데이터를 시각화 해보자.
먼저 입력한 인덱스를 Kibana에서 받아오도록 설정한다.
Index Pattern -> Create index pattern -> 이름 : [인덱스명], 타임스탬프 필드 : [submit_date]
데이터를 무사히 받아오면 다음과 같이 인덱스를 잘 받아온 것을 확인할 수 있다.
Discover
이번엔 Kibana Discover를 사용하여 데이터 차트를 확인하도록 하자.
인덱스를 basketball로 선택하고 결과를 봤을 때 처음에 'no results found' 결과가 뜬다면 검색 기간을 지난 15년으로 변경한다면 자료를 확인할 수 있다.
타임필터를 이용해서 차트를 볼 수 있고 아래 테이블에서도 필터 필드들을 확인할 수 있다.
보여지는 바 차트를 hover하면 도큐먼트의 갯수가 뜨는 것을 확인할 수 있다.
여기서 + 버튼을 이용해서 필터를 추가할 수 있다.
필터에 hover를 통해 확인되는 top values등을 이용해 특정 데이터만 볼 수도 있다.
Visualize
이번엔 Kibana Visualize를 이용해서 파이차트나 바 차트 등으로 시각화 해보자. (키바나 7.11 기준으로는 Aggregation based)
Bar
먼저 바 차트로 만들어보자.
좌측 바의 Visualize Library -> create new visualization -> lens -> bar vertical stack
각 선수별로 평균 점수를 확인하기 위해 y축 기준과 x축 기준은 다음과 같이 설정해준다.
설정이 완료되면 다음과 같이 바 차트로 결과를 확인할 수 있다.
Donut
이번엔 Donut으로 결과를 확인해보자. 아까와 같이 선택하고 이번엔 bar가 아닌 Donut을 선택해준다.
선수들 총점을 이용한 결과를 확인하기 위해 x축과 y축은 다음과 같이 설정해준다.
설정이 완료되면 다음과 같이 결과를 확인할 수 있다.
Map
이번엔 Map을 이용하여 지도상의 표로 데이터를 확인하도록 하자.
먼저 다음과 같이 인덱스를 생성해준다. 여기서 매핑이 완료 되어야 지도에서 표시될 수 있는 데이터임을 알 수 있다.
% curl -X POST 'http://localhost:9200/_bulk?pretty' -H 'Content-Type: application/json' --data-binary @classes.json
{
"took" : 110,
"errors" : false,
"items" : [
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "1",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 24,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "2",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 25,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "3",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 26,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "5",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 27,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "6",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 28,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "7",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 29,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "8",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 30,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "9",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 31,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "10",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 32,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "11",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 33,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "12",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 34,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "13",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 35,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "14",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 36,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "15",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 37,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "16",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 38,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "17",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 39,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "18",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 40,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "19",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 41,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "20",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 42,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "21",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 43,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "22",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 44,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "23",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 45,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "24",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 46,
"_primary_term" : 2,
"status" : 200
}
},
{
"index" : {
"_index" : "classes",
"_type" : "class",
"_id" : "25",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 47,
"_primary_term" : 2,
"status" : 200
}
}
]
}
% curl -XPUT 'http://localhost:9200/classes/class/_mapping?include_type_name=true&pretty' -H 'Content-Type:application/json' -d @classesRating_mapping.json
{
"acknowledged" : true
}
% curl -XGET 'http://localhost:9200/classes/class/1?pretty'
{
"_index" : "classes",
"_type" : "class",
"_id" : "1",
"_version" : 2,
"_seq_no" : 24,
"_primary_term" : 2,
"found" : true,
"_source" : {
"title" : "Machine Learning",
"Professor" : "Minsuk Heo",
"major" : "Computer Science",
"semester" : [
"spring",
"fall"
],
"student_count" : 100,
"unit" : 3,
"rating" : 5,
"submit_date" : "2016-01-02",
"school_location" : {
"lat" : 36.0,
"lon" : -120.0
}
}
}
생성한 인덱스를 위에서 했던 것과 같이 Index patterns를 이용해 Kibana에 가져온다.
이번엔 Visualization에서 Lens가 아닌 Maps를 선택해준다.
좌측 바의 Visualize Library -> create new visualization -> Maps -> Add Layer -> Documents
그
여기서 아까 생성한 인덱스와 지도 표시 필드를 선택해준다.
기간을 올바르게 설정하면 다음과 같이 지도 표시 데이터를 확인할 수 있다.
Dashboard
이번엔 대시보드를 이용해서 앞서 보았던 표들을 한번에 모아서 볼 수 있도록 설정해보자.
이전에 만든 visualization들에 대해서 모두 save가 된 상태이거나 이 단계에서 visualization을 생성하는 방법으로 진행할 수 있다.
나는 이전에 만들어둔 표들을 모두 save로 저장해놓고 진행하였다.
좌측 Dashboard -> create new dashboard -> Add from libarary -> 표시하고자 하는 데이터 선택
데이터를 추가하고 나면 다음과 같이 시각화된 대시보드를 확인할 수 있다.
( 참고한 사이트 ✨)
https://kim-dragon.tistory.com/20
ELK(ElasticSearch, Logstash, Kibana) 란? ELK Stack 이란?
ELK란? ELK는 3가지 오픈소스 소프트웨어 Elastic Search, LogStatsh, Kibana의 조합을 말합니다. 각 제품이 연동되어 데이터 수집 및 분석 툴로서 동작합니다. Elastic이라는 기업명에 걸맞게 높은 확장성과
kim-dragon.tistory.com