[root@elk-master ~]# curl -XGET localhost:9200/_cat
=^.^= 😺 고양이!
/_cat/allocation
/_cat/shards
/_cat/shards/{index}
/_cat/master
/_cat/nodes
/_cat/tasks
/_cat/indices
# 전체 alias 조회
# 지금은 alias를 설정한 것이 없기때문에 대부분 비어있다.
[root@elk-master ~]# curl -XGET localhost:9200/_alias?pretty
{
"movie_search" : {
"aliases" : { }
},
"ilm-history-3-000001" : {
"aliases" : {
"ilm-history-3" : {
"is_write_index" : true,
"is_hidden" : true
}
}
},
"sshd_fail-2022.10" : {
"aliases" : { }
},
".async-search" : {
"aliases" : { }
},
"apache-web-log-applied-mapping" : {
"aliases" : { }
},
".apm-custom-link" : {
"aliases" : { }
},
".kibana_1" : {
"aliases" : {
".kibana" : { }
}
},
"ktmagazines" : {
"aliases" : { }
},
"books" : {
"aliases" : { }
},
"ktbooks" : {
"aliases" : { }
},
".kibana-event-log-7.10.2-000001" : {
"aliases" : {
".kibana-event-log-7.10.2" : {
"is_write_index" : true
}
}
},
"apache-web-log" : {
"aliases" : { }
},
".kibana_task_manager_1" : {
"aliases" : {
".kibana_task_manager" : { }
}
},
".apm-agent-configuration" : {
"aliases" : { }
}
}
# 인덱스의 alias만 조회하기 -> 현재는 alias 없음
[root@elk-master ~]# curl -XGET localhost:9200/kibana_sample_data_flights/_alias?pretty
{
"kibana_sample_data_flights" : {
"aliases" : { }
}
}
# kibana_sample_data_flights에 fligths alias 생성하기
curl -XPOST localhost:9200/_aliases?pretty -H 'Content-Type: application/json' -d'
{
"actions": [
{ "add" : { "index": "kibana_sample_data_flights", "alias": "flights" } }
]
}'
# 생성한 인덱스 확인
[root@elk-master ~]# curl -XGET localhost:9200/kibana_sample_data_flights/_alias?pretty {
"kibana_sample_data_flights" : {
"aliases" : {
"flights" : { }
}
}
}
# 나머지 샘플 데이터에도 alias 생성
curl -XPOST localhost:9200/_aliases?pretty -H 'Content-Type: application/json' -d'
{
"actions": [
{ "add" : { "index": "kibana_sample_data_logs", "alias": "weblogs" } }
]
}'
curl -XPOST localhost:9200/_aliases?pretty -H 'Content-Type: application/json' -d'
{
"actions": [
{ "add" : { "index": "kibana_sample_data_ecommerce", "alias": "ecommerce" } }
]
}'
# reindex
curl -XPOST http://localhost:9200/_reindex -H 'Content-Type: application/json' -d '{
"source": {
"index": "kibana_sample_data_flights"
},
"dest": {
"index": "air-flights"
}
}'
{"took":3398,"timed_out":false,"total":13059,"updated":0,"created":13059,"deleted":0,"batches":14,"version_conflicts":0,"noops":0,"retries":{"bulk":0,"search":0},"throttled_millis":0,"requests_per_second":-1.0,"throttled_until_millis":0,"failures":[]}
curl -XGET localhost:9200/_cat/aliases?v
[root@elk-master ~]# curl -XGET localhost:9200/_cat/aliases?v
alias index filter routing.index routing.search is_write_index
.kibana .kibana_1 - - - -
flights kibana_sample_data_flights - - - -
weblogs kibana_sample_data_logs - - - -
.kibana-event-log-7.10.2 .kibana-event-log-7.10.2-000001 - - - true
.kibana_task_manager .kibana_task_manager_1 - - - -
ilm-history-3 ilm-history-3-000001 - - - true
ecommerce kibana_sample_data_ecommerce - - - -
[root@elk-master ~]# cd /etc/logstash/conf.d
젤 마지막에 날짜에 .DD만 추가
[root@elk-master conf.d]# vi sshd_fail.conf
[root@elk-master conf.d]# cat sshd_fail.conf
input {
file {
type => "secure_log"
path => "/var/log/secure"
}
}
filter {
grok {
add_tag => ["sshd_fail"]
match => {"message" => "Failed %{WORD:sshd_auth_type} for %{USERNAME:sshd_invalid_user} from %{IP:sshd_client_ip} port %{NUMBER:sshd_port} %{GREEDYDATA:sshd_protocol}"}
}
}
output {
elasticsearch {
index => "sshd_fail-%{+YYYY.MM.DD}"
}
}
/usr/share/logstash/bin/logstash -f ./sshd_fail.conf
--- 다른 터미널에서 실패 접근 시도
아래와 같이 sshd_fail 인덱스가 2개가 생겼으면 성공~
이제 이걸 합쳐보자
# 합치기 전 상태
[root@elk-master ~]# curl localhost:9200/_cat/indices?v | grep ssh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2413 100 2413 0 0 73531 0 --:--:-- --:--:-- --:--:-- 75406
yellow open sshd_fail-2022.10 JnDIOVAnSg2bHmReNFzn5A 1 1 154 0 149.3kb 149.3kb
yellow open sshd_fail-2022.10.301 2t8KD9OkRvekpAhamerK9w 1 1 56 0 51.3kb 51.3kb
# reindex로 인덱스 합치기
curl -XPOST http://localhost:9200/_reindex -H 'Content-Type: application/json' -d '{
"source": {
"index": ["sshd_fail-2022.10", "sshd_fail-2022.10.301"]
},
"dest": {
"index": "sshd_fail-2210",
"type": "doc"
}
}'
{"took":419,"timed_out":false,"total":210,"updated":0,"created":210,"deleted":0,"batches":1,"version_conflicts":0,"noops":0,"retries":{"bulk":0,"search":0},"throttled_millis":0,"requests_per_second":-1.0,"throttled_until_millis":0,"failures":[]}
# 인덱스 조회하기
[root@elk-master ~]# curl localhost:9200/_cat/indices?v | grep ssh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2540 100 2540 0 0 52374 0 --:--:-- --:--:-- --:--:-- 52916
yellow open sshd_fail-2210 xNVXjpP_T2iT9ERVRjefTQ 1 1 💡210 0 63.4kb 63.4kb
yellow open sshd_fail-2022.10.301 2t8KD9OkRvekpAhamerK9w 1 1 56 0 51.3kb 51.3kb
yellow open sshd_fail-2022.10 JnDIOVAnSg2bHmReNFzn5A 1 1 154 0 149.3kb 149.3kb
검색 창에 DevTools
검색 or 왼쪽 네비게이션바 아래에 DevTools
클릭
?size=0
:집계된 document 들의 데이터는 불
필요하므로 결과는 반환하지 않는다
[root@elk-master ~]# curl localhost:9200/_cat/indices?v | grep apache
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2540 100 2540 0 0 75464 0 --:--:-- --:--:-- --:--:-- 79375
red open apache-web-log-applied-mapping v3YoHAaCSsOqbndazA-iaw 5 1 4037 0 3.8mb 3.8mb
red open apache-web-log A_VVv_QbRKGgm2uAp0HRSg 5 1 7964 0 7mb 7mb
[root@elk-master ~]#
# 합산 집계 (sum)를 통해 해당 서버로 유입된 데이터 집계
# 총 bytes 수를 더해라
GET /apache-web-log/_search?size=0
{
"aggs": {
"total_bytes": {
"sum": {
"field": "bytes"
}
}
}
}
# 특정 지역(Paris)에서 서버로 유입된 데이터 합산 집계
GET /apache-web-log/_search?size=0
{
"query": {
"constant_score": {
"filter": {
"match": {"geoip.city_name": "Paris" }
}
}
},
"aggs": {
"total_bytes": {
"sum": {
"field": "bytes"
}
}
}
}
# 평균 집계(avg)를 통해 해당 서버로 유입된 데이터의 평균 집계
GET /apache-web-log/_search?size=0
{
"aggs": {
"avg_bytes": {
"avg": {
"field": "bytes"
}
}
}
}
# 파리에서 서버로 유입된 데이터의 최대(max) 값
GET /apache-web-log/_search?size=0
{
"query": {
"constant_score": {
"filter": {
"match": {"geoip.city_name": "Paris" }
}
}
},
"aggs": {
"total_bytes": {
"max": {
"field": "bytes"
}
}
}
}
# 파리에서 서버로 유입된 데이터의 최소(min) 값
GET /apache-web-log/_search?size=0
{
"query": {
"constant_score": {
"filter": {
"match": {"geoip.city_name": "Paris" }
}
}
},
"aggs": {
"total_bytes": {
"min": {
"field": "bytes"
}
}
}
}
# 파리에서 서버로 유입된 데이터의 갯수(value_count)
GET /apache-web-log/_search?size=0
{
"query": {
"constant_score": {
"filter": {
"match": {"geoip.city_name": "Paris" }
}
}
},
"aggs": {
"total_bytes": {
"value_count": {
"field": "bytes"
}
}
}
}
# 통계 집계(stats aggregation): 모든 집계 결과값 출력
GET /apache-web-log/_search?size=0
{
"aggs": {
"bytes_stats": {
"stats": {
"field": "bytes"
}
}
}
}
# 특정 지역의 통계 집계(stats aggregation)
GET /apache-web-log/_search?size=0
{
"query": {
"constant_score": {
"filter": {
"match": {"geoip.city_name": "Paris" }
}
}
},
"aggs": {
"bytes_stats": {
"stats": {
"field": "bytes"
}
}
}
}
# 확장 통계 집계 (표준편차, 분산 등..)
GET /apache-web-log/_search?size=0
{
"aggs": {
"bytes_extended_stats": {
"extended_stats": {
"field": "bytes"
}
}
}
}
# 특정 지역(파리) 확장 통계 집계
GET /apache-web-log/_search?size=0
{
"query": {
"constant_score": {
"filter": {
"match": {"geoip.city_name": "Paris" }
}
}
},
"aggs": {
"bytes_extended_stats": {
"extended_stats": {
"field": "bytes"
}
}
}
}
# 카디널리티 집계(Cardinality aggregation)은 중복 값을 제외한 고유 값 집계
# 웹로그에서 미국의 몇 개 도시에서 데이터 유입이 있었는지 횟수 집계(💡terms 이용)
# 결과는 미국 내에서 요청 수가 가장 많은 도시 순으로 출력
GET /apache-web-log/_search?size=0
{
"query": {
"constant_score": {
"filter": {
"match": {"geoip.country_name": "United States" }
}
}
},
"aggs": {
"us_city_names": {
"terms": {
"field": "geoip.city_name.keyword",
"size": 20
}
}
}
}
# 미국 내 몇 개의 도시에서 데이터가 유입되었는지 확인
GET /apache-web-log/_search?size=0
{
"query": {
"constant_score": {
"filter": {
"match": {"geoip.country_name": "United States" }
}
}
},
"aggs": {
"us_cardinality": {
"cardinality": {
"field": "geoip.city_name.keyword"
}
}
}
}
#백분위 수 집계를 통해 백분위에 대한 구간 분포 비율 확인
GET /apache-web-log/_search?size=0
{
"aggs": {
"bytes_percentiles": {
"percentiles": {
"field": "bytes"
}
}
}
}
# 백분위에 대한 구간 분포 비율 지정을 통해 확인
[실무팁] 이것을 활용해 서버 사양보다 너무 큰 데이터가 유입되는 경우 데이터 크기를 조절해서 서비스 품질을 개선할 수 있다.
GET /apache-web-log/_search?size=0
{
"aggs": {
"bytes_percentiles": {
"percentiles": {
"field": "bytes",
"percents": [
10,
20,
30,
40,
50,
60,
70,
80,
90
]
}
}
}
}
# 백분위 수 Rank 집계
# 백분위 수 집계와 반대로 백분위를 지정해서 백분위 수를 확인하고, 이것은 특정 필드 수치를 통해 백분위 수 구간을 확인할 수 있다.
GET /apache-web-log/_search?size=0
{
"aggs": {
"bytes_percentile_ranks": {
"percentile_ranks": {
"field": "bytes",
"values": [5000, 10000]
}
}
}
}
# 지형경계 집계는 지형 좌표 필드를 통해 해당 지역 경계를 계산(geo_point)
GET /apache-web-log-applied-mapping/_search?size=0
{
"aggs": {
"viewport": {
"geo_bounds": {
"field": "geoip.location",
"wrap_longitude": true
}
}
}
}
# 유럽 지역 지형 경계 집계 geo_point
GET /apache-web-log-applied-mapping/_search?size=0
{
"query": {
"constant_score": {
"filter": {
"match": { "geoip.continent_code": "EU" }
}
}
},
"aggs": {
"viewport": {
"geo_bounds": {
"field": "geoip.location",
"wrap_longitude": true
}
}
}
}
# tokenizer 설정하기
PUT kakao_nori
{
"settings": {
"analysis": {
"tokenizer": {
"kakao_nori_tokenizer": {
"type": "nori_tokenizer",
"user_dictionary_rules": [
"해물"]
}
}
}
}
}
GET kakao_nori/_analyze
{
"tokenizer": "kakao_nori_tokenizer",
"text": [
"동해물과"]
}
PUT kakao_nori2
{
"settings": {
"analysis": {
"tokenizer": {
"nori_none": {
"type": "nori_tokenizer",
"decompound_mode": "none"
},
"nori_discard": {
"type": "nori_tokenizer",
"decompound_mode": "discard"
},
"nori_mixed": {
"type": "nori_tokenizer",
"decompound_mode": "mixed"
}
}
}
}
}
GET kakao_nori2/_analyze
{
"tokenizer": "nori_none",
"text": ["백두산이"]
}
GET kakao_nori2/_analyze
{
"tokenizer": "nori_discard",
"text": ["백두산이"]
}
GET kakao_nori2/_analyze
{
"tokenizer": "nori_mixed",
"text": ["백두산이"]
}
PUT kakao_pos
{
"settings": {
"index": {
"analysis": {
"filter": {
"kakao_pos_f": {
"type": "nori_part_of_speech",
"stoptags" :[
"NR", "J"
]
}
}
}
}
}
}
GET kakao_pos/_analyze
{
"tokenizer": "nori_tokenizer",
"filter": ["nori_readingform"],
"text": "孤軍奮鬪"
}
GET kakao_pos/_analyze
{
"tokenizer": "nori_tokenizer",
"filter": ["nori_readingform"],
"text": "苦盡甘來"
}
# filebeat 설치
[root@elk-master LABs]# yum -y install filebeat-7.10.2-1
# filebeat 설정
vim /etc/filebeat/filebeat.yml
24 enabled: true # 수정
110 index.codec: best_compression # 주석 해제
# 도착지가 logstash니까 여기는 주석처리해준다.
176 # output.elasticsearch:
177 # Array of hosts to connect to.
178 # hosts: ["localhost:9200"]
189 output.logstash: # 주석 해제
191 hosts: ["192.168.56.101:5044"] # 주석 해제 & 수정
[root@elk-master LABs]# systemctl restart filebeat.service
# 열려있는 방화벽 확인
[root@elk-master LABs]# firewall-cmd --list-all
FirewallD is not running
[root@elk-master LABs]# systemctl start firewalld.service
[root@elk-master LABs]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: enp0s3 enp0s8
sources:
services: dhcpv6-client ssh
ports: 9200/tcp 9300/tcp 5443/tcp 5443/udp 5601/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
# 방화벽에 5044/tcp 포트 열기
[root@elk-master LABs]# firewall-cmd --add-port=5044/tcp --permanent --zone=public
success
[root@elk-master LABs]# firewall-cmd --reload
success
[root@elk-master LABs]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: enp0s3 enp0s8
sources:
services: dhcpv6-client ssh
ports: 9200/tcp 9300/tcp 5443/tcp 5443/udp 5601/tcp 5044/tcp
[root@elk-master LABs]# vim /etc/logstash/conf.d/appserver-log.conf
input {
beats {
port => 5044
}
}
output {
elasticsearch {
hosts => ["192.168.56.101:9200"]
index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
}
}
# 전체 시스템 로그를 타켓으로 로그 수집
[root@elk-master conf.d]# /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/appserver-log.conf
⭐ 📘 📗 💭 🤔 📕 📔 🐳 ✍ 🥳 ⭐ 🐣 👻 💡 💻