ELK 작업기
- 꼬반
- 2019. 7. 3. 10:06
일단 Elasticsearch는 버전업이 무지하게 빠르다. 무시무시하다.
개발자님들에게 X키를 눌러 JOY를...
그런 환경이므로 elk를 docker를 활용하여 올린다.
docker의 환경설정을 수정하여 docker 볼륨 위치도 변경해놓고 2개 클러스터 512m 램으로
기본 사용하여 mysql의 general 로그를 파싱하여 넣기로 했다.
일단 직접하려고 하루정도 golang으로 삽질하다가 검색 고고싱 아래 사이트들에서 도움을 받았다.
- *<https://pad.yohdah.com/285/mysql-general-query-log-and-logstash>
- <https://qbox.io/blog/mysql-logs-elasticsearch-logstash-kibana>
- <https://qbox.io/blog/ship-mysql-logs-elasticsearch-filebeat>
- *<https://github.com/cj203/logstash-mysql-general-log-filter/blob/master/pipeline.conf>
특히 별표가 있는 사이트가 도움이 되었는데 일단 버전이 다른 부분은 좀더 수정하였다.
첫번째 pad 사이트의 아래 부분의 파이선 스크립트로 general 로그를 전처리를 수행하고
이후 logstash 로 파싱하여 elastic으로 input해주었는데 중간에 filter 부분에 multiline { }
은 현재 사용하는 7.1.1 버전에서는 codec => multiline { } 으로 바꿔 사용하여 주고
filter 부분이 아닌 input 쪽에 넣어주어
input {
file {
codec => multiline {
pattern => "^%{NUMBER}\s+%{NOTSPACE}"
negate => "true"
what => "previous"
}
...
}
처럼 설정해준다.
그럼 path에 지정한 log파일을 파싱해서 input 하는데 대상 로그 사이즈는 2016년10월부터 현재까지 약 80G
로그 파일이고 전처리는 오래 걸리지 않았으나 elk로 전체 data를 입력하는데는 약 5일정도 걸린것 같다...
그리고 중간에 elk memory heap 이 부족하여 error가 났고 docker-composer 를 수정하여
각 node의 메모리를 4G로 / 전체 클러스터를 마스터1 / 노드 3으로 수정하여 이후 문제없이 모두 입력을 받았다.
그리고 이후 입력된 값을 확인하는 중에 사용한 grok 패턴은 connect command 에만 접속한 db, 유저, client 정보가 나오고 나머지엔 나오지 않아 다른 레코드들의 field 를 업데이트 해주어야 했다.
이는 update_by_query 를 통해 수행하였는데
- <https://www.roseindia.net/elasticsearch/elasticsearch-update-by-query-add-field.shtml>
- <https://discuss.elastic.co/t/is-there-any-way-to-update-multiple-fields-by-update-by-query/70644/1>
- <https://discuss.elastic.co/t/add-field-to-existing-document-by-query/68874/1>
다음 사이트들의 도움을 받았고 kibana console 에서
POST /mysql-xxxx-xx-xx/_update_by_query
{
"script": {
"inline": "ctx._source.mysql_database=\"\";ctx._source.mysql_connect_user=\"\";ctx._source.mysql_connect_host=\"\"",
"lang": "painless"
},
"query": {
"match": {
"command": "Query"
}
}
}
특정일에 대한 인덱스에 대해 테스트 후 동작하는 것을 확인하고 mysql-* 로 전체 인덱스에로 쿼리를 수행했다.
그리고 kibana에서 request timeout 으로 정상 수행 결과가 나오지 않는 것을 보고는 날짜별/월별/일별 등 다양한
방법으로 테스트 하였는데 월별 정도로 돌릴때 타임아웃없이 수행된것을 보고 실제 레코드를 확인해보면
필드가 반영이 안되어 있는 등 여러 이슈를 발견하여 해결하기 위해 다양하게 체크를 했는데
결과적으로는 에러가 아니라 실질적으로 해당 쿼리를 수행하고 kibana에서의 대기시간에 return이 없어서
timeout이 난 것뿐 이고
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
002b90c4fc50 es04 229.43% 4.831GiB / 62.65GiB 7.71% 456GB / 159GB 50.1GB / 531GB 215
3052fb09ca6a es01 268.17% 5.363GiB / 62.65GiB 8.56% 1.05TB / 955GB 65.5GB / 597GB 259
73ee3a3d2f17 es03 227.66% 4.868GiB / 62.65GiB 7.77% 442GB / 635GB 49.6GB / 589GB 222
d81350bd7053 kibana 0.55% 174.1MiB / 62.65GiB 0.27% 19.5GB / 1.58GB 437MB / 102kB 14
5b36619c88b5 es02 261.03% 4.857GiB / 62.65GiB 7.75% 499GB / 212GB 61.8GB / 584GB 229
도커 컨테이너의 resoure를 보면 부지런히 해당 쿼리를 수행하고 있음을 알게 되었다. 그래서 이후는 쿼리를 수행시키고
리소스 사용률이 없어질때까지 기다리기..
이후 원하는데로 필드가 추가된 것을 볼수 있었다.