์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐Ÿ” ๋กœ๊ทธ ์ˆ˜์ง‘๊ณผ ์ค‘์•™ ๊ด€๋ฆฌ: ELK Stack ๊ตฌ์„ฑ

๐Ÿ” ๋กœ๊ทธ ์ˆ˜์ง‘๊ณผ ์ค‘์•™ ๊ด€๋ฆฌ: ELK Stack ๊ตฌ์„ฑ

Elasticsearch, Logstash, Kibana๋กœ ์™„์„ฑํ•˜๋Š” ๋กœ๊ทธ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ

๐ŸŽฏ ์™œ ๋กœ๊ทธ ๊ด€๋ฆฌ๊ฐ€ ์ค‘์š”ํ• ๊นŒ?

์นœ๊ตฌ์•ผ, ์„œ๋ฒ„ ์šด์˜ํ•˜๋‹ค ๋ณด๋ฉด ์ง„์งœ ๋‹ต๋‹ตํ•œ ์ˆœ๊ฐ„์ด ์žˆ์–ด. ๐Ÿคฏ
"์–ด? ๊ฐ‘์ž๊ธฐ ์„œ๋น„์Šค๊ฐ€ ๋А๋ ค์กŒ๋Š”๋ฐ ์™œ ๊ทธ๋Ÿฐ ๊ฑฐ์ง€?"
"์—๋Ÿฌ๊ฐ€ ๋‚ฌ๋‹ค๋Š”๋ฐ ์–ด๋””์„œ ๋‚œ ๊ฑด์ง€ ๋ชจ๋ฅด๊ฒ ์–ด..."
"์–ด์ œ ๋ฐค์— ๋ฌด์Šจ ์ผ์ด ์žˆ์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์‹ถ์€๋ฐ ๋กœ๊ทธ๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์•„!"

์ด๋Ÿฐ ์ƒํ™ฉ๋“ค, ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ํ•œ ๋ฒˆ์ฏค์€ ๊ฒช์–ด๋ดค์„ ๊ฑฐ์•ผ. ์„œ๋ฒ„ ํ•˜๋‚˜๋งŒ ๊ด€๋ฆฌํ•  ๋•Œ๋Š” ๊ทธ๋ƒฅ SSH ์ ‘์†ํ•ด์„œ tail -f ๋ช…๋ น์–ด๋กœ ๋กœ๊ทธ ๋ณด๋ฉด ๋˜์ง€๋งŒ, ์„œ๋ฒ„๊ฐ€ 10๋Œ€, 20๋Œ€๋กœ ๋Š˜์–ด๋‚˜๋ฉด? ๐Ÿ˜ฑ ์ผ์ผ์ด ์ ‘์†ํ•ด์„œ ํ™•์ธํ•˜๋Š” ๊ฑด ์ •๋ง ๋น„ํšจ์œจ์ ์ด์ง€.

๋ฐ”๋กœ ์ด๋Ÿด ๋•Œ ํ•„์š”ํ•œ ๊ฒŒ ์ค‘์•™ ์ง‘์ค‘์‹ ๋กœ๊ทธ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์ด์•ผ! ๊ทธ๋ฆฌ๊ณ  ๊ทธ ์ค‘์—์„œ๋„ ๊ฐ€์žฅ ์œ ๋ช…ํ•˜๊ณ  ๊ฐ•๋ ฅํ•œ ๊ฒŒ ๋ฐ”๋กœ ELK Stack์ด์ง€. ๐Ÿ’ช

๐Ÿ“Œ ELK Stack์ด๋ž€?

Elasticsearch: ๋กœ๊ทธ๋ฅผ ์ €์žฅํ•˜๊ณ  ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ฒ€์ƒ‰ ์—”์ง„
Logstash: ๋กœ๊ทธ๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ  ๊ฐ€๊ณตํ•˜๋Š” ํŒŒ์ดํ”„๋ผ์ธ
Kibana: ๋กœ๊ทธ๋ฅผ ์‹œ๊ฐํ™”ํ•˜๊ณ  ๋ถ„์„ํ•˜๋Š” ๋Œ€์‹œ๋ณด๋“œ

์ด ์„ธ ๊ฐ€์ง€๊ฐ€ ํ•ฉ์ณ์ ธ์„œ ์™„๋ฒฝํ•œ ๋กœ๊ทธ ๊ด€๋ฆฌ ์ƒํƒœ๊ณ„๋ฅผ ๋งŒ๋“ค์–ด๋‚ด๋Š” ๊ฑฐ์•ผ! ๐ŸŽจ
ELK Stack ์•„ํ‚คํ…์ฒ˜ ์„œ๋ฒ„ A ๋กœ๊ทธ ์ƒ์„ฑ ์„œ๋ฒ„ B ๋กœ๊ทธ ์ƒ์„ฑ ์„œ๋ฒ„ C ๋กœ๊ทธ ์ƒ์„ฑ Logstash ์ˆ˜์ง‘ ๋ฐ ๊ฐ€๊ณต ํ•„ํ„ฐ๋ง ํŒŒ์‹ฑ Elasticsearch ์ €์žฅ ๋ฐ ๊ฒ€์ƒ‰ ์ธ๋ฑ์‹ฑ ๋ถ„์‚ฐ ์ €์žฅ Kibana ์‹œ๊ฐํ™” ๋ฐ ๋ถ„์„ ๋Œ€์‹œ๋ณด๋“œ

๐Ÿ—๏ธ ELK Stack์˜ ๊ฐ ๊ตฌ์„ฑ ์š”์†Œ ํŒŒํ—ค์น˜๊ธฐ

1๏ธโƒฃ Elasticsearch: ๊ฒ€์ƒ‰์˜ ๋งˆ๋ฒ•์‚ฌ

Elasticsearch๋Š” Apache Lucene ๊ธฐ๋ฐ˜์˜ ๋ถ„์‚ฐ ๊ฒ€์ƒ‰ ์—”์ง„์ด์•ผ. ๐Ÿ”Ž
์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด, ์—„์ฒญ๋‚˜๊ฒŒ ๋งŽ์€ ๋ฐ์ดํ„ฐ ์†์—์„œ๋„ ์›ํ•˜๋Š” ์ •๋ณด๋ฅผ ๋น›์˜ ์†๋„๋กœ ์ฐพ์•„์ฃผ๋Š” ์นœ๊ตฌ์ง€!

์ผ๋ฐ˜์ ์ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” LIKE '%error%' ๊ฐ™์€ ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ฆฌ๋ฉด ์ „์ฒด ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค ๋’ค์ ธ์•ผ ํ•ด์„œ ๋А๋ ค. ํ•˜์ง€๋งŒ Elasticsearch๋Š” ์—ญ์ƒ‰์ธ(Inverted Index)์ด๋ผ๋Š” ํŠน๋ณ„ํ•œ ๋ฐฉ์‹์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•ด์„œ, ๊ฒ€์ƒ‰์ด ์ •๋ง ๋นจ๋ผ! โšก

๐ŸŽ“ ์—ญ์ƒ‰์ธ์ด ๋ญ๋ƒ๊ณ ?

์ผ๋ฐ˜ ์ฑ…์˜ ๋ชฉ์ฐจ๋Š” "1์žฅ์— ์ด๋Ÿฐ ๋‚ด์šฉ, 2์žฅ์— ์ €๋Ÿฐ ๋‚ด์šฉ"์ด๋ผ๊ณ  ๋˜์–ด ์žˆ์ง€?
ํ•˜์ง€๋งŒ ์ฑ… ๋’ค์— ์žˆ๋Š” ์ƒ‰์ธ(Index)์€ "์—๋Ÿฌ๋ผ๋Š” ๋‹จ์–ด๋Š” 15ํŽ˜์ด์ง€, 47ํŽ˜์ด์ง€, 89ํŽ˜์ด์ง€์— ๋‚˜์˜จ๋‹ค"๊ณ  ๋˜์–ด ์žˆ์–ด.

Elasticsearch๋Š” ๋ฐ”๋กœ ์ด ์ƒ‰์ธ ๋ฐฉ์‹์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•ด! ๊ทธ๋ž˜์„œ ํŠน์ • ๋‹จ์–ด๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋ฉด ๋ฐ”๋กœ ํ•ด๋‹น ๋ฌธ์„œ๋“ค์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š” ๊ฑฐ์ง€. ๐Ÿ“š
Elasticsearch์˜ ํ•ต์‹ฌ ํŠน์ง•
  • โœ… ๋ถ„์‚ฐ ์ฒ˜๋ฆฌ: ๋ฐ์ดํ„ฐ๋ฅผ ์—ฌ๋Ÿฌ ๋…ธ๋“œ์— ๋‚˜๋ˆ ์„œ ์ €์žฅํ•˜๊ณ  ์ฒ˜๋ฆฌ
  • โœ… ์‹ค์‹œ๊ฐ„ ๊ฒ€์ƒ‰: ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์˜ค๋ฉด ๊ฑฐ์˜ ์ฆ‰์‹œ ๊ฒ€์ƒ‰ ๊ฐ€๋Šฅ
  • โœ… RESTful API: HTTP ๊ธฐ๋ฐ˜์œผ๋กœ ์‰ฝ๊ฒŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • โœ… ์Šคํ‚ค๋งˆ ํ”„๋ฆฌ: JSON ํ˜•์‹์œผ๋กœ ์ž์œ ๋กญ๊ฒŒ ๋ฐ์ดํ„ฐ ์ €์žฅ
  • โœ… ํ™•์žฅ์„ฑ: ๋…ธ๋“œ๋งŒ ์ถ”๊ฐ€ํ•˜๋ฉด ์„ฑ๋Šฅ ํ–ฅ์ƒ ๊ฐ€๋Šฅ

2๏ธโƒฃ Logstash: ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ์˜ ๋‹ฌ์ธ

Logstash๋Š” ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘๊ณผ ๊ฐ€๊ณต์„ ๋‹ด๋‹นํ•˜๋Š” ์นœ๊ตฌ์•ผ. ๐Ÿšฐ
๋งˆ์น˜ ์ •์ˆ˜๊ธฐ์ฒ˜๋Ÿผ, ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ๋“ค์–ด์˜ค๋Š” ์ง€์ €๋ถ„ํ•œ ๋กœ๊ทธ ๋ฐ์ดํ„ฐ๋ฅผ ๊นจ๋—ํ•˜๊ฒŒ ์ •์ œํ•ด์„œ Elasticsearch๋กœ ๋ณด๋‚ด์ฃผ์ง€.

Logstash์˜ ๋™์ž‘ ๋ฐฉ์‹์€ ํฌ๊ฒŒ ์„ธ ๋‹จ๊ณ„๋กœ ๋‚˜๋‰˜์–ด:

1
Input (์ž…๋ ฅ)
๋‹ค์–‘ํ•œ ์†Œ์Šค์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์™€. ํŒŒ์ผ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค, ๋ฉ”์‹œ์ง€ ํ, HTTP ๋“ฑ๋“ฑ... ์ •๋ง ๋งŽ์€ ์ž…๋ ฅ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์žˆ์–ด! ๐Ÿ“ฅ
2
Filter (ํ•„ํ„ฐ)
๋ฐ›์•„์˜จ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•ด. ํŒŒ์‹ฑํ•˜๊ณ , ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜๊ณ , ํ˜•์‹์„ ๋ณ€ํ™˜ํ•˜๊ณ ... ์ด๊ฒŒ Logstash์˜ ์ง„์งœ ํ•ต์‹ฌ์ด์•ผ! ๐Ÿ”ง
3
Output (์ถœ๋ ฅ)
๊ฐ€๊ณต๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ชฉ์ ์ง€๋กœ ๋ณด๋‚ด. ์ฃผ๋กœ 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๋กœ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋“ค:

๐ŸŽจ 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"
}
๐Ÿ’ก Tip: Elasticsearch ๋ฉ”๋ชจ๋ฆฌ ์„ค์ •

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
  }
}

ํ•˜๋‚˜์”ฉ ๋œฏ์–ด๋ณด์ž! ๐Ÿ”

Input ์„น์…˜

- path: ์ฝ์„ ํŒŒ์ผ ๊ฒฝ๋กœ (์™€์ผ๋“œ์นด๋“œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ)
- start_position: "beginning"์€ ํŒŒ์ผ ์ฒ˜์Œ๋ถ€ํ„ฐ, "end"๋Š” ๋๋ถ€ํ„ฐ
- sincedb_path: ์–ด๋””๊นŒ์ง€ ์ฝ์—ˆ๋Š”์ง€ ๊ธฐ๋กํ•˜๋Š” ํŒŒ์ผ (ํ…Œ์ŠคํŠธ์šฉ์œผ๋กœ /dev/null ์‚ฌ์šฉ)
Filter ์„น์…˜

- grok: ์ •๊ทœํ‘œํ˜„์‹์œผ๋กœ ๋กœ๊ทธ ํŒŒ์‹ฑ (COMBINEDAPACHELOG๋Š” ๋ฏธ๋ฆฌ ์ •์˜๋œ ํŒจํ„ด)
- date: ํƒ€์ž„์Šคํƒฌํ”„ ํ•„๋“œ๋ฅผ ํŒŒ์‹ฑํ•ด์„œ @timestamp๋กœ ์„ค์ •
- geoip: IP ์ฃผ์†Œ๋กœ ์ง€๋ฆฌ ์ •๋ณด ์ถ”๊ฐ€ (์–ด๋А ๋‚˜๋ผ์—์„œ ์ ‘์†ํ–ˆ๋Š”์ง€ ๋“ฑ)
Output ์„น์…˜

- 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 ๋””๋ฒ„๊ฑฐ ํ™œ์šฉํ•˜๊ธฐ

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์„ ๋งŒ๋“ค์–ด์•ผ ํ•ด. ์ด๊ฑด "์–ด๋–ค ์ธ๋ฑ์Šค์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณผ ๊ฑด์ง€" ์•Œ๋ ค์ฃผ๋Š” ๊ฑฐ์•ผ.

1
Kibana ์™ผ์ชฝ ๋ฉ”๋‰ด์—์„œ Management โ†’ Stack Management ํด๋ฆญ
2
Kibana ์„น์…˜์—์„œ Index Patterns ํด๋ฆญ
3
Create index pattern ๋ฒ„ํŠผ ํด๋ฆญ
4
Index pattern name์— nginx-logs-* ์ž…๋ ฅ (์™€์ผ๋“œ์นด๋“œ๋กœ ๋ชจ๋“  ๋‚ ์งœ ํฌํ•จ)
5
Time field๋กœ @timestamp ์„ ํƒ

์ด์ œ Discover ๋ฉ”๋‰ด์—์„œ ๋กœ๊ทธ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์–ด! ๐ŸŽ‰

2๋‹จ๊ณ„: Discover๋กœ ๋กœ๊ทธ ํƒ์ƒ‰ํ•˜๊ธฐ

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)

1
Visualize Library โ†’ Create visualization ํด๋ฆญ
2
Line ์ฐจํŠธ ์„ ํƒ
3
Index pattern ์„ ํƒ (nginx-logs-*)
4
Y์ถ•: Count (๊ธฐ๋ณธ๊ฐ’)
X์ถ•: Date Histogram, @timestamp ํ•„๋“œ, Interval์€ Auto

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์‹œ๊ฐ„๋Œ€๋ณ„๋กœ ๋กœ๊ทธ๊ฐ€ ์–ผ๋งˆ๋‚˜ ๋“ค์–ด์™”๋Š”์ง€ ๋ณด์—ฌ์ฃผ๋Š” ๊ทธ๋ž˜ํ”„๊ฐ€ ์™„์„ฑ๋ผ! ๐Ÿ“ˆ

์˜ˆ์ œ 2: ์ƒํƒœ ์ฝ”๋“œ๋ณ„ ๋ถ„ํฌ (Pie Chart)

1
Pie ์ฐจํŠธ ์„ ํƒ
2
Slice by: Terms
Field: response.keyword (์ƒํƒœ ์ฝ”๋“œ ํ•„๋“œ)
Size: 10 (์ƒ์œ„ 10๊ฐœ)

200, 404, 500 ๋“ฑ ์ƒํƒœ ์ฝ”๋“œ๋ณ„๋กœ ๋น„์œจ์„ ๋ณด์—ฌ์ฃผ๋Š” ํŒŒ์ด ์ฐจํŠธ๊ฐ€ ๋งŒ๋“ค์–ด์ ธ! ๐Ÿฅง

์˜ˆ์ œ 3: ์ง€์—ญ๋ณ„ ์ ‘์†์ž (Map)

geoip ํ•„ํ„ฐ๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด, ์ง€๋„์— ์ ‘์†์ž ์œ„์น˜๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์–ด!

1
Maps ์„ ํƒ
2
Add layer โ†’ Documents
3
Index pattern ์„ ํƒ
Geospatial field: geoip.location

์„ธ๊ณ„ ์ง€๋„์— ์ ‘์†์ž๋“ค์ด ์ ์œผ๋กœ ์ฐํ˜€์„œ ๋‚˜ํƒ€๋‚˜! ์ •๋ง ๋ฉ‹์ง€์ง€? ๐Ÿ—บ๏ธ

4๋‹จ๊ณ„: Dashboard ๊ตฌ์„ฑํ•˜๊ธฐ

์—ฌ๋Ÿฌ ๊ฐœ์˜ ์‹œ๊ฐํ™”๋ฅผ ๋งŒ๋“ค์—ˆ์œผ๋ฉด, ์ด์ œ ๋Œ€์‹œ๋ณด๋“œ๋กœ ๋ชจ์•„๋ณด์ž!

1
Dashboard โ†’ Create dashboard
2
Add from library๋กœ ๋งŒ๋“ค์–ด๋‘” ์‹œ๊ฐํ™”๋“ค ์ถ”๊ฐ€
3
๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ์œผ๋กœ ๋ฐฐ์น˜ ์กฐ์ •
4
Save๋กœ ์ €์žฅ

์ด์ œ ํ•œ ํ™”๋ฉด์—์„œ ๋ชจ๋“  ์ค‘์š”ํ•œ ์ง€ํ‘œ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์–ด! ๐ŸŽฏ
์‹œ๊ฐ„ ๋ฒ”์œ„๋ฅผ ๋ฐ”๊พธ๋ฉด ๋ชจ๋“  ์ฐจํŠธ๊ฐ€ ๋™์‹œ์— ์—…๋ฐ์ดํŠธ๋˜๊ณ , ํ•œ ์ฐจํŠธ๋ฅผ ํด๋ฆญํ•˜๋ฉด ๋‹ค๋ฅธ ์ฐจํŠธ๋“ค๋„ ํ•„ํ„ฐ๋ง๋ผ. ์ •๋ง ๊ฐ•๋ ฅํ•˜์ง€!

๐Ÿ’ก ๋Œ€์‹œ๋ณด๋“œ ๋””์ž์ธ ํŒ

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 ๊ธฐ๋Šฅ์œผ๋กœ ๋ฌธ์ œ ๋ฐœ์ƒ ์‹œ ์ž๋™์œผ๋กœ ์•Œ๋ฆผ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์–ด! ๐Ÿšจ

1
Stack Management โ†’ Rules and Connectors
2
Create rule ํด๋ฆญ
3
Rule type: Elasticsearch query ์„ ํƒ
4
์กฐ๊ฑด ์„ค์ •:
- Index: application-production-*
- Query: level: "ERROR"
- Threshold: Count > 10 (5๋ถ„ ๋™์•ˆ ์—๋Ÿฌ๊ฐ€ 10๊ฐœ ์ด์ƒ ๋ฐœ์ƒํ•˜๋ฉด)
5
Action: Slack, Email, Webhook ๋“ฑ์œผ๋กœ ์•Œ๋ฆผ ์ „์†ก

์ด์ œ ์—๋Ÿฌ๊ฐ€ ๊ธ‰์ฆํ•˜๋ฉด ์ž๋™์œผ๋กœ 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)

๋กœ๊ทธ๋Š” ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด ๋œ ์ค‘์š”ํ•ด์ง€์ง€? ์˜ค๋ž˜๋œ ๋กœ๊ทธ๋Š” ์‚ญ์ œํ•˜๊ฑฐ๋‚˜ ์••์ถ•ํ•ด์„œ ์ €์žฅ ๊ณต๊ฐ„์„ ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ์–ด.

๐Ÿ”„ 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 ๋ฉ”๋‰ด์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋“ค:

๐Ÿ” Elasticsearch
- ํด๋Ÿฌ์Šคํ„ฐ ์ƒํƒœ (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

์ƒ์„ฑ๋˜๋Š” ๊ธฐ๋ณธ ์‚ฌ์šฉ์ž๋“ค:

๐Ÿ‘ค elastic: ์Šˆํผ์œ ์ € (๋ชจ๋“  ๊ถŒํ•œ)
๐Ÿ‘ค 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
2. ๋””๋ฒ„๊ทธ ๋ชจ๋“œ๋กœ ์‹คํ–‰:
/usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/your-config.conf --log.level=debug
3. stdout์œผ๋กœ ์ถœ๋ ฅ ํ™•์ธ:
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.*
2. read-only ๋ชจ๋“œ ํ•ด์ œ:
PUT _all/_settings
{
  "index.blocks.read_only_allow_delete": null
}
3. ILM ์ •์ฑ… ์„ค์ •ํ•ด์„œ ์ž๋™ ์‚ญ์ œ
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
2. ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ๋ชจ๋‹ˆํ„ฐ๋ง:
GET _nodes/stats/jvm?human
3. ๋ถˆํ•„์š”ํ•œ ํ•„๋“œ ์ œ๊ฑฐ
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์„ ์„ค์น˜ํ•˜๊ณ  ์„ค์ •ํ•ด๋ณด์ž! ์‹ค์Šต์ด ์ตœ๊ณ ์˜ ํ•™์Šต ๋ฐฉ๋ฒ•์ด๋‹ˆ๊นŒ. ํ™”์ดํŒ…! ๐Ÿš€โœจ

ELK Stack ๋กœ๊ทธ ๊ด€๋ฆฌ์˜ ์ƒˆ๋กœ์šด ์‹œ์ž‘ E Elasticsearch L Logstash K Kibana
๐ŸŽ“ Happy Logging! ๐ŸŽ“

๋กœ๊ทธ์™€ ํ•จ๊ป˜ํ•˜๋Š” ์ฆ๊ฑฐ์šด ๊ฐœ๋ฐœ ๋˜์„ธ์š”! ๐Ÿ˜Š
๋Œ“๊ธ€ ์ž‘์„ฑ

์ด ๊ธ€์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ƒ๊ฐ์„ ๋“ค๋ ค์ฃผ์„ธ์š”

๋Œ“๊ธ€ 0
๋Œ“๊ธ€์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘์ž…๋‹ˆ๋‹ค.

์•„์ง ๋Œ“๊ธ€์ด ์—†์Šต๋‹ˆ๋‹ค.