Ver3.0 ๐ ๋ก๊ทธ ์์ง๊ณผ ์ค์ ๊ด๋ฆฌ: ELK Stack ๊ตฌ์ฑ

๐ ๋ก๊ทธ ์์ง๊ณผ ์ค์ ๊ด๋ฆฌ: ELK Stack ๊ตฌ์ฑ
Elasticsearch, Logstash, Kibana๋ก ์์ฑํ๋ ๋ก๊ทธ ๊ด๋ฆฌ ์์คํ
๐ฏ ์ ๋ก๊ทธ ๊ด๋ฆฌ๊ฐ ์ค์ํ ๊น?
์น๊ตฌ์ผ, ์๋ฒ ์ด์ํ๋ค ๋ณด๋ฉด ์ง์ง ๋ต๋ตํ ์๊ฐ์ด ์์ด. ๐คฏ
"์ด? ๊ฐ์๊ธฐ ์๋น์ค๊ฐ ๋๋ ค์ก๋๋ฐ ์ ๊ทธ๋ฐ ๊ฑฐ์ง?"
"์๋ฌ๊ฐ ๋ฌ๋ค๋๋ฐ ์ด๋์ ๋ ๊ฑด์ง ๋ชจ๋ฅด๊ฒ ์ด..."
"์ด์ ๋ฐค์ ๋ฌด์จ ์ผ์ด ์์๋์ง ํ์ธํ๊ณ ์ถ์๋ฐ ๋ก๊ทธ๊ฐ ๋๋ฌด ๋ง์!"
์ด๋ฐ ์ํฉ๋ค, ๊ฐ๋ฐ์๋ผ๋ฉด ํ ๋ฒ์ฏค์ ๊ฒช์ด๋ดค์ ๊ฑฐ์ผ. ์๋ฒ ํ๋๋ง ๊ด๋ฆฌํ ๋๋ ๊ทธ๋ฅ SSH ์ ์ํด์ tail -f ๋ช
๋ น์ด๋ก ๋ก๊ทธ ๋ณด๋ฉด ๋์ง๋ง, ์๋ฒ๊ฐ 10๋, 20๋๋ก ๋์ด๋๋ฉด? ๐ฑ ์ผ์ผ์ด ์ ์ํด์ ํ์ธํ๋ ๊ฑด ์ ๋ง ๋นํจ์จ์ ์ด์ง.
๋ฐ๋ก ์ด๋ด ๋ ํ์ํ ๊ฒ ์ค์ ์ง์ค์ ๋ก๊ทธ ๊ด๋ฆฌ ์์คํ
์ด์ผ! ๊ทธ๋ฆฌ๊ณ ๊ทธ ์ค์์๋ ๊ฐ์ฅ ์ ๋ช
ํ๊ณ ๊ฐ๋ ฅํ ๊ฒ ๋ฐ๋ก ELK Stack์ด์ง. ๐ช
Elasticsearch: ๋ก๊ทธ๋ฅผ ์ ์ฅํ๊ณ ๊ฒ์ํ๋ ๊ฒ์ ์์ง
Logstash: ๋ก๊ทธ๋ฅผ ์์งํ๊ณ ๊ฐ๊ณตํ๋ ํ์ดํ๋ผ์ธ
Kibana: ๋ก๊ทธ๋ฅผ ์๊ฐํํ๊ณ ๋ถ์ํ๋ ๋์๋ณด๋
์ด ์ธ ๊ฐ์ง๊ฐ ํฉ์ณ์ ธ์ ์๋ฒฝํ ๋ก๊ทธ ๊ด๋ฆฌ ์ํ๊ณ๋ฅผ ๋ง๋ค์ด๋ด๋ ๊ฑฐ์ผ! ๐จ
๐๏ธ ELK Stack์ ๊ฐ ๊ตฌ์ฑ ์์ ํํค์น๊ธฐ
1๏ธโฃ Elasticsearch: ๊ฒ์์ ๋ง๋ฒ์ฌ
Elasticsearch๋ Apache Lucene ๊ธฐ๋ฐ์ ๋ถ์ฐ ๊ฒ์ ์์ง์ด์ผ. ๐
์ฝ๊ฒ ๋งํ๋ฉด, ์์ฒญ๋๊ฒ ๋ง์ ๋ฐ์ดํฐ ์์์๋ ์ํ๋ ์ ๋ณด๋ฅผ ๋น์ ์๋๋ก ์ฐพ์์ฃผ๋ ์น๊ตฌ์ง!
์ผ๋ฐ์ ์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ LIKE '%error%' ๊ฐ์ ์ฟผ๋ฆฌ๋ฅผ ๋ ๋ฆฌ๋ฉด ์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ๋ค ๋ค์ ธ์ผ ํด์ ๋๋ ค. ํ์ง๋ง Elasticsearch๋ ์ญ์์ธ(Inverted Index)์ด๋ผ๋ ํน๋ณํ ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํด์, ๊ฒ์์ด ์ ๋ง ๋นจ๋ผ! โก
์ผ๋ฐ ์ฑ ์ ๋ชฉ์ฐจ๋ "1์ฅ์ ์ด๋ฐ ๋ด์ฉ, 2์ฅ์ ์ ๋ฐ ๋ด์ฉ"์ด๋ผ๊ณ ๋์ด ์์ง?
ํ์ง๋ง ์ฑ ๋ค์ ์๋ ์์ธ(Index)์ "์๋ฌ๋ผ๋ ๋จ์ด๋ 15ํ์ด์ง, 47ํ์ด์ง, 89ํ์ด์ง์ ๋์จ๋ค"๊ณ ๋์ด ์์ด.
Elasticsearch๋ ๋ฐ๋ก ์ด ์์ธ ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํด! ๊ทธ๋์ ํน์ ๋จ์ด๋ฅผ ๊ฒ์ํ๋ฉด ๋ฐ๋ก ํด๋น ๋ฌธ์๋ค์ ์ฐพ์ ์ ์๋ ๊ฑฐ์ง. ๐
- โ ๋ถ์ฐ ์ฒ๋ฆฌ: ๋ฐ์ดํฐ๋ฅผ ์ฌ๋ฌ ๋ ธ๋์ ๋๋ ์ ์ ์ฅํ๊ณ ์ฒ๋ฆฌ
- โ ์ค์๊ฐ ๊ฒ์: ๋ฐ์ดํฐ๊ฐ ๋ค์ด์ค๋ฉด ๊ฑฐ์ ์ฆ์ ๊ฒ์ ๊ฐ๋ฅ
- โ RESTful API: HTTP ๊ธฐ๋ฐ์ผ๋ก ์ฝ๊ฒ ์ฌ์ฉ ๊ฐ๋ฅ
- โ ์คํค๋ง ํ๋ฆฌ: JSON ํ์์ผ๋ก ์์ ๋กญ๊ฒ ๋ฐ์ดํฐ ์ ์ฅ
- โ ํ์ฅ์ฑ: ๋ ธ๋๋ง ์ถ๊ฐํ๋ฉด ์ฑ๋ฅ ํฅ์ ๊ฐ๋ฅ
2๏ธโฃ Logstash: ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ์ ๋ฌ์ธ
Logstash๋ ๋ฐ์ดํฐ ์์ง๊ณผ ๊ฐ๊ณต์ ๋ด๋นํ๋ ์น๊ตฌ์ผ. ๐ฐ
๋ง์น ์ ์๊ธฐ์ฒ๋ผ, ์ฌ๋ฌ ๊ณณ์์ ๋ค์ด์ค๋ ์ง์ ๋ถํ ๋ก๊ทธ ๋ฐ์ดํฐ๋ฅผ ๊นจ๋ํ๊ฒ ์ ์ ํด์ Elasticsearch๋ก ๋ณด๋ด์ฃผ์ง.
Logstash์ ๋์ ๋ฐฉ์์ ํฌ๊ฒ ์ธ ๋จ๊ณ๋ก ๋๋์ด:
๋ค์ํ ์์ค์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์. ํ์ผ, ๋ฐ์ดํฐ๋ฒ ์ด์ค, ๋ฉ์์ง ํ, HTTP ๋ฑ๋ฑ... ์ ๋ง ๋ง์ ์ ๋ ฅ ํ๋ฌ๊ทธ์ธ์ด ์์ด! ๐ฅ
๋ฐ์์จ ๋ฐ์ดํฐ๋ฅผ ๊ฐ๊ณตํด. ํ์ฑํ๊ณ , ํ๋๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ์ญ์ ํ๊ณ , ํ์์ ๋ณํํ๊ณ ... ์ด๊ฒ Logstash์ ์ง์ง ํต์ฌ์ด์ผ! ๐ง
๊ฐ๊ณต๋ ๋ฐ์ดํฐ๋ฅผ ๋ชฉ์ ์ง๋ก ๋ณด๋ด. ์ฃผ๋ก Elasticsearch๋ก ๋ณด๋ด์ง๋ง, ํ์ผ์ด๋ ๋ค๋ฅธ ์์คํ ์ผ๋ก๋ ๋ณด๋ผ ์ ์์ด! ๐ค
์๋ฅผ ๋ค์ด๋ณผ๊น? ์น ์๋ฒ์ ์ก์ธ์ค ๋ก๊ทธ๊ฐ ์ด๋ ๊ฒ ์๊ฒผ๋ค๊ณ ํด๋ณด์:
192.168.1.100 - - [15/Jan/2024:10:30:45 +0900] "GET /api/users HTTP/1.1" 200 1234
์ด ํ ์ค์ ๋ก๊ทธ๋ฅผ Logstash๊ฐ ํ์ฑํ๋ฉด:
{
"client_ip": "192.168.1.100",
"timestamp": "2024-01-15T10:30:45+09:00",
"method": "GET",
"path": "/api/users",
"protocol": "HTTP/1.1",
"status_code": 200,
"response_size": 1234
}
์ด๋ ๊ฒ ๊ตฌ์กฐํ๋ JSON ๋ฐ์ดํฐ๋ก ๋ณํํด์ฃผ๋ ๊ฑฐ์ผ! ์ด์ ๊ฐ ํ๋๋ณ๋ก ๊ฒ์ํ๊ณ ๋ถ์ํ ์ ์๊ฒ ๋์ง. ๐
3๏ธโฃ Kibana: ๋ฐ์ดํฐ ์๊ฐํ์ ์์ ๊ฐ
Kibana๋ Elasticsearch์ ์ ์ฅ๋ ๋ฐ์ดํฐ๋ฅผ ์์๊ฒ ์๊ฐํํด์ฃผ๋ ๋๊ตฌ์ผ. ๐
์ซ์์ ํ
์คํธ๋ก๋ง ๊ฐ๋ํ ๋ก๊ทธ๋ฅผ ๋ณด๋ฉด ๋จธ๋ฆฌ๊ฐ ์ํ์์? Kibana๋ ์ด๊ฑธ ๊ทธ๋ํ, ์ฐจํธ, ์ง๋ ๋ฑ์ผ๋ก ๋ณด์ฌ์ค์ ํ๋์ ์ดํดํ ์ ์๊ฒ ๋ง๋ค์ด์ค!
Kibana๋ก ํ ์ ์๋ ๊ฒ๋ค:
Discover ๋ก๊ทธ ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ํ๊ณ ํ์
Visualize ๋ค์ํ ์ฐจํธ์ ๊ทธ๋ํ ์์ฑ
Dashboard ์ฌ๋ฌ ์๊ฐํ๋ฅผ ๋ชจ์์ ๋์๋ณด๋ ๊ตฌ์ฑ
Canvas ์ธํฌ๊ทธ๋ํฝ ์คํ์ผ์ ํ๋ ์ ํ ์ด์ ์ ์
Maps ์ง๋ฆฌ ๋ฐ์ดํฐ๋ฅผ ์ง๋์ ํ์
Machine Learning ์ด์ ํ์ง์ ์์ธก ๋ถ์
Alerting ํน์ ์กฐ๊ฑด์์ ์๋ฆผ ๋ฐ์ก
ํนํ ๋์๋ณด๋ ๊ธฐ๋ฅ์ด ์ ๋ง ์ ์ฉํด! ๐ฏ
์๋ฅผ ๋ค์ด "์ค์๊ฐ ์๋น์ค ๋ชจ๋ํฐ๋ง ๋์๋ณด๋"๋ฅผ ๋ง๋ค๋ฉด:
- ์ด๋น ์์ฒญ ์ ๊ทธ๋ํ
- ์๋ฌ์จ ์ถ์ด
- ์๋ต ์๊ฐ ๋ถํฌ
- ๊ฐ์ฅ ๋ง์ด ํธ์ถ๋๋ API Top 10
- ์ง์ญ๋ณ ์ ์์ ์ง๋
์ด๋ฐ ๊ฒ๋ค์ ํ ํ๋ฉด์ ๋ชจ์์ ๋ณผ ์ ์์ด. ๋ญ๊ฐ ๋ฌธ์ ๊ฐ ์๊ธฐ๋ฉด ๋ฐ๋ก ์์์ฑ ์ ์์ง! ๐จ
๐ ๏ธ ELK Stack ์ค์นํ๊ธฐ
์, ์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ELK Stack์ ์ค์นํด๋ณด์! ๐ช
์ฌ๊ธฐ์๋ Ubuntu 20.04 ๊ธฐ์ค์ผ๋ก ์ค๋ช
ํ ๊ฒ. ๋ค๋ฅธ OS๋ฅผ ์ด๋ค๋ฉด ๊ณต์ ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ๋ฉด ๋ผ.
์ฐธ๊ณ ๋ก, ELK Stack์ ์ฒ์ ์ค์นํ๊ณ ์ค์ ํ๋ ๊ฒ ์ข ๋ณต์กํ ์ ์์ด. ๋ง์ฝ ์ด๋ ค์์ ๊ฒช๋๋ค๋ฉด ์ฌ๋ฅ๋ท์์ ์๋ฒ ๊ตฌ์ถ ์ ๋ฌธ๊ฐ์ ๋์์ ๋ฐ๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด์ผ! ๐ค
๐ฆ ์ฌ์ ์ค๋น์ฌํญ
ELK Stack์ ๊ฝค ๋ง์ ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํด. ์ต์ํ ์ด ์ ๋๋ ํ์ํด:
- CPU: 4์ฝ์ด ์ด์
- RAM: 8GB ์ด์ (๊ถ์ฅ 16GB)
- ๋์คํฌ: 50GB ์ด์ (๋ก๊ทธ ์์ ๋ฐ๋ผ ๋ ํ์)
- Java: OpenJDK 11 ์ด์
1๋จ๊ณ: Java ์ค์น
ELK Stack์ ๋ชจ๋ ๊ตฌ์ฑ ์์๋ Java๋ก ๋ง๋ค์ด์ก์ด. ๊ทธ๋์ ๋จผ์ Java๋ฅผ ์ค์นํด์ผ ํด! โ
# Java ์ค์น
sudo apt update
sudo apt install openjdk-11-jdk -y
# ์ค์น ํ์ธ
java -version
2๋จ๊ณ: Elasticsearch ์ค์น
Elasticsearch๋ถํฐ ์ค์นํด๋ณด์. ๊ณต์ ์ ์ฅ์๋ฅผ ์ถ๊ฐํ๊ณ ์ค์นํ๋ ๋ฐฉ์์ด ๊ฐ์ฅ ๊น๋ํด!
# Elasticsearch GPG ํค ์ถ๊ฐ
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
# ์ ์ฅ์ ์ถ๊ฐ
echo "deb https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
# Elasticsearch ์ค์น
sudo apt update
sudo apt install elasticsearch -y
# ์๋น์ค ์์ ๋ฐ ์๋ ์์ ์ค์
sudo systemctl start elasticsearch
sudo systemctl enable elasticsearch
# ์ค์น ํ์ธ (์ฝ๊ฐ ์๊ฐ์ด ๊ฑธ๋ฆด ์ ์์ด)
curl -X GET "localhost:9200/"
๋ง์ง๋ง ๋ช ๋ น์ด๋ฅผ ์คํํ๋ฉด ์ด๋ฐ ์๋ต์ด ์์ผ ํด:
{
"name" : "your-hostname",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "...",
"version" : {
"number" : "8.x.x",
...
},
"tagline" : "You Know, for Search"
}
Elasticsearch๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์์คํ ๋ฉ๋ชจ๋ฆฌ์ ์ ๋ฐ์ ์ฌ์ฉํ๋ ค๊ณ ํด. ํ์ง๋ง ๋ค๋ฅธ ์๋น์ค๋ ๋์๊ฐ๋ ์๋ฒ๋ผ๋ฉด ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ํํ๋ ๊ฒ ์ข์!
/etc/elasticsearch/jvm.options ํ์ผ์์:
-Xms4g (์ต์ ํ ํฌ๊ธฐ)
-Xmx4g (์ต๋ ํ ํฌ๊ธฐ)
์ด๋ ๊ฒ ์ค์ ํ๋ฉด 4GB๋ก ์ ํํ ์ ์์ด. ๋ ๊ฐ์ ๊ฐ๊ฒ ์ค์ ํ๋ ๊ฒ ์ข์!
3๋จ๊ณ: Kibana ์ค์น
์ด๋ฏธ Elasticsearch ์ ์ฅ์๋ฅผ ์ถ๊ฐํ์ผ๋, Kibana ์ค์น๋ ๊ฐ๋จํด!
# Kibana ์ค์น
sudo apt install kibana -y
# ์๋น์ค ์์ ๋ฐ ์๋ ์์ ์ค์
sudo systemctl start kibana
sudo systemctl enable kibana
Kibana๋ ๊ธฐ๋ณธ์ ์ผ๋ก localhost:5601์์ ์คํ๋ผ. ์ธ๋ถ์์ ์ ์ํ๋ ค๋ฉด ์ค์ ์ ๋ฐ๊ฟ์ผ ํด:
# Kibana ์ค์ ํ์ผ ํธ์ง
sudo nano /etc/kibana/kibana.yml
# ๋ค์ ์ค์ ์ฃผ์์ ์ ๊ฑฐํ๊ณ ์์
server.host: "0.0.0.0"
server.port: 5601
elasticsearch.hosts: ["http://localhost:9200"]
# Kibana ์ฌ์์
sudo systemctl restart kibana
์ด์ ๋ธ๋ผ์ฐ์ ์์ http://์๋ฒIP:5601๋ก ์ ์ํ๋ฉด Kibana ํ๋ฉด์ ๋ณผ ์ ์์ด! ๐
4๋จ๊ณ: Logstash ์ค์น
๋ง์ง๋ง์ผ๋ก Logstash๋ฅผ ์ค์นํ์!
# Logstash ์ค์น
sudo apt install logstash -y
# ์๋น์ค ์์ ๋ฐ ์๋ ์์ ์ค์
sudo systemctl start logstash
sudo systemctl enable logstash
Logstash๋ ์ค์ ํ์ผ์ ์์ฑํด์ผ ์ ๋๋ก ๋์ํด. ์ด๊ฑด ๋ค์ ์น์ ์์ ์์ธํ ๋ค๋ฃฐ๊ฒ! ๐
โ๏ธ Logstash ์ค์ ํ๊ธฐ
Logstash ์ค์ ์ด ELK Stack์์ ๊ฐ์ฅ ์ค์ํ๊ณ ๋ ๋ณต์กํ ๋ถ๋ถ์ด์ผ. ํ์ง๋ง ๊ฑฑ์ ๋ง! ์ฐจ๊ทผ์ฐจ๊ทผ ์์๋ณด๋ฉด ์ด๋ ต์ง ์์. ๐
Logstash ์ค์ ํ์ผ์ /etc/logstash/conf.d/ ๋๋ ํ ๋ฆฌ์ .conf ํ์ฅ์๋ก ์ ์ฅํ๋ฉด ๋ผ.
๊ธฐ๋ณธ ๊ตฌ์กฐ ์ดํดํ๊ธฐ
Logstash ์ค์ ํ์ผ์ ์ธ ๊ฐ์ ์น์ ์ผ๋ก ๊ตฌ์ฑ๋ผ:
input {
# ๋ฐ์ดํฐ๋ฅผ ์ด๋์ ๋ฐ์์ง
}
filter {
# ๋ฐ์ดํฐ๋ฅผ ์ด๋ป๊ฒ ๊ฐ๊ณตํ ์ง
}
output {
# ๋ฐ์ดํฐ๋ฅผ ์ด๋๋ก ๋ณด๋ผ์ง
}
์์ 1: ํ์ผ์์ ๋ก๊ทธ ์ฝ๊ธฐ
๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ์์ ๋ถํฐ ์์ํด๋ณด์. ํ์ผ์์ ๋ก๊ทธ๋ฅผ ์ฝ์ด์ Elasticsearch๋ก ๋ณด๋ด๋ ์ค์ ์ด์ผ:
input {
file {
path => "/var/log/nginx/access.log"
start_position => "beginning"
sincedb_path => "/dev/null"
}
}
filter {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
date {
match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
}
geoip {
source => "clientip"
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
index => "nginx-logs-%{+YYYY.MM.dd}"
}
stdout {
codec => rubydebug
}
}
ํ๋์ฉ ๋ฏ์ด๋ณด์! ๐
- path: ์ฝ์ ํ์ผ ๊ฒฝ๋ก (์์ผ๋์นด๋ ์ฌ์ฉ ๊ฐ๋ฅ)
- start_position: "beginning"์ ํ์ผ ์ฒ์๋ถํฐ, "end"๋ ๋๋ถํฐ
- sincedb_path: ์ด๋๊น์ง ์ฝ์๋์ง ๊ธฐ๋กํ๋ ํ์ผ (ํ ์คํธ์ฉ์ผ๋ก /dev/null ์ฌ์ฉ)
- grok: ์ ๊ทํํ์์ผ๋ก ๋ก๊ทธ ํ์ฑ (COMBINEDAPACHELOG๋ ๋ฏธ๋ฆฌ ์ ์๋ ํจํด)
- date: ํ์์คํฌํ ํ๋๋ฅผ ํ์ฑํด์ @timestamp๋ก ์ค์
- geoip: IP ์ฃผ์๋ก ์ง๋ฆฌ ์ ๋ณด ์ถ๊ฐ (์ด๋ ๋๋ผ์์ ์ ์ํ๋์ง ๋ฑ)
- elasticsearch: Elasticsearch๋ก ๋ฐ์ดํฐ ์ ์ก
- index: ์ธ๋ฑ์ค ์ด๋ฆ (๋ ์ง๋ณ๋ก ๋ถ๋ฆฌ)
- stdout: ์ฝ์์๋ ์ถ๋ ฅ (๋๋ฒ๊น ์ฉ)
์์ 2: Beats๋ก ๋ก๊ทธ ์์งํ๊ธฐ
์ค์ ์ด์ ํ๊ฒฝ์์๋ Filebeat๋ Metricbeat ๊ฐ์ ๊ฒฝ๋ ์์ด์ ํธ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ ๋ ํจ์จ์ ์ด์ผ. ๊ฐ ์๋ฒ์ Beat๋ฅผ ์ค์นํ๊ณ , Logstash๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๋ ๋ฐฉ์์ด์ง! ๐
input {
beats {
port => 5044
}
}
filter {
if [fields][log_type] == "nginx" {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
}
else if [fields][log_type] == "application" {
json {
source => "message"
}
}
mutate {
remove_field => ["agent", "ecs", "host"]
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
index => "%{[fields][log_type]}-%{+YYYY.MM.dd}"
}
}
์ด ์ค์ ์ Beats๋ก๋ถํฐ 5044 ํฌํธ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์, ๋ก๊ทธ ํ์ ์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ์ฒ๋ฆฌํด. ์กฐ๊ฑด๋ฌธ์ ์ฌ์ฉํด์ ์ ์ฐํ๊ฒ ์ฒ๋ฆฌํ ์ ์์ง! ๐ก
Grok ํจํด ๋ง๋ค๊ธฐ
Grok์ ์ ๊ทํํ์์ ์ข ๋ ์ฝ๊ธฐ ์ฝ๊ฒ ๋ง๋ ๊ฑฐ์ผ. ์์ฃผ ์ฌ์ฉํ๋ ํจํด๋ค์ด ๋ฏธ๋ฆฌ ์ ์๋์ด ์์ด์ ํธํด!
์๋ฅผ ๋ค์ด, ์ด๋ฐ ๋ก๊ทธ๊ฐ ์๋ค๊ณ ํด๋ณด์:
2024-01-15 10:30:45 INFO [UserService] User login: user@example.com from 192.168.1.100
์ด๊ฑธ ํ์ฑํ๋ Grok ํจํด์:
%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} \[%{DATA:service}\] %{GREEDYDATA:message}
๊ฒฐ๊ณผ๋ ์ด๋ ๊ฒ ๋์:
{
"timestamp": "2024-01-15 10:30:45",
"level": "INFO",
"service": "UserService",
"message": "User login: user@example.com from 192.168.1.100"
}
Grok ํจํด์ ๋ง๋ค ๋๋ Kibana์ Dev Tools์ ์๋ Grok Debugger๋ฅผ ์ฌ์ฉํ๋ฉด ์ ๋ง ํธํด!
์ค์ ๋ก๊ทธ๋ฅผ ๋ฃ๊ณ ํจํด์ ํ ์คํธํด๋ณผ ์ ์์ด์, ์ํ์ฐฉ์ค๋ฅผ ์ค์ผ ์ ์์ง. ๐ฏ
์ ์ฉํ Filter ํ๋ฌ๊ทธ์ธ๋ค
Grok ๋ง๊ณ ๋ ์ ๋ง ๋ง์ ํํฐ ํ๋ฌ๊ทธ์ธ์ด ์์ด. ์์ฃผ ์ฐ๋ ๊ฒ๋ค์ ์๊ฐํ ๊ฒ!
| ํ๋ฌ๊ทธ์ธ | ์ฉ๋ | ์์ |
|---|---|---|
| mutate | ํ๋ ์ถ๊ฐ/์ญ์ /๋ณ๊ฒฝ | ํ๋๋ช ๋ณ๊ฒฝ, ํ์ ๋ณํ |
| json | JSON ํ์ฑ | JSON ํ์ ๋ก๊ทธ ์ฒ๋ฆฌ |
| csv | CSV ํ์ฑ | CSV ํ์ ๋ฐ์ดํฐ ์ฒ๋ฆฌ |
| useragent | User-Agent ํ์ฑ | ๋ธ๋ผ์ฐ์ , OS ์ ๋ณด ์ถ์ถ |
| drop | ์ด๋ฒคํธ ์ญ์ | ๋ถํ์ํ ๋ก๊ทธ ํํฐ๋ง |
| ruby | Ruby ์ฝ๋ ์คํ | ๋ณต์กํ ์ปค์คํ ๋ก์ง |
์๋ฅผ ๋ค์ด, mutate ํ๋ฌ๊ทธ์ธ์ผ๋ก ์ด๋ฐ ๊ฒ๋ค์ ํ ์ ์์ด:
filter {
mutate {
# ํ๋ ์ถ๊ฐ
add_field => { "environment" => "production" }
# ํ๋๋ช
๋ณ๊ฒฝ
rename => { "old_field" => "new_field" }
# ํ๋ ์ญ์
remove_field => ["unnecessary_field"]
# ํ์
๋ณํ
convert => { "response_time" => "integer" }
# ์๋ฌธ์๋ก ๋ณํ
lowercase => ["username"]
# ๋ฌธ์์ด ์นํ
gsub => ["message", "/", "_"]
}
}
๐จ Kibana๋ก ๋ฐ์ดํฐ ์๊ฐํํ๊ธฐ
์ด์ Elasticsearch์ ๋ก๊ทธ ๋ฐ์ดํฐ๊ฐ ์์ด๊ธฐ ์์ํ์ด! Kibana๋ก ์ด ๋ฐ์ดํฐ๋ฅผ ์์๊ฒ ์๊ฐํํด๋ณด์. ๐ผ๏ธ
1๋จ๊ณ: Index Pattern ์์ฑ
Kibana์์ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ ค๋ฉด ๋จผ์ Index Pattern์ ๋ง๋ค์ด์ผ ํด. ์ด๊ฑด "์ด๋ค ์ธ๋ฑ์ค์ ๋ฐ์ดํฐ๋ฅผ ๋ณผ ๊ฑด์ง" ์๋ ค์ฃผ๋ ๊ฑฐ์ผ.
์ด์ Discover ๋ฉ๋ด์์ ๋ก๊ทธ๋ฅผ ๋ณผ ์ ์์ด! ๐
2๋จ๊ณ: Discover๋ก ๋ก๊ทธ ํ์ํ๊ธฐ
Discover๋ ๋ก๊ทธ๋ฅผ ๊ฒ์ํ๊ณ ํ์ํ๋ ๊ธฐ๋ณธ ๋๊ตฌ์ผ. ์ฌ๊ธฐ์ ํ ์ ์๋ ๊ฒ๋ค:
์๊ฐ ๋ฒ์ ์ ํ
์ค๋ฅธ์ชฝ ์์์ "Last 15 minutes", "Last 7 days" ๋ฑ ์ ํ ๊ฐ๋ฅ. ์ปค์คํ ๋ฒ์๋ ์ค์ ํ ์ ์์ด!
๊ฒ์ ์ฟผ๋ฆฌ
๊ฒ์์ฐฝ์ KQL(Kibana Query Language)์ด๋ Lucene ์ฟผ๋ฆฌ ์ ๋ ฅ
์: response: 500 (500 ์๋ฌ๋ง ๋ณด๊ธฐ)
์: clientip: "192.168.1.*" (ํน์ IP ๋์ญ)
ํ๋ ํํฐ๋ง
์ผ์ชฝ์์ ๋ณด๊ณ ์ถ์ ํ๋๋ง ์ ํํด์ ํ ์ด๋ธ ํํ๋ก ๋ณผ ์ ์์ด
์ ์ฅ ๋ฐ ๊ณต์
๊ฒ์ ์กฐ๊ฑด์ ์ ์ฅํด๋๊ณ ๋์ค์ ๋ค์ ๋ถ๋ฌ์ฌ ์ ์์ด
3๋จ๊ณ: Visualization ๋ง๋ค๊ธฐ
์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ์๊ฐํ๋ฅผ ๋ง๋ค์ด๋ณด์! Kibana๋ ์ ๋ง ๋ค์ํ ์ฐจํธ ํ์ ์ ์ง์ํด. ๐
์์ 1: ์๊ฐ๋๋ณ ์์ฒญ ์ (Line Chart)
X์ถ: Date Histogram, @timestamp ํ๋, Interval์ Auto
์ด๋ ๊ฒ ํ๋ฉด ์๊ฐ๋๋ณ๋ก ๋ก๊ทธ๊ฐ ์ผ๋ง๋ ๋ค์ด์๋์ง ๋ณด์ฌ์ฃผ๋ ๊ทธ๋ํ๊ฐ ์์ฑ๋ผ! ๐
์์ 2: ์ํ ์ฝ๋๋ณ ๋ถํฌ (Pie Chart)
Field: response.keyword (์ํ ์ฝ๋ ํ๋)
Size: 10 (์์ 10๊ฐ)
200, 404, 500 ๋ฑ ์ํ ์ฝ๋๋ณ๋ก ๋น์จ์ ๋ณด์ฌ์ฃผ๋ ํ์ด ์ฐจํธ๊ฐ ๋ง๋ค์ด์ ธ! ๐ฅง
์์ 3: ์ง์ญ๋ณ ์ ์์ (Map)
geoip ํํฐ๋ฅผ ์ฌ์ฉํ๋ค๋ฉด, ์ง๋์ ์ ์์ ์์น๋ฅผ ํ์ํ ์ ์์ด!
Geospatial field: geoip.location
์ธ๊ณ ์ง๋์ ์ ์์๋ค์ด ์ ์ผ๋ก ์ฐํ์ ๋ํ๋! ์ ๋ง ๋ฉ์ง์ง? ๐บ๏ธ
4๋จ๊ณ: Dashboard ๊ตฌ์ฑํ๊ธฐ
์ฌ๋ฌ ๊ฐ์ ์๊ฐํ๋ฅผ ๋ง๋ค์์ผ๋ฉด, ์ด์ ๋์๋ณด๋๋ก ๋ชจ์๋ณด์!
์ด์ ํ ํ๋ฉด์์ ๋ชจ๋ ์ค์ํ ์งํ๋ฅผ ๋ณผ ์ ์์ด! ๐ฏ
์๊ฐ ๋ฒ์๋ฅผ ๋ฐ๊พธ๋ฉด ๋ชจ๋ ์ฐจํธ๊ฐ ๋์์ ์
๋ฐ์ดํธ๋๊ณ , ํ ์ฐจํธ๋ฅผ ํด๋ฆญํ๋ฉด ๋ค๋ฅธ ์ฐจํธ๋ค๋ ํํฐ๋ง๋ผ. ์ ๋ง ๊ฐ๋ ฅํ์ง!
1. ์ค์ํ ์งํ๋ฅผ ์์ชฝ์: ๊ฐ์ฅ ์ค์ํ KPI๋ ๋์๋ณด๋ ์๋จ์ ๋ฐฐ์น
2. ์์ ์ผ๊ด์ฑ: ๊ฐ์ ์๋ฏธ์ ๋ฐ์ดํฐ๋ ๊ฐ์ ์์ ์ฌ์ฉ
3. ์ ์ ํ ํฌ๊ธฐ: ๋๋ฌด ๋ง์ ์ฐจํธ๋ฅผ ๋ฃ์ง ๋ง๊ณ , ๊ฐ ์ฐจํธ๊ฐ ์ถฉ๋ถํ ๋ณด์ด๋๋ก
4. ์๋ ์๋ก๊ณ ์นจ: ์ค์๊ฐ ๋ชจ๋ํฐ๋ง์ด ํ์ํ๋ฉด Auto-refresh ์ค์
5. ํํฐ ํ์ฉ: ๋์๋ณด๋ ๋ ๋ฒจ ํํฐ๋ก ์ ์ฒด ๋ฐ์ดํฐ ๋ฒ์ ์กฐ์
๐ ์ค์ ํ์ฉ ์ฌ๋ก
์ด๋ก ์ ์ถฉ๋ถํ ๋ฐฐ์ ์ผ๋, ์ด์ ์ค์ ๋ก ์ด๋ป๊ฒ ํ์ฉํ๋์ง ๊ตฌ์ฒด์ ์ธ ์ฌ๋ก๋ฅผ ๋ณด์! ๐ผ
์ฌ๋ก 1: ์น ์ ํ๋ฆฌ์ผ์ด์ ๋ชจ๋ํฐ๋ง
์จ๋ผ์ธ ์ผํ๋ชฐ์ ์ด์ํ๋ค๊ณ ๊ฐ์ ํด๋ณด์. ๐
์ฌ๋ฌ ๋์ ์น ์๋ฒ์ API ์๋ฒ๊ฐ ์๊ณ , ๊ฐ๊ฐ ๋ก๊ทธ๋ฅผ ๋จ๊ธฐ๊ณ ์์ด.
- โ ์ค์๊ฐ ํธ๋ํฝ ๋ชจ๋ํฐ๋ง
- โ ์๋ฌ ๋ฐ์ ์ฆ์ ๊ฐ์ง
- โ ๋๋ฆฐ API ์ฐพ์๋ด๊ธฐ
- โ ์ฌ์ฉ์ ํ๋ ํจํด ๋ถ์
- โ ๋ณด์ ์ํ ํ์ง
๊ตฌ์ฑ ๋ฐฉ๋ฒ
1. ๊ฐ ์๋ฒ์ Filebeat ์ค์น
# Filebeat ์ค์น
sudo apt install filebeat -y
# ์ค์ ํ์ผ ํธ์ง
sudo nano /etc/filebeat/filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
fields:
log_type: nginx
environment: production
server_name: web-01
- type: log
enabled: true
paths:
- /var/log/application/*.log
fields:
log_type: application
environment: production
server_name: web-01
output.logstash:
hosts: ["logstash-server:5044"]
2. Logstash์์ ๋ก๊ทธ ์ฒ๋ฆฌ
input {
beats {
port => 5044
}
}
filter {
# ์ ํ๋ฆฌ์ผ์ด์
๋ก๊ทธ ์ฒ๋ฆฌ
if [fields][log_type] == "application" {
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} \[%{DATA:thread}\] %{DATA:logger} - %{GREEDYDATA:log_message}" }
}
# ์๋ฌ ๋ ๋ฒจ์ ๋ฐ๋ผ ํ๊ทธ ์ถ๊ฐ
if [level] == "ERROR" or [level] == "FATAL" {
mutate {
add_tag => ["error"]
}
}
# ์๋ต ์๊ฐ ์ถ์ถ (์๋ ๊ฒฝ์ฐ)
grok {
match => { "log_message" => "response_time=(?<response_time>\d+)ms" }
tag_on_failure => []
}
if [response_time] {
mutate {
convert => { "response_time" => "integer" }
}
# ๋๋ฆฐ ์์ฒญ ํ๊ทธ ์ถ๊ฐ
if [response_time] > 1000 {
mutate {
add_tag => ["slow_request"]
}
}
}
}
# Nginx ๋ก๊ทธ ์ฒ๋ฆฌ
else if [fields][log_type] == "nginx" {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
geoip {
source => "clientip"
}
useragent {
source => "agent"
target => "user_agent"
}
# ์์ฌ์ค๋ฌ์ด ์์ฒญ ํ์ง
if [request] =~ /(\.\.|<script|union.*select|exec\()/i {
mutate {
add_tag => ["suspicious"]
}
}
}
# ๊ณตํต ์ฒ๋ฆฌ
date {
match => [ "timestamp", "ISO8601", "dd/MMM/yyyy:HH:mm:ss Z" ]
target => "@timestamp"
}
mutate {
remove_field => ["agent", "ecs"]
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
index => "%{[fields][log_type]}-%{[fields][environment]}-%{+YYYY.MM.dd}"
}
}
3. Kibana ๋์๋ณด๋ ๊ตฌ์ฑ
๋ค์๊ณผ ๊ฐ์ ์๊ฐํ๋ค์ ๋ง๋ค์ด์ ๋์๋ณด๋์ ๋ฐฐ์นํด:
์๋จ KPI ์์ญ
- ํ์ฌ ์๊ฐ๋ ์ด ์์ฒญ ์ (Metric)
- ์๋ฌ์จ (Metric, ๋นจ๊ฐ์์ผ๋ก ๊ฐ์กฐ)
- ํ๊ท ์๋ต ์๊ฐ (Metric)
- ํ์ฑ ์ฌ์ฉ์ ์ (Unique Count)
์ค๊ฐ ํธ๋ ๋ ์์ญ
- ์๊ฐ๋๋ณ ์์ฒญ ์ (Line Chart)
- ์ํ ์ฝ๋ ๋ถํฌ (Pie Chart)
- ์๋ต ์๊ฐ ๋ถํฌ (Histogram)
- ๊ฐ์ฅ ๋ง์ด ํธ์ถ๋ API Top 10 (Bar Chart)
ํ๋จ ์์ธ ์์ญ
- ์ง์ญ๋ณ ์ ์์ (Map)
- ๋ธ๋ผ์ฐ์ /OS ๋ถํฌ (Pie Chart)
- ์ต๊ทผ ์๋ฌ ๋ก๊ทธ (Data Table)
- ์์ฌ์ค๋ฌ์ด ์์ฒญ (Data Table)
์๋ฆผ ์ค์
Kibana์ Alerting ๊ธฐ๋ฅ์ผ๋ก ๋ฌธ์ ๋ฐ์ ์ ์๋์ผ๋ก ์๋ฆผ์ ๋ฐ์ ์ ์์ด! ๐จ
- Index: application-production-*
- Query: level: "ERROR"
- Threshold: Count > 10 (5๋ถ ๋์ ์๋ฌ๊ฐ 10๊ฐ ์ด์ ๋ฐ์ํ๋ฉด)
์ด์ ์๋ฌ๊ฐ ๊ธ์ฆํ๋ฉด ์๋์ผ๋ก Slack ๋ฉ์์ง๊ฐ ๋ ์์! ๐ฑ
์ฌ๋ก 2: ๋ณด์ ๋ก๊ทธ ๋ถ์
ELK Stack์ ๋ณด์ ๋ชจ๋ํฐ๋ง์๋ ์ ๋ง ์ ์ฉํด. ๐
SSH ๋ก๊ทธ์ธ ์๋, ๋ฐฉํ๋ฒฝ ๋ก๊ทธ, ์น ๊ณต๊ฒฉ ์๋ ๋ฑ์ ์ค์๊ฐ์ผ๋ก ๋ชจ๋ํฐ๋งํ ์ ์์ด.
SSH ๋ก๊ทธ์ธ ๋ชจ๋ํฐ๋ง
filter {
if [fields][log_type] == "auth" {
grok {
match => { "message" => "%{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:hostname} %{DATA:program}(?:\[%{POSINT:pid}\])?: %{GREEDYDATA:log_message}" }
}
# ๋ก๊ทธ์ธ ์คํจ ๊ฐ์ง
if [log_message] =~ /Failed password/ {
grok {
match => { "log_message" => "Failed password for (?:invalid user )?(?<username>\S+) from (?<source_ip>\S+)" }
}
mutate {
add_tag => ["failed_login"]
}
}
# ๋ก๊ทธ์ธ ์ฑ๊ณต ๊ฐ์ง
else if [log_message] =~ /Accepted password/ {
grok {
match => { "log_message" => "Accepted password for (?<username>\S+) from (?<source_ip>\S+)" }
}
mutate {
add_tag => ["successful_login"]
}
}
# ์ง๋ฆฌ ์ ๋ณด ์ถ๊ฐ
if [source_ip] {
geoip {
source => "source_ip"
}
}
}
}
์ด๋ ๊ฒ ์ค์ ํ๋ฉด Kibana์์:
- โ ๋ก๊ทธ์ธ ์คํจ ์๋๊ฐ ๋ง์ IP ์ฐพ๊ธฐ
- โ ๋น์ ์์ ์ธ ์๊ฐ๋์ ๋ก๊ทธ์ธ ๊ฐ์ง
- โ ํด์ธ์์์ ๋ก๊ทธ์ธ ์๋ ๋ชจ๋ํฐ๋ง
- โ ๋ฌด์ฐจ๋ณ ๋์ ๊ณต๊ฒฉ(Brute Force) ํ์ง
์ฌ๋ก 3: ๋น์ฆ๋์ค ๋ถ์
๋ก๊ทธ๋ ๋จ์ํ ์๋ฌ๋ฅผ ์ฐพ๋ ์ฉ๋๋ง์ด ์๋์ผ. ๋น์ฆ๋์ค ์ธ์ฌ์ดํธ๋ฅผ ์ป๋ ๋ฐ๋ ํ์ฉํ ์ ์์ด! ๐
์ ์์๊ฑฐ๋ ๋ถ์ ์์
์ ํ๋ฆฌ์ผ์ด์ ๋ก๊ทธ์ ์ด๋ฐ ์ ๋ณด๋ฅผ ๋จ๊ธด๋ค๋ฉด:
2024-01-15 10:30:45 INFO [OrderService] Order created: order_id=12345, user_id=67890, amount=150000, payment_method=card, items=3
Logstash์์ ํ์ฑํด์:
filter {
grok {
match => { "message" => "Order created: order_id=%{NUMBER:order_id}, user_id=%{NUMBER:user_id}, amount=%{NUMBER:amount}, payment_method=%{WORD:payment_method}, items=%{NUMBER:items}" }
}
mutate {
convert => {
"amount" => "integer"
"items" => "integer"
}
}
}
Kibana์์ ์ด๋ฐ ๋ถ์์ด ๊ฐ๋ฅํด์ ธ:
๐ณ ๊ฒฐ์ ์๋จ๋ณ ์ ํธ๋
๐๏ธ ํ๊ท ์ฃผ๋ฌธ ๊ธ์ก
๐ฆ ํ๊ท ์ฃผ๋ฌธ ์ํ ์
๐ฅ ์ฌ๊ตฌ๋งค์จ ๋ถ์
๐ฏ ํ๋ก๋ชจ์ ํจ๊ณผ ์ธก์
์ด๋ฐ ์์ผ๋ก ELK Stack์ ํ์ฉํ๋ฉด ๋ณ๋์ ๋ถ์ ๋๊ตฌ ์์ด๋ ์ค์๊ฐ์ผ๋ก ๋น์ฆ๋์ค ์งํ๋ฅผ ๋ชจ๋ํฐ๋งํ ์ ์์ด! ๐ก
โก ์ฑ๋ฅ ์ต์ ํ ํ
ELK Stack์ ์ด์ํ๋ค ๋ณด๋ฉด ์ฑ๋ฅ ๋ฌธ์ ์ ๋ถ๋ชํ ์ ์์ด. ํนํ ๋ก๊ทธ ์์ด ๋ง์์ง๋ฉด ๋์ฑ ๊ทธ๋ ์ง. ์ฌ๊ธฐ ๋ช ๊ฐ์ง ์ต์ ํ ํ์ ๊ณต์ ํ ๊ฒ! ๐
Elasticsearch ์ต์ ํ
1. ์ธ๋ฑ์ค ๋ผ์ดํ์ฌ์ดํด ๊ด๋ฆฌ (ILM)
๋ก๊ทธ๋ ์๊ฐ์ด ์ง๋๋ฉด ๋ ์ค์ํด์ง์ง? ์ค๋๋ ๋ก๊ทธ๋ ์ญ์ ํ๊ฑฐ๋ ์์ถํด์ ์ ์ฅ ๊ณต๊ฐ์ ์ ์ฝํ ์ ์์ด.
Hot Phase (0์ผ)
- ์๋ก์ด ๋ฐ์ดํฐ๊ฐ ๋ค์ด์ค๋ ์ธ๋ฑ์ค
- ๋น ๋ฅธ SSD์ ์ ์ฅ
- ๊ฒ์๊ณผ ์ฐ๊ธฐ๊ฐ ๋น๋ฒํจ
Warm Phase (7์ผ ํ)
- ๊ฒ์์ ๊ฐ๋, ์ฐ๊ธฐ๋ ์์
- ์ผ๋ฐ ๋์คํฌ๋ก ์ด๋
- ์ค๋ ์ ์ค์ด๊ธฐ
Cold Phase (30์ผ ํ)
- ๊ฑฐ์ ๊ฒ์ํ์ง ์์
- ์์ถํด์ ์ ์ฅ
- ๋๋ฆฐ ๋์คํฌ ์ฌ์ฉ ๊ฐ๋ฅ
Delete Phase (90์ผ ํ)
- ์ธ๋ฑ์ค ์ญ์
ILM ์ ์ฑ ์ค์ ๋ฐฉ๋ฒ:
PUT _ilm/policy/logs-policy
{
"policy": {
"phases": {
"hot": {
"actions": {
"rollover": {
"max_size": "50GB",
"max_age": "1d"
}
}
},
"warm": {
"min_age": "7d",
"actions": {
"shrink": {
"number_of_shards": 1
},
"forcemerge": {
"max_num_segments": 1
}
}
},
"cold": {
"min_age": "30d",
"actions": {
"freeze": {}
}
},
"delete": {
"min_age": "90d",
"actions": {
"delete": {}
}
}
}
}
}
2. ์ค๋ ์ต์ ํ
Elasticsearch๋ ๋ฐ์ดํฐ๋ฅผ ์ค๋(Shard)๋ผ๋ ๋จ์๋ก ๋๋ ์ ์ ์ฅํด. ์ค๋ ๊ฐ์๊ฐ ๋๋ฌด ๋ง๊ฑฐ๋ ์ ์ผ๋ฉด ์ฑ๋ฅ์ด ๋จ์ด์ ธ! ๐ฏ
- ์ค๋ ํ๋์ ํฌ๊ธฐ: 20GB ~ 50GB๊ฐ ์ ๋น
- ๋ ธ๋๋น ์ค๋ ๊ฐ์: 20๊ฐ ์ดํ ๊ถ์ฅ
- ์์ ์ธ๋ฑ์ค๋ ์ค๋ 1๊ฐ๋ก ์ถฉ๋ถ
- ํฐ ์ธ๋ฑ์ค๋ ๋ ธ๋ ์๋งํผ ์ค๋ ์์ฑ
์: 100GB ๋ฐ์ดํฐ, 3๊ฐ ๋ ธ๋ โ 3๊ฐ ์ค๋ (๊ฐ 33GB)
3. ๋งคํ ์ต์ ํ
ํ๋ ํ์ ์ ์ ์ ํ ์ค์ ํ๋ฉด ์ ์ฅ ๊ณต๊ฐ๊ณผ ๊ฒ์ ์๋๋ฅผ ๊ฐ์ ํ ์ ์์ด!
PUT /nginx-logs-2024.01.15
{
"mappings": {
"properties": {
"@timestamp": {
"type": "date"
},
"clientip": {
"type": "ip"
},
"response": {
"type": "short" // 200, 404 ๋ฑ์ short๋ก ์ถฉ๋ถ
},
"bytes": {
"type": "long"
},
"request": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"message": {
"type": "text",
"index": false // ๊ฒ์ ์ ํ๋ ํ๋๋ ์ธ๋ฑ์ฑ ๋นํ์ฑํ
}
}
}
}
Logstash ์ต์ ํ
1. ํ์ดํ๋ผ์ธ ์์ปค ์กฐ์
Logstash๋ ๊ธฐ๋ณธ์ ์ผ๋ก CPU ์ฝ์ด ์๋งํผ ์์ปค๋ฅผ ์์ฑํด. ํ์ง๋ง ์ํฉ์ ๋ฐ๋ผ ์กฐ์ ์ด ํ์ํ ์ ์์ด.
# /etc/logstash/logstash.yml
pipeline.workers: 4 # ์์ปค ์
pipeline.batch.size: 125 # ํ ๋ฒ์ ์ฒ๋ฆฌํ ์ด๋ฒคํธ ์
pipeline.batch.delay: 50 # ๋ฐฐ์น๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ์๊ฐ(ms)
- CPU ์ง์ฝ์ ํํฐ ๋ง์ โ workers ๋๋ฆฌ๊ธฐ
- ๋คํธ์ํฌ I/O ๋ง์ โ batch.size ๋๋ฆฌ๊ธฐ
- ์ค์๊ฐ์ฑ ์ค์ โ batch.delay ์ค์ด๊ธฐ
- ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ โ batch.size ์ค์ด๊ธฐ
2. ํํฐ ์ต์ ํ
Grok ํจํด์ ์ ๊ทํํ์์ด๋ผ ๋๋ฆด ์ ์์ด. ์ต์ ํ ๋ฐฉ๋ฒ:
- โ ์กฐ๊ฑด๋ฌธ ๋จผ์ ์ฒดํฌ: ๋ถํ์ํ ํํฐ ์คํ ๋ฐฉ์ง
- โ ๊ฐ๋จํ ํจํด ์ฌ์ฉ: GREEDYDATA๋ณด๋ค ๊ตฌ์ฒด์ ์ธ ํจํด
- โ ํํฐ ์์ ์ต์ ํ: ๋น ๋ฅธ ํํฐ๋ฅผ ๋จผ์ ์คํ
- โ ๋ถํ์ํ ํ๋ ์ญ์ : mutate๋ก ๋ฏธ๋ฆฌ ์ ๊ฑฐ
- โ ์บ์ฑ ํ์ฉ: translate ํ๋ฌ๊ทธ์ธ์ผ๋ก ๋ฐ๋ณต ์กฐํ ์ค์ด๊ธฐ
filter {
# ์กฐ๊ฑด๋ฌธ์ผ๋ก ๋ถํ์ํ ์ฒ๋ฆฌ ์คํต
if [fields][log_type] != "nginx" {
drop {}
}
# ๊ฐ๋จํ ํํฐ๋ถํฐ ์คํ
mutate {
remove_field => ["agent", "ecs", "host"]
}
# ๋ณต์กํ Grok์ ๋์ค์
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
}
Kibana ์ต์ ํ
1. ๊ฒ์ ๋ฒ์ ์ ํ
Kibana์์ "Last 30 days" ๊ฐ์ ๋์ ๋ฒ์๋ก ๊ฒ์ํ๋ฉด ๋๋ ค์ ธ. ํ์ํ ๋ฒ์๋ง ๊ฒ์ํ์! โฐ
- ์ผ๋ฐ ๋ชจ๋ํฐ๋ง: Last 15 minutes
- ๋ฌธ์ ์กฐ์ฌ: Last 1 hour
- ํธ๋ ๋ ๋ถ์: Last 7 days
- ์ฅ๊ธฐ ๋ถ์: ์๋ณ ์ธ๋ฑ์ค ํจํด ํ์ฉ
2. ๋์๋ณด๋ ์ต์ ํ
- โ ์๊ฐํ ๊ฐ์ ์ ํ (10๊ฐ ์ดํ ๊ถ์ฅ)
- โ ๋ณต์กํ ์ง๊ณ ์ค์ด๊ธฐ
- โ ์๋ ์๋ก๊ณ ์นจ ๊ฐ๊ฒฉ ๋๋ฆฌ๊ธฐ
- โ ํํฐ ํ์ฉํด์ ๋ฐ์ดํฐ ์ ์ค์ด๊ธฐ
- โ ์บ์ฑ ํ์ฉ (Kibana 7.10+)
๋ชจ๋ํฐ๋ง
ELK Stack ์์ฒด๋ ๋ชจ๋ํฐ๋ง์ด ํ์ํด! Elasticsearch์ Monitoring ๊ธฐ๋ฅ์ ํ์ฑํํ๋ฉด ํด๋ฌ์คํฐ ์ํ๋ฅผ ์ค์๊ฐ์ผ๋ก ๋ณผ ์ ์์ด. ๐
# Monitoring ํ์ฑํ
PUT _cluster/settings
{
"persistent": {
"xpack.monitoring.collection.enabled": true
}
}
Kibana์ Stack Monitoring ๋ฉ๋ด์์ ํ์ธํ ์ ์๋ ๊ฒ๋ค:
- ํด๋ฌ์คํฐ ์ํ (Green/Yellow/Red)
- ๋ ธ๋๋ณ CPU, ๋ฉ๋ชจ๋ฆฌ, ๋์คํฌ ์ฌ์ฉ๋
- ์ธ๋ฑ์ฑ ์๋, ๊ฒ์ ์๋
- ์ค๋ ๋ถํฌ
๐ฐ Logstash
- ํ์ดํ๋ผ์ธ ์ฒ๋ฆฌ๋
- ์ด๋ฒคํธ ์ฒ๋ฆฌ ์๋
- ์๋ฌ ๋ฐ์ ํํฉ
๐จ Kibana
- ์๋ต ์๊ฐ
- ๋์ ์ฌ์ฉ์ ์
- ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋
๐ ๋ณด์ ์ค์
ELK Stack์ ์ธํฐ๋ท์ ๋
ธ์ถํ ๋๋ ๋ณด์์ด ์ ๋ง ์ค์ํด! ๊ธฐ๋ณธ ์ค์ ์ผ๋ก๋ ์ธ์ฆ๋ ์๊ณ ์ํธํ๋ ์ ๋์ด ์๊ฑฐ๋ . ๐ฑ
Elastic Stack 8.x๋ถํฐ๋ ๋ณด์ ๊ธฐ๋ฅ์ด ๊ธฐ๋ณธ์ผ๋ก ํ์ฑํ๋์ง๋ง, ์ ๋๋ก ์ค์ ํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด์!
1. TLS/SSL ์ํธํ
๋คํธ์ํฌ ํต์ ์ ์ํธํํด์ ์ค๊ฐ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ๋ก์ฑ์ง ๋ชปํ๊ฒ ํด์ผ ํด! ๐
์ธ์ฆ์ ์์ฑ
# Elasticsearch ๋๋ ํ ๋ฆฌ๋ก ์ด๋
cd /usr/share/elasticsearch
# CA ์ธ์ฆ์ ์์ฑ
bin/elasticsearch-certutil ca
# ๋
ธ๋ ์ธ์ฆ์ ์์ฑ
bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12
# ์ธ์ฆ์๋ฅผ config ๋๋ ํ ๋ฆฌ๋ก ๋ณต์ฌ
cp elastic-certificates.p12 /etc/elasticsearch/
chmod 660 /etc/elasticsearch/elastic-certificates.p12
chown root:elasticsearch /etc/elasticsearch/elastic-certificates.p12
Elasticsearch ์ค์
# /etc/elasticsearch/elasticsearch.yml
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: elastic-certificates.p12
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: elastic-certificates.p12
2. ์ฌ์ฉ์ ์ธ์ฆ
๊ธฐ๋ณธ ์ฌ์ฉ์๋ค์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ค์ ํ์!
# ์๋์ผ๋ก ๋น๋ฐ๋ฒํธ ์์ฑ
bin/elasticsearch-setup-passwords auto
# ๋๋ ์๋์ผ๋ก ์ค์
bin/elasticsearch-setup-passwords interactive
์์ฑ๋๋ ๊ธฐ๋ณธ ์ฌ์ฉ์๋ค:
๐ค kibana_system: Kibana๊ฐ Elasticsearch์ ์ ์ํ ๋ ์ฌ์ฉ
๐ค logstash_system: Logstash๊ฐ ๋ชจ๋ํฐ๋ง ๋ฐ์ดํฐ ์ ์กํ ๋ ์ฌ์ฉ
๐ค beats_system: Beats๊ฐ ๋ชจ๋ํฐ๋ง ๋ฐ์ดํฐ ์ ์กํ ๋ ์ฌ์ฉ
Kibana ์ค์
# /etc/kibana/kibana.yml
elasticsearch.username: "kibana_system"
elasticsearch.password: "์์ฑ๋_๋น๋ฐ๋ฒํธ"
elasticsearch.ssl.verificationMode: none # ์์ฒด ์๋ช
์ธ์ฆ์ ์ฌ์ฉ ์
Logstash ์ค์
output {
elasticsearch {
hosts => ["https://localhost:9200"]
user => "elastic"
password => "์์ฑ๋_๋น๋ฐ๋ฒํธ"
ssl => true
cacert => "/etc/logstash/ca.crt"
}
}
3. ์ญํ ๊ธฐ๋ฐ ์ ๊ทผ ์ ์ด (RBAC)
๋ชจ๋ ์ฌ๋์๊ฒ ๋ชจ๋ ๊ถํ์ ์ค ์ ์์ง! ์ญํ ์ ๋ง๋ค์ด์ ํ์ํ ๊ถํ๋ง ๋ถ์ฌํ์. ๐ญ
์ญํ ์์ฑ ์์
POST /_security/role/logs_reader
{
"cluster": ["monitor"],
"indices": [
{
"names": ["logs-*"],
"privileges": ["read", "view_index_metadata"]
}
]
}
์ฌ์ฉ์ ์์ฑ ๋ฐ ์ญํ ํ ๋น
POST /_security/user/john
{
"password": "secure_password",
"roles": ["logs_reader"],
"full_name": "John Doe",
"email": "john@example.com"
}
์ด์ john ์ฌ์ฉ์๋ logs-* ์ธ๋ฑ์ค๋ง ์ฝ์ ์ ์์ด! ๐
4. IP ํํฐ๋ง
ํน์ IP์์๋ง ์ ์ํ ์ ์๋๋ก ์ ํํ ์๋ ์์ด.
# /etc/elasticsearch/elasticsearch.yml
xpack.security.http.filter.allow: ["192.168.1.0/24", "10.0.0.0/8"]
xpack.security.http.filter.deny: ["0.0.0.0/0"]
5. ๊ฐ์ฌ ๋ก๊น (Audit Logging)
๋๊ฐ ์ธ์ ๋ฌด์์ ํ๋์ง ๊ธฐ๋ก์ ๋จ๊ธฐ๋ ๊ฒ๋ ์ค์ํด! ๐ต๏ธ
# /etc/elasticsearch/elasticsearch.yml
xpack.security.audit.enabled: true
xpack.security.audit.logfile.events.include: ["access_granted", "access_denied", "authentication_failed"]
- โ TLS/SSL ์ํธํ ํ์ฑํ
- โ ๊ธฐ๋ณธ ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ
- โ ๋ถํ์ํ ์ฌ์ฉ์ ์ญ์
- โ ์ต์ ๊ถํ ์์น ์ ์ฉ
- โ IP ํ์ดํธ๋ฆฌ์คํธ ์ค์
- โ ์ ๊ธฐ์ ์ธ ๋ณด์ ์ ๋ฐ์ดํธ
- โ ๊ฐ์ฌ ๋ก๊ทธ ๋ชจ๋ํฐ๋ง
- โ ๋ฐฑ์ ์ํธํ
๐ง ํธ๋ฌ๋ธ์ํ
ELK Stack์ ์ด์ํ๋ค ๋ณด๋ฉด ์ฌ๋ฌ ๋ฌธ์ ์ ๋ถ๋ชํ ์ ์์ด. ์์ฃผ ๋ฐ์ํ๋ ๋ฌธ์ ๋ค๊ณผ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ ๋ฆฌํด๋ดค์ด! ๐ ๏ธ
๋ฌธ์ 1: Elasticsearch๊ฐ ์์๋์ง ์์์!
systemctl start elasticsearch ์คํ ํ ๋ฐ๋ก ์ข ๋ฃ๋จ
์์ธ
๋๋ถ๋ถ ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ์ด๋ ์ค์ ์ค๋ฅ
ํด๊ฒฐ ๋ฐฉ๋ฒ
1. ๋ก๊ทธ ํ์ธ: journalctl -u elasticsearch -n 100
2. ๋ฉ๋ชจ๋ฆฌ ํ์ธ: free -h
3. JVM ํ ํฌ๊ธฐ ์กฐ์ : /etc/elasticsearch/jvm.options
4. ์ค์ ํ์ผ ๋ฌธ๋ฒ ํ์ธ: YAML ๋ค์ฌ์ฐ๊ธฐ ์ฃผ์!
๋ฌธ์ 2: Elasticsearch ํด๋ฌ์คํฐ๊ฐ Yellow ์ํ์์
ํด๋ฌ์คํฐ ์ํ๊ฐ Green์ด ์๋ Yellow
์์ธ
๋ณต์ ๋ณธ(Replica) ์ค๋๊ฐ ํ ๋น๋์ง ์์
๋จ์ผ ๋ ธ๋์์๋ ๋ณต์ ๋ณธ์ ๋ง๋ค ์ ์์ด์ ์ ์์ ์ธ ์ํฉ!
ํด๊ฒฐ ๋ฐฉ๋ฒ
๋จ์ผ ๋ ธ๋๋ผ๋ฉด ๋ณต์ ๋ณธ ๊ฐ์๋ฅผ 0์ผ๋ก ์ค์ :
PUT _settings
{
"index": {
"number_of_replicas": 0
}
}
๋ฌธ์ 3: Logstash๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ์ง ์์์
Logstash๋ ์คํ ์ค์ธ๋ฐ Elasticsearch์ ๋ฐ์ดํฐ๊ฐ ์ ๋ค์ด์ด
์์ธ
- ์ค์ ํ์ผ ์ค๋ฅ
- ์ ๋ ฅ ์์ค ์ฐ๊ฒฐ ์คํจ
- ํํฐ ํ์ฑ ์คํจ
ํด๊ฒฐ ๋ฐฉ๋ฒ
1. ์ค์ ํ์ผ ํ ์คํธ:
/usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/your-config.conf --config.test_and_exit
/usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/your-config.conf --log.level=debug
output {
stdout {
codec => rubydebug
}
}
๋ฌธ์ 4: Kibana๊ฐ ๋๋ ค์
๋์๋ณด๋ ๋ก๋ฉ์ด ์ค๋ ๊ฑธ๋ฆฌ๊ฑฐ๋ ํ์์์ ๋ฐ์
์์ธ
- ๋๋ฌด ๋์ ์๊ฐ ๋ฒ์ ๊ฒ์
- ๋ณต์กํ ์ง๊ณ ์ฟผ๋ฆฌ
- Elasticsearch ์ฑ๋ฅ ๋ฌธ์
ํด๊ฒฐ ๋ฐฉ๋ฒ
1. ๊ฒ์ ๋ฒ์ ์ค์ด๊ธฐ (Last 15 minutes ๋ฑ)
2. ์๊ฐํ ๊ฐ์ ์ค์ด๊ธฐ
3. ์ธ๋ฑ์ค ํจํด ์ต์ ํ
4. Elasticsearch ์ค๋ ์ํ ํ์ธ:
GET _cat/shards?v&h=index,shard,prirep,state,docs,store&s=store:desc
๋ฌธ์ 5: ๋์คํฌ ๊ณต๊ฐ์ด ๋ถ์กฑํด์
Elasticsearch๊ฐ read-only ๋ชจ๋๋ก ์ ํ๋จ
์์ธ
๋์คํฌ ์ฌ์ฉ๋ฅ ์ด 95%๋ฅผ ๋์ผ๋ฉด ์๋์ผ๋ก ์ฐ๊ธฐ ์ฐจ๋จ
ํด๊ฒฐ ๋ฐฉ๋ฒ
1. ์ค๋๋ ์ธ๋ฑ์ค ์ญ์ :
DELETE /logs-2023.01.*
PUT _all/_settings
{
"index.blocks.read_only_allow_delete": null
}
4. ๋์คํฌ ์ถ๊ฐ ๋๋ ๋ ธ๋ ์ถ๊ฐ
๋ฌธ์ 6: Grok ํจํด์ด ๋งค์นญ๋์ง ์์์
_grokparsefailure ํ๊ทธ๊ฐ ๋ถ์
์์ธ
๋ก๊ทธ ํ์๊ณผ Grok ํจํด์ด ๋ง์ง ์์
ํด๊ฒฐ ๋ฐฉ๋ฒ
1. Kibana Dev Tools์ Grok Debugger ์ฌ์ฉ
2. ์ค์ ๋ก๊ทธ ์ํ๋ก ํ ์คํธ
3. ํจํด์ ๋จ๊ณ์ ์ผ๋ก ์์ฑ:
# ๊ฐ๋จํ ํจํด๋ถํฐ ์์
%{TIMESTAMP_ISO8601:timestamp}
# ์ ์ง์ ์ผ๋ก ํ์ฅ
%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level}
# ์ต์ข
ํจํด
%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} \[%{DATA:service}\] %{GREEDYDATA:message}
๋ฌธ์ 7: ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ (Out of Memory)
Elasticsearch๋ Logstash๊ฐ ๊ฐ์๊ธฐ ์ข ๋ฃ๋จ
์์ธ
JVM ํ ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ
ํด๊ฒฐ ๋ฐฉ๋ฒ
1. ํ ํฌ๊ธฐ ์กฐ์ (์์คํ ๋ฉ๋ชจ๋ฆฌ์ 50% ์ดํ):
# Elasticsearch
# /etc/elasticsearch/jvm.options
-Xms4g
-Xmx4g
# Logstash
# /etc/logstash/jvm.options
-Xms2g
-Xmx2g
GET _nodes/stats/jvm?human
4. ๋ฐฐ์น ํฌ๊ธฐ ์ค์ด๊ธฐ
๋ฌธ์ ๊ฐ ์๊ธฐ๋ฉด ํญ์ ๋ก๊ทธ๋ถํฐ ํ์ธํด!
Elasticsearch: /var/log/elasticsearch/
Logstash: /var/log/logstash/
Kibana: /var/log/kibana/
๊ทธ๋ฆฌ๊ณ ์ฌ๋ฅ๋ท์์ ELK Stack ์ ๋ฌธ๊ฐ์ ๋์์ ๋ฐ๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด์ผ! ๋ณต์กํ ๋ฌธ์ ๋ ๊ฒฝํ ๋ง์ ์ฌ๋์ ์กฐ์ธ์ด ํฐ ๋์์ด ๋๊ฑฐ๋ . ๐ค
๐ ์ถ๊ฐ ํ์ต ์๋ฃ
ELK Stack์ ์ ๋ง ๋ฐฉ๋ํ ์ํ๊ณ์ผ. ์ฌ๊ธฐ์ ๋ค๋ฃฌ ๋ด์ฉ์ ๊ธฐ๋ณธ์ ์ธ ๊ฒ๋ค์ด๊ณ , ๋ ๊น์ด ๊ณต๋ถํ๊ณ ์ถ๋ค๋ฉด ์ด๋ฐ ์๋ฃ๋ค์ ์ฐธ๊ณ ํด๋ด! ๐
- Elasticsearch ๊ณต์ ๋ฌธ์: elastic.co/guide/en/elasticsearch
- Logstash ๊ณต์ ๋ฌธ์: elastic.co/guide/en/logstash
- Kibana ๊ณต์ ๋ฌธ์: elastic.co/guide/en/kibana
- Beats ๊ณต์ ๋ฌธ์: elastic.co/guide/en/beats
- Elastic ๊ณต์ ํธ๋ ์ด๋
- Udemy์ ELK Stack ๊ฐ์ข๋ค
- YouTube์ Elastic ์ฑ๋
- ํ๊ตญ์ด ๋ธ๋ก๊ทธ์ ์ปค๋ฎค๋ํฐ
- Docker Compose๋ก ๋ก์ปฌ ํ๊ฒฝ ๊ตฌ์ถ
- Elastic Cloud ๋ฌด๋ฃ ์ฒดํํ
- AWS/GCP์ Elasticsearch ์๋น์ค
- ๊ฐ์ ๋จธ์ ์ ์ง์ ์ค์น
- Elastic ๊ณต์ ํฌ๋ผ
- Stack Overflow์ elasticsearch ํ๊ทธ
- Reddit์ r/elasticsearch
- ํ๊ตญ Elastic ์ฌ์ฉ์ ๊ทธ๋ฃน
๋ค์ ๋จ๊ณ๋ก ๋์๊ฐ๊ธฐ
๊ธฐ๋ณธ์ ๋ง์คํฐํ๋ค๋ฉด, ์ด๋ฐ ๊ณ ๊ธ ์ฃผ์ ๋ค๋ ๋์ ํด๋ด! ๐
1. Machine Learning
Elasticsearch์ ML ๊ธฐ๋ฅ์ผ๋ก ์ด์ ํ์ง์ ์์ธก ๋ถ์
2. APM (Application Performance Monitoring)
์ ํ๋ฆฌ์ผ์ด์ ์ฑ๋ฅ์ ์ค์๊ฐ์ผ๋ก ๋ชจ๋ํฐ๋ง
3. SIEM (Security Information and Event Management)
๋ณด์ ์ด๋ฒคํธ ํตํฉ ๊ด๋ฆฌ
4. ํด๋ฌ์คํฐ ๊ด๋ฆฌ
๋ค์ค ๋ ธ๋ ํด๋ฌ์คํฐ ๊ตฌ์ฑ๊ณผ ์ด์
5. ๊ณ ๊ฐ์ฉ์ฑ (HA)
์ฅ์ ๋์๊ณผ ๋ฌด์ค๋จ ์ด์
6. ์ฑ๋ฅ ํ๋
๋์ฉ๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์ต์ ํ
7. ์ปค์คํ ํ๋ฌ๊ทธ์ธ ๊ฐ๋ฐ
ํน์ํ ์๊ตฌ์ฌํญ์ ์ํ ํ๋ฌ๊ทธ์ธ ์ ์
๐ฌ ๋ง๋ฌด๋ฆฌํ๋ฉฐ
์! ์ฌ๊ธฐ๊น์ง ์ฝ์๋ค๋ฉด ์ ๋ง ๋๋จํด! ๐
ELK Stack์ ์ฒ์์๋ ๋ณต์กํด ๋ณด์ด์ง๋ง, ํ๋์ฉ ์ฐจ๊ทผ์ฐจ๊ทผ ์ตํ๋ค ๋ณด๋ฉด ์ ๋ง ๊ฐ๋ ฅํ ๋๊ตฌ๋ผ๋ ๊ฑธ ์๊ฒ ๋ ๊ฑฐ์ผ.
๋ก๊ทธ ๊ด๋ฆฌ๋ ๋จ์ํ ์๋ฌ๋ฅผ ์ฐพ๋ ๊ฒ ์ด์์ ์๋ฏธ๊ฐ ์์ด. ์์คํ
์ ๊ฑด๊ฐ ์ํ๋ฅผ ํ์
ํ๊ณ , ์ฌ์ฉ์ ํ๋์ ์ดํดํ๊ณ , ๋น์ฆ๋์ค ์ธ์ฌ์ดํธ๋ฅผ ์ป๋ ๋ฐ ํ์ฉํ ์ ์์ง. ๐
ELK Stack์ ์ ํ์ฉํ๋ฉด:
- โ ๋ฌธ์ ๋ฅผ ๋น ๋ฅด๊ฒ ๋ฐ๊ฒฌํ๊ณ ํด๊ฒฐํ ์ ์์ด
- โ ์์คํ ์ฑ๋ฅ์ ์ง์์ ์ผ๋ก ๊ฐ์ ํ ์ ์์ด
- โ ๋ณด์ ์ํ์ ์กฐ๊ธฐ์ ํ์งํ ์ ์์ด
- โ ๋ฐ์ดํฐ ๊ธฐ๋ฐ์ ์์ฌ๊ฒฐ์ ์ ํ ์ ์์ด
- โ ํ ์ ์ฒด์ ์์ฐ์ฑ์ด ํฅ์๋ผ
์ฒ์ ์์ํ ๋๋ ์์ ๊ท๋ชจ๋ก ์์ํด๋ด. ํ๋ ๊ฐ์ ์๋ฒ ๋ก๊ทธ๋ง ์์งํด์ ๊ธฐ๋ณธ์ ์ธ ๋์๋ณด๋๋ฅผ ๋ง๋ค์ด๋ณด๋ ๊ฑฐ์ผ. ๊ทธ๋ฌ๋ค ๋ณด๋ฉด ์ ์ ๋ ๋ง์ ๊ฒ๋ค์ ๋ชจ๋ํฐ๋งํ๊ณ ์ถ์ด์ง ๊ฑฐ๊ณ , ์์ฐ์ค๋ฝ๊ฒ ์ค๋ ฅ์ด ๋์ด๋ ๊ฑฐ์ผ! ๐ช
ํน์ ๊ตฌ์ถํ๋ค๊ฐ ๋งํ๋ ๋ถ๋ถ์ด ์๊ฑฐ๋, ๋ ์ ๋ฌธ์ ์ธ ๋์์ด ํ์ํ๋ค๋ฉด ์ฌ๋ฅ๋ท์์ ELK Stack ์ ๋ฌธ๊ฐ๋ฅผ ์ฐพ์๋ณด๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด์ผ. ๊ฒฝํ ๋ง์ ์ ๋ฌธ๊ฐ์ ์กฐ์ธ ํ๋ง๋๊ฐ ๋ฉฐ์น ๊ฐ์ ์ฝ์ง์ ์ค์ฌ์ค ์ ์๊ฑฐ๋ ! ๐
์, ์ด์ ์ง์ ELK Stack์ ์ค์นํ๊ณ ์ค์ ํด๋ณด์! ์ค์ต์ด ์ต๊ณ ์ ํ์ต ๋ฐฉ๋ฒ์ด๋๊น. ํ์ดํ
! ๐โจ
๋ก๊ทธ์ ํจ๊ปํ๋ ์ฆ๊ฑฐ์ด ๊ฐ๋ฐ ๋์ธ์! ๐
๊ด๋ จ ํค์๋
๋๊ธ ์์ฑ
์ด ๊ธ์ ๋ํ ์ฌ๋ฌ๋ถ์ ์๊ฐ์ ๋ค๋ ค์ฃผ์ธ์
๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค
๋๊ธ์ ์์ฑํ๋ ค๋ฉด ๋จผ์ ๋ก๊ทธ์ธํด์ฃผ์ธ์.
๋๊ธ 0
์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
์์ง ๋๊ธ์ด ์์ต๋๋ค.