์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐Ÿš€ ์„œ๋ฒ„ ์„ฑ๋Šฅ ๋ชจ๋‹ˆํ„ฐ๋ง์˜ ์™„๋ฒฝํ•œ ์กฐํ•ฉ! Prometheus์™€ Grafana ํ™œ์šฉ ๊ฐ€์ด๋“œ

๐Ÿš€ ์„œ๋ฒ„ ์„ฑ๋Šฅ ๋ชจ๋‹ˆํ„ฐ๋ง์˜ ์™„๋ฒฝํ•œ ์กฐํ•ฉ! Prometheus์™€ Grafana ํ™œ์šฉ ๊ฐ€์ด๋“œ

์‹ค์‹œ๊ฐ„์œผ๋กœ ์„œ๋ฒ„๋ฅผ ์ง€์ผœ์ฃผ๋Š” ๋“ ๋“ ํ•œ ํŒŒ์ˆ˜๊พผ ๋งŒ๋“ค๊ธฐ ๐Ÿ’ช

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

P Prometheus G Grafana ๐Ÿ“Š ์™„๋ฒฝํ•œ ๋ชจ๋‹ˆํ„ฐ๋ง ์‹œ์Šคํ…œ

๐ŸŽฏ ์™œ ๋ชจ๋‹ˆํ„ฐ๋ง์ด ํ•„์š”ํ• ๊นŒ?

์„œ๋ฒ„๋ฅผ ์šด์˜ํ•œ๋‹ค๋Š” ๊ฑด ๋งˆ์น˜ ๋น„ํ–‰๊ธฐ๋ฅผ ์กฐ์ข…ํ•˜๋Š” ๊ฒƒ๊ณผ ๋น„์Šทํ•ด. ๊ณ„๊ธฐํŒ ์—†์ด ๋น„ํ–‰๊ธฐ๋ฅผ ์กฐ์ข…ํ•œ๋‹ค๊ณ  ์ƒ์ƒํ•ด๋ด. ๊ณ ๋„๋„ ๋ชจ๋ฅด๊ณ , ์†๋„๋„ ๋ชจ๋ฅด๊ณ , ์—ฐ๋ฃŒ๊ฐ€ ์–ผ๋งˆ๋‚˜ ๋‚จ์•˜๋Š”์ง€๋„ ๋ชจ๋ฅด๋Š” ์ƒํƒœ๋กœ ๋‚ ์•„๊ฐ„๋‹ค๋ฉด? ์ƒ๊ฐ๋งŒ ํ•ด๋„ ์•„์ฐ”ํ•˜์ง€? ๐Ÿ˜ฑ

์„œ๋ฒ„๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์•ผ. CPU ์‚ฌ์šฉ๋ฅ , ๋ฉ”๋ชจ๋ฆฌ ์ƒํƒœ, ๋””์Šคํฌ ์šฉ๋Ÿ‰, ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ... ์ด๋Ÿฐ ์ •๋ณด๋“ค์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜์ง€ ์•Š์œผ๋ฉด ์–ธ์ œ ๋ฌธ์ œ๊ฐ€ ํ„ฐ์งˆ์ง€ ์•Œ ์ˆ˜ ์—†์–ด. ๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ์—๊ฒŒ๋Š” Prometheus์™€ Grafana๋ผ๋Š” ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ•œ ๊ฑฐ์ง€!

๐Ÿ’ก ๋ชจ๋‹ˆํ„ฐ๋ง์˜ ํ•ต์‹ฌ ๊ฐ€์น˜

1. ๋ฌธ์ œ ์˜ˆ๋ฐฉ: ์žฅ์• ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์ „์— ๋ฏธ๋ฆฌ ๊ฐ์ง€
2. ๋น ๋ฅธ ๋Œ€์‘: ๋ฌธ์ œ ๋ฐœ์ƒ ์‹œ ์ฆ‰๊ฐ์ ์ธ ์›์ธ ํŒŒ์•…
3. ์„ฑ๋Šฅ ์ตœ์ ํ™”: ๋ณ‘๋ชฉ ์ง€์ ์„ ์ฐพ์•„ ๊ฐœ์„ 
4. ์šฉ๋Ÿ‰ ๊ณ„ํš: ๋ฆฌ์†Œ์Šค ์ฆ์„ค ์‹œ์ ์„ ์ •ํ™•ํžˆ ์˜ˆ์ธก
5. ๋น„์šฉ ์ ˆ๊ฐ: ๋ถˆํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค ๋‚ญ๋น„ ๋ฐฉ์ง€

๐Ÿ” Prometheus๋ž€ ๋ฌด์—‡์ธ๊ฐ€?

Prometheus(ํ”„๋กœ๋ฉ”ํ…Œ์šฐ์Šค)๋Š” 2012๋…„ SoundCloud์—์„œ ๊ฐœ๋ฐœํ•œ ์˜คํ”ˆ์†Œ์Šค ๋ชจ๋‹ˆํ„ฐ๋ง ์‹œ์Šคํ…œ์ด์•ผ. ๊ทธ๋ฆฌ์Šค ์‹ ํ™”์— ๋‚˜์˜ค๋Š” ํ”„๋กœ๋ฉ”ํ…Œ์šฐ์Šค์ฒ˜๋Ÿผ ์ธ๋ฅ˜(๊ฐœ๋ฐœ์ž๋“ค)์—๊ฒŒ ๋ถˆ(๋ชจ๋‹ˆํ„ฐ๋ง ๋Šฅ๋ ฅ)์„ ๊ฐ€์ ธ๋‹ค์ค€ ์กด์žฌ๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์ง€! ๐Ÿ”ฅ

Prometheus์˜ ๊ฐ€์žฅ ํฐ ํŠน์ง•์€ ์‹œ๊ณ„์—ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(Time Series Database)๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ๋‹ค๋Š” ๊ฑฐ์•ผ. ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด, ์‹œ๊ฐ„์˜ ํ๋ฆ„์— ๋”ฐ๋ผ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ๋ถ„์„ํ•˜๋Š” ๋ฐ ํŠนํ™”๋˜์–ด ์žˆ๋‹ค๋Š” ๋œป์ด์ง€. CPU ์‚ฌ์šฉ๋ฅ ์ด ์˜ค์ „ 10์‹œ์— 50%์˜€๋‹ค๊ฐ€ ์˜คํ›„ 2์‹œ์— 80%๋กœ ์˜ฌ๋ผ๊ฐ”๋‹ค๋Š” ์‹์˜ ์ •๋ณด๋ฅผ ์•„์ฃผ ํšจ์œจ์ ์œผ๋กœ ์ €์žฅํ•˜๊ณ  ์กฐํšŒํ•  ์ˆ˜ ์žˆ์–ด.

๐ŸŽจ Prometheus์˜ ํ•ต์‹ฌ ํŠน์ง•

๐Ÿ“ฅ Pull ๋ฐฉ์‹ ์ˆ˜์ง‘
Prometheus๊ฐ€ ์ง์ ‘ ํƒ€๊ฒŸ ์„œ๋ฒ„์— ์ ‘์†ํ•ด์„œ ๋ฉ”ํŠธ๋ฆญ์„ ๊ฐ€์ ธ์™€. ์ด๊ฒŒ Push ๋ฐฉ์‹๋ณด๋‹ค ์•ˆ์ •์ ์ด๊ณ  ๊ด€๋ฆฌํ•˜๊ธฐ ์‰ฌ์›Œ!
๐Ÿท๏ธ ๋‹ค์ฐจ์› ๋ฐ์ดํ„ฐ ๋ชจ๋ธ
๋ ˆ์ด๋ธ”(Label)์„ ์‚ฌ์šฉํ•ด์„œ ๊ฐ™์€ ๋ฉ”ํŠธ๋ฆญ๋„ ๋‹ค์–‘ํ•œ ๊ด€์ ์—์„œ ๋ถ„๋ฅ˜ํ•  ์ˆ˜ ์žˆ์–ด. ์˜ˆ๋ฅผ ๋“ค์–ด HTTP ์š”์ฒญ์„ URL๋ณ„, ์ƒํƒœ์ฝ”๋“œ๋ณ„๋กœ ๊ตฌ๋ถ„ ๊ฐ€๋Šฅ!
๐Ÿ”Ž ๊ฐ•๋ ฅํ•œ ์ฟผ๋ฆฌ ์–ธ์–ด
PromQL์ด๋ผ๋Š” ์ž์ฒด ์ฟผ๋ฆฌ ์–ธ์–ด๋กœ ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ๋ถ„์„๋„ ๊ฐ„๋‹จํ•˜๊ฒŒ! SQL์ฒ˜๋Ÿผ ๋ฐฐ์šฐ๋ฉด ์ •๋ง ๊ฐ•๋ ฅํ•œ ๋ฌด๊ธฐ๊ฐ€ ๋ผ.

๐Ÿ—๏ธ Prometheus ์•„ํ‚คํ…์ฒ˜ ์ดํ•ดํ•˜๊ธฐ

Prometheus์˜ ๊ตฌ์กฐ๋ฅผ ์ดํ•ดํ•˜๋ฉด ํ™œ์šฉ๋„๊ฐ€ ํ›จ์”ฌ ๋†’์•„์ ธ. ์ฃผ์š” ๊ตฌ์„ฑ ์š”์†Œ๋“ค์„ ์‚ดํŽด๋ณผ๊นŒ?

๊ตฌ์„ฑ ์š”์†Œ ์—ญํ•  ์„ค๋ช…
Prometheus Server ํ•ต์‹ฌ ์—”์ง„ ๋ฉ”ํŠธ๋ฆญ ์ˆ˜์ง‘, ์ €์žฅ, ์ฟผ๋ฆฌ ์ฒ˜๋ฆฌ๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ๋ฉ”์ธ ์„œ๋ฒ„
Exporter ๋ฐ์ดํ„ฐ ์ œ๊ณต์ž ๋‹ค์–‘ํ•œ ์‹œ์Šคํ…œ์˜ ๋ฉ”ํŠธ๋ฆญ์„ Prometheus ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜
Pushgateway ์ž„์‹œ ์ž‘์—… ์ง€์› ์งง์€ ์‹œ๊ฐ„ ๋™์•ˆ ์‹คํ–‰๋˜๋Š” ๋ฐฐ์น˜ ์ž‘์—…์˜ ๋ฉ”ํŠธ๋ฆญ ์ˆ˜์ง‘
Alertmanager ์•Œ๋ฆผ ๊ด€๋ฆฌ ์ž„๊ณ„๊ฐ’ ์ดˆ๊ณผ ์‹œ ์ด๋ฉ”์ผ, ์Šฌ๋ž™ ๋“ฑ์œผ๋กœ ์•Œ๋ฆผ ๋ฐœ์†ก
Service Discovery ์ž๋™ ํƒ์ง€ Kubernetes, Consul ๋“ฑ๊ณผ ์—ฐ๋™ํ•˜์—ฌ ๋ชจ๋‹ˆํ„ฐ๋ง ๋Œ€์ƒ ์ž๋™ ๋ฐœ๊ฒฌ
๐Ÿ’š ์ดˆ๋ณด์ž ํŒ: ์ฒ˜์Œ์—๋Š” Prometheus Server์™€ Node Exporter๋งŒ์œผ๋กœ ์‹œ์ž‘ํ•ด๋„ ์ถฉ๋ถ„ํ•ด! ์‹œ์Šคํ…œ์ด ๋ณต์žกํ•ด์ง€๋ฉด ์ ์ง„์ ์œผ๋กœ ๋‹ค๋ฅธ ๊ตฌ์„ฑ ์š”์†Œ๋“ค์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ผ. ํ•œ ๋ฒˆ์— ๋‹ค ์ดํ•ดํ•˜๋ ค๊ณ  ํ•˜์ง€ ๋ง๊ณ  ์ฒœ์ฒœํžˆ ์ตํ˜€๊ฐ€์ž! ๐Ÿ˜Š

๐Ÿ“Š Grafana, ๋ฐ์ดํ„ฐ๋ฅผ ์˜ˆ์ˆ ๋กœ ๋งŒ๋“ค๋‹ค

Prometheus๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ  ์ €์žฅํ•˜๋Š” ์—ญํ• ์ด๋ผ๋ฉด, Grafana๋Š” ๊ทธ ๋ฐ์ดํ„ฐ๋ฅผ ์•„๋ฆ„๋‹ต๊ณ  ์ง๊ด€์ ์ธ ์‹œ๊ฐํ™”๋กœ ๋ณด์—ฌ์ฃผ๋Š” ์—ญํ• ์„ ํ•ด. ๋งˆ์น˜ ํ›Œ๋ฅญํ•œ ์š”๋ฆฌ์‚ฌ๊ฐ€ ์‹ ์„ ํ•œ ์žฌ๋ฃŒ(Prometheus ๋ฐ์ดํ„ฐ)๋ฅผ ๋ฉ‹์ง„ ์š”๋ฆฌ(๋Œ€์‹œ๋ณด๋“œ)๋กœ ๋งŒ๋“ค์–ด๋‚ด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์•ผ! ๐Ÿ‘จโ€๐Ÿณ

Grafana๋Š” 2014๋…„์— ์‹œ์ž‘๋œ ์˜คํ”ˆ์†Œ์Šค ํ”„๋กœ์ ํŠธ๋กœ, ํ˜„์žฌ๋Š” ์ „ ์„ธ๊ณ„ ์ˆ˜๋งŽ์€ ๊ธฐ์—…๊ณผ ๊ฐœ๋ฐœ์ž๋“ค์ด ์‚ฌ์šฉํ•˜๋Š” ํ‘œ์ค€ ์‹œ๊ฐํ™” ๋„๊ตฌ๊ฐ€ ๋˜์—ˆ์–ด. Netflix, Uber, Bloomberg ๊ฐ™์€ ๊ธ€๋กœ๋ฒŒ ๊ธฐ์—…๋“ค๋„ Grafana๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋‹ˆ, ๊ทธ ์‹ ๋ขฐ๋„๋ฅผ ์•Œ ์ˆ˜ ์žˆ์ง€?

โœจ Grafana์˜ ๋งค๋ ฅ ํฌ์ธํŠธ

1. ๐ŸŽจ ๋‹ค์–‘ํ•œ ์‹œ๊ฐํ™” ์˜ต์…˜

๊ทธ๋ž˜ํ”„, ๊ฒŒ์ด์ง€, ํžˆํŠธ๋งต, ํ…Œ์ด๋ธ”... ์ƒ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๊ฑฐ์˜ ๋ชจ๋“  ํ˜•ํƒœ์˜ ์ฐจํŠธ๋ฅผ ์ง€์›ํ•ด. ๋ฐ์ดํ„ฐ์˜ ํŠน์„ฑ์— ๋งž๋Š” ์ตœ์ ์˜ ์‹œ๊ฐํ™”๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ์–ด์„œ ์ •๋ง ํŽธ๋ฆฌํ•ด!

2. ๐Ÿ”Œ ๋‹ค์ค‘ ๋ฐ์ดํ„ฐ ์†Œ์Šค ์ง€์›

Prometheus๋ฟ๋งŒ ์•„๋‹ˆ๋ผ InfluxDB, Elasticsearch, MySQL, PostgreSQL ๋“ฑ 70๊ฐœ ์ด์ƒ์˜ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ์ง€์›ํ•ด. ํ•˜๋‚˜์˜ ๋Œ€์‹œ๋ณด๋“œ์—์„œ ์—ฌ๋Ÿฌ ์†Œ์Šค์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ†ตํ•ฉํ•ด์„œ ๋ณผ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒŒ ์ •๋ง ํฐ ์žฅ์ ์ด์ง€!

3. ๐Ÿšจ ์•Œ๋ฆผ ๊ธฐ๋Šฅ

ํŠน์ • ์กฐ๊ฑด์ด ๋งŒ์กฑ๋˜๋ฉด ์ž๋™์œผ๋กœ ์•Œ๋ฆผ์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์–ด. ์˜ˆ๋ฅผ ๋“ค์–ด CPU ์‚ฌ์šฉ๋ฅ ์ด 90%๋ฅผ ๋„˜์œผ๋ฉด ์Šฌ๋ž™์œผ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๋Š” ์‹์œผ๋กœ ์„ค์ • ๊ฐ€๋Šฅํ•ด!

4. ๐Ÿ“ฑ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ

๋ชจ๋ฐ”์ผ์—์„œ๋„ ๊น”๋”ํ•˜๊ฒŒ ๋ณด์—ฌ์„œ ์–ธ์ œ ์–ด๋””์„œ๋‚˜ ์„œ๋ฒ„ ์ƒํƒœ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด. ์ถœ๊ทผ๊ธธ ์ง€ํ•˜์ฒ ์—์„œ๋„ ์„œ๋ฒ„ ๋ชจ๋‹ˆํ„ฐ๋ง์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋‹ˆ, ํŽธ๋ฆฌํ•˜์ง€ ์•Š์•„? (๋ฌผ๋ก  ๋„ˆ๋ฌด ์ž์ฃผ ๋ณด๋ฉด ์ŠคํŠธ๋ ˆ์Šค๋ฐ›์„ ์ˆ˜๋„... ๐Ÿ˜…)

โš ๏ธ ์ฃผ์˜์‚ฌํ•ญ: Grafana๋Š” ์‹œ๊ฐํ™” ๋„๊ตฌ์ผ ๋ฟ, ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ์ˆ˜์ง‘ํ•˜๊ฑฐ๋‚˜ ์ €์žฅํ•˜์ง€๋Š” ์•Š์•„. ๋ฐ˜๋“œ์‹œ Prometheus ๊ฐ™์€ ๋ฐ์ดํ„ฐ ์†Œ์Šค์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ด์•ผ ํ•ด. ์ด ๋‘˜์€ ์ฐฐ๋–ก๊ถํ•ฉ์ด์ง€๋งŒ, ๊ฐ์ž์˜ ์—ญํ• ์ด ๋ช…ํ™•ํžˆ ๊ตฌ๋ถ„๋˜์–ด ์žˆ๋‹ค๋Š” ๊ฑธ ๊ธฐ์–ตํ•˜์ž!

๐Ÿ› ๏ธ Prometheus ์„ค์น˜ํ•˜๊ณ  ์„ค์ •ํ•˜๊ธฐ

์ž, ์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์‹ค์ „์— ๋“ค์–ด๊ฐ€๋ณผ๊นŒ? Prometheus๋ฅผ ์„ค์น˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€๊ฐ€ ์žˆ์ง€๋งŒ, ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•๋“ค์„ ์†Œ๊ฐœํ• ๊ฒŒ. ๊ฑฑ์ •ํ•˜์ง€ ๋งˆ! ์ƒ๊ฐ๋ณด๋‹ค ์–ด๋ ต์ง€ ์•Š์•„. ๐Ÿ˜Š

๐Ÿ“ฆ ์„ค์น˜ ๋ฐฉ๋ฒ• 1: ๋ฐ”์ด๋„ˆ๋ฆฌ ์ง์ ‘ ๋‹ค์šด๋กœ๋“œ

๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ด์•ผ. Prometheus ๊ณต์‹ ์›น์‚ฌ์ดํŠธ์—์„œ ์šด์˜์ฒด์ œ์— ๋งž๋Š” ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๋ฉด ๋ผ.

# Linux ํ™˜๊ฒฝ์—์„œ ๋‹ค์šด๋กœ๋“œ ๋ฐ ์„ค์น˜
wget https://github.com/prometheus/prometheus/releases/download/v2.45.0/prometheus-2.45.0.linux-amd64.tar.gz
tar xvfz prometheus-2.45.0.linux-amd64.tar.gz
cd prometheus-2.45.0.linux-amd64

# Prometheus ์‹คํ–‰
./prometheus --config.file=prometheus.yml

๐Ÿณ ์„ค์น˜ ๋ฐฉ๋ฒ• 2: Docker ์‚ฌ์šฉ

Docker๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ™˜๊ฒฝ ์„ค์ • ๊ฑฑ์ • ์—†์ด ๊น”๋”ํ•˜๊ฒŒ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์–ด. ์š”์ฆ˜ ๋Œ€์„ธ์ง€!

# Docker๋กœ Prometheus ์‹คํ–‰
docker run -d \
  --name prometheus \
  -p 9090:9090 \
  -v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml \
  prom/prometheus

# ์‹คํ–‰ ํ™•์ธ
docker ps | grep prometheus

โš™๏ธ ๊ธฐ๋ณธ ์„ค์ • ํŒŒ์ผ ์ดํ•ดํ•˜๊ธฐ

Prometheus์˜ ํ•ต์‹ฌ์€ prometheus.yml ์„ค์ • ํŒŒ์ผ์ด์•ผ. ์ด ํŒŒ์ผ์—์„œ ๋ชจ๋‹ˆํ„ฐ๋งํ•  ๋Œ€์ƒ๊ณผ ์ˆ˜์ง‘ ์ฃผ๊ธฐ ๋“ฑ์„ ์ •์˜ํ•ด. ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ฅผ ์‚ดํŽด๋ณด์ž:

# prometheus.yml ๊ธฐ๋ณธ ๊ตฌ์กฐ
global:
  scrape_interval: 15s      # ๋ฉ”ํŠธ๋ฆญ ์ˆ˜์ง‘ ์ฃผ๊ธฐ (๊ธฐ๋ณธ 15์ดˆ)
  evaluation_interval: 15s   # ๊ทœ์น™ ํ‰๊ฐ€ ์ฃผ๊ธฐ
  
  external_labels:
    cluster: 'my-cluster'
    region: 'ap-northeast-2'

# ์•Œ๋ฆผ ๊ทœ์น™ ํŒŒ์ผ ๊ฒฝ๋กœ
rule_files:
  - "alerts.yml"

# ๋ชจ๋‹ˆํ„ฐ๋ง ๋Œ€์ƒ ์„ค์ •
scrape_configs:
  # Prometheus ์ž์ฒด ๋ชจ๋‹ˆํ„ฐ๋ง
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']
  
  # Node Exporter (์„œ๋ฒ„ ๋ฉ”ํŠธ๋ฆญ)
  - job_name: 'node'
    static_configs:
      - targets: ['localhost:9100']
        labels:
          env: 'production'
          team: 'backend'
๐Ÿ”‘ ์„ค์ • ํŒŒ์ผ ํ•ต์‹ฌ ํฌ์ธํŠธ

โ€ข scrape_interval: ๋„ˆ๋ฌด ์งง์œผ๋ฉด ๋ถ€ํ•˜๊ฐ€ ํฌ๊ณ , ๋„ˆ๋ฌด ๊ธธ๋ฉด ์‹ค์‹œ๊ฐ„์„ฑ์ด ๋–จ์–ด์ ธ. ๋ณดํ†ต 15~60์ดˆ๊ฐ€ ์ ๋‹นํ•ด.
โ€ข job_name: ๋…ผ๋ฆฌ์ ์ธ ๊ทธ๋ฃน ์ด๋ฆ„. ๋‚˜์ค‘์— ์ฟผ๋ฆฌํ•  ๋•Œ ์ด ์ด๋ฆ„์œผ๋กœ ํ•„ํ„ฐ๋งํ•  ์ˆ˜ ์žˆ์–ด.
โ€ข targets: ์‹ค์ œ ๋ชจ๋‹ˆํ„ฐ๋งํ•  ์—”๋“œํฌ์ธํŠธ. IP:Port ํ˜•์‹์œผ๋กœ ์ง€์ •.
โ€ข labels: ๋ฉ”ํŠธ๋ฆญ์— ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ๋ถ™์—ฌ. ํ™˜๊ฒฝ(dev/prod), ํŒ€, ๋ฆฌ์ „ ๋“ฑ์„ ๊ตฌ๋ถ„ํ•  ๋•Œ ์œ ์šฉํ•ด!

๐ŸŽฏ Node Exporter ์„ค์น˜ํ•˜๊ธฐ

์„œ๋ฒ„์˜ CPU, ๋ฉ”๋ชจ๋ฆฌ, ๋””์Šคํฌ ๋“ฑ ์‹œ์Šคํ…œ ๋ฉ”ํŠธ๋ฆญ์„ ์ˆ˜์ง‘ํ•˜๋ ค๋ฉด Node Exporter๊ฐ€ ํ•„์š”ํ•ด. ์ด๊ฑด Prometheus๊ฐ€ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ํ˜•์‹์œผ๋กœ ์‹œ์Šคํ…œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” ์—์ด์ „ํŠธ์•ผ.

# Node Exporter ๋‹ค์šด๋กœ๋“œ ๋ฐ ์„ค์น˜
wget https://github.com/prometheus/node_exporter/releases/download/v1.6.0/node_exporter-1.6.0.linux-amd64.tar.gz
tar xvfz node_exporter-1.6.0.linux-amd64.tar.gz
cd node_exporter-1.6.0.linux-amd64

# ๋ฐฑ๊ทธ๋ผ์šด๋“œ๋กœ ์‹คํ–‰
nohup ./node_exporter &

# ๋ฉ”ํŠธ๋ฆญ ํ™•์ธ (๋ธŒ๋ผ์šฐ์ €๋‚˜ curl๋กœ)
curl http://localhost:9100/metrics

Node Exporter๋ฅผ ์‹คํ–‰ํ•˜๋ฉด 9100 ํฌํŠธ์—์„œ ๋ฉ”ํŠธ๋ฆญ์„ ์ œ๊ณตํ•ด. ๋ธŒ๋ผ์šฐ์ €๋กœ ์ ‘์†ํ•ด๋ณด๋ฉด ์—„์ฒญ๋‚˜๊ฒŒ ๋งŽ์€ ๋ฉ”ํŠธ๋ฆญ๋“ค์ด ํ…์ŠคํŠธ ํ˜•์‹์œผ๋กœ ์ญ‰ ๋‚˜์—ด๋˜๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์–ด. ์ฒ˜์Œ ๋ณด๋ฉด ์ข€ ๋‹นํ™ฉ์Šค๋Ÿฌ์šธ ์ˆ˜ ์žˆ๋Š”๋ฐ, ๊ฑฑ์ • ๋งˆ! Prometheus๊ฐ€ ์•Œ์•„์„œ ์ž˜ ํŒŒ์‹ฑํ•ด์ค„ ๊ฑฐ์•ผ. ๐Ÿ˜„

๐Ÿ’ก ํ”„๋กœ ํŒ: ์—ฌ๋Ÿฌ ์„œ๋ฒ„๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋งํ•œ๋‹ค๋ฉด ๊ฐ ์„œ๋ฒ„๋งˆ๋‹ค Node Exporter๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ด. ๊ทธ๋ฆฌ๊ณ  Prometheus ์„ค์ • ํŒŒ์ผ์˜ targets์— ๋ชจ๋“  ์„œ๋ฒ„ ์ฃผ์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ผ. ์„œ๋ฒ„๊ฐ€ ๋งŽ๋‹ค๋ฉด ํŒŒ์ผ ๊ธฐ๋ฐ˜ ์„œ๋น„์Šค ๋””์Šค์ปค๋ฒ„๋ฆฌ๋‚˜ Kubernetes ์—ฐ๋™์„ ๊ณ ๋ คํ•ด๋ณด์ž!

๐ŸŽจ Grafana ์„ค์น˜์™€ Prometheus ์—ฐ๋™ํ•˜๊ธฐ

์ด์ œ Prometheus๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ  ์žˆ์œผ๋‹ˆ, Grafana๋กœ ๋ฉ‹์ง„ ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ๋งŒ๋“ค์–ด๋ณผ ์ฐจ๋ก€์•ผ! Grafana ์„ค์น˜๋„ ์—ฌ๋Ÿฌ ๋ฐฉ๋ฒ•์ด ์žˆ์ง€๋งŒ, ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๋“ค์„ ์•Œ์•„๋ณด์ž.

๐Ÿ“ฅ Grafana ์„ค์น˜ํ•˜๊ธฐ

๋ฐฉ๋ฒ• 1: APT ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ € ์‚ฌ์šฉ (Ubuntu/Debian)

# Grafana GPG ํ‚ค ์ถ”๊ฐ€
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -

# Grafana ์ €์žฅ์†Œ ์ถ”๊ฐ€
echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee /etc/apt/sources.list.d/grafana.list

# ์„ค์น˜
sudo apt-get update
sudo apt-get install grafana

# ์„œ๋น„์Šค ์‹œ์ž‘ ๋ฐ ์ž๋™ ์‹œ์ž‘ ์„ค์ •
sudo systemctl start grafana-server
sudo systemctl enable grafana-server

# ์ƒํƒœ ํ™•์ธ
sudo systemctl status grafana-server

๋ฐฉ๋ฒ• 2: Docker ์‚ฌ์šฉ

# Docker๋กœ Grafana ์‹คํ–‰
docker run -d \
  --name=grafana \
  -p 3000:3000 \
  -v grafana-storage:/var/lib/grafana \
  grafana/grafana-oss

# ์‹คํ–‰ ํ™•์ธ
docker logs grafana

์„ค์น˜๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ๋ธŒ๋ผ์šฐ์ €์—์„œ http://localhost:3000์œผ๋กœ ์ ‘์†ํ•ด๋ด. Grafana ๋กœ๊ทธ์ธ ํ™”๋ฉด์ด ๋‚˜ํƒ€๋‚  ๊ฑฐ์•ผ! ๐ŸŽ‰

๐Ÿ” ๊ธฐ๋ณธ ๋กœ๊ทธ์ธ ์ •๋ณด

Username: admin
Password: admin

์ฒซ ๋กœ๊ทธ์ธ ํ›„์—๋Š” ๋ฐ˜๋“œ์‹œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ผ๊ณ  ๋‚˜์˜ฌ ๊ฑฐ์•ผ. ๋ณด์•ˆ์„ ์œ„ํ•ด ๊ผญ ๋ณ€๊ฒฝํ•˜์ž!

๐Ÿ”— Prometheus ๋ฐ์ดํ„ฐ ์†Œ์Šค ์—ฐ๊ฒฐํ•˜๊ธฐ

Grafana์— ๋กœ๊ทธ์ธํ–ˆ๋‹ค๋ฉด, ์ด์ œ Prometheus๋ฅผ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋กœ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ด. ๋‹จ๊ณ„๋ณ„๋กœ ๋”ฐ๋ผํ•ด๋ณด์ž:

Step 1: ์™ผ์ชฝ ๋ฉ”๋‰ด์—์„œ โš™๏ธ Configuration โ†’ Data Sources ํด๋ฆญ

Step 2: "Add data source" ๋ฒ„ํŠผ ํด๋ฆญ

Step 3: Prometheus ์„ ํƒ

Step 4: ๋‹ค์Œ ์ •๋ณด ์ž…๋ ฅ:

Name: Prometheus
URL: http://localhost:9090
Access: Server (default)

# ๊ณ ๊ธ‰ ์„ค์ • (์„ ํƒ์‚ฌํ•ญ)
Scrape interval: 15s
Query timeout: 60s

Step 5: ํ•˜๋‹จ์˜ "Save & Test" ๋ฒ„ํŠผ ํด๋ฆญ

"Data source is working" ๋ฉ”์‹œ์ง€๊ฐ€ ๋‚˜์˜ค๋ฉด ์„ฑ๊ณต! ๐ŸŽŠ ์ด์ œ Grafana์—์„œ Prometheus์˜ ๋ชจ๋“  ๋ฉ”ํŠธ๋ฆญ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด.

โš ๏ธ ์—ฐ๊ฒฐ ์‹คํŒจ ์‹œ ์ฒดํฌ๋ฆฌ์ŠคํŠธ:

1. Prometheus๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰ ์ค‘์ธ์ง€ ํ™•์ธ (http://localhost:9090 ์ ‘์† ํ…Œ์ŠคํŠธ)
2. ๋ฐฉํ™”๋ฒฝ์—์„œ 9090 ํฌํŠธ๊ฐ€ ์—ด๋ ค์žˆ๋Š”์ง€ ํ™•์ธ
3. Docker๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๋„คํŠธ์›Œํฌ ์„ค์ • ํ™•์ธ (๊ฐ™์€ ๋„คํŠธ์›Œํฌ์— ์žˆ์–ด์•ผ ํ•จ)
4. URL์— http:// ํ”„๋กœํ† ์ฝœ์„ ์ •ํ™•ํžˆ ์ž…๋ ฅํ–ˆ๋Š”์ง€ ํ™•์ธ

๐Ÿ“Š ์ฒซ ๋ฒˆ์งธ ๋Œ€์‹œ๋ณด๋“œ ๋งŒ๋“ค๊ธฐ

์ž, ์ด์ œ ์ง„์งœ ์žฌ๋ฏธ์žˆ๋Š” ๋ถ€๋ถ„์ด์•ผ! ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž. ์ฒ˜์Œ๋ถ€ํ„ฐ ๋ณต์žกํ•œ ๊ฑธ ๋งŒ๋“ค ํ•„์š”๋Š” ์—†์–ด. ๊ฐ„๋‹จํ•œ CPU ์‚ฌ์šฉ๋ฅ  ๊ทธ๋ž˜ํ”„๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด๋ณด์ž.

1. ์ƒˆ ๋Œ€์‹œ๋ณด๋“œ ์ƒ์„ฑ

์™ผ์ชฝ ๋ฉ”๋‰ด์—์„œ + ์•„์ด์ฝ˜ โ†’ Dashboard โ†’ Add new panel ํด๋ฆญ

2. ์ฟผ๋ฆฌ ์ž‘์„ฑ

Query ํƒญ์—์„œ ๋‹ค์Œ PromQL ์ฟผ๋ฆฌ ์ž…๋ ฅ:

# CPU ์‚ฌ์šฉ๋ฅ  (%)
100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

3. ์‹œ๊ฐํ™” ์„ค์ •

์˜ค๋ฅธ์ชฝ ํŒจ๋„์—์„œ ๋‹ค์Œ ์„ค์ •:

Panel title: CPU Usage
Unit: Percent (0-100)
Min: 0
Max: 100
Visualization: Time series
Line width: 2
Fill opacity: 10
Gradient mode: Opacity

4. ์ €์žฅ

์˜ค๋ฅธ์ชฝ ์ƒ๋‹จ์˜ Apply ๋ฒ„ํŠผ ํด๋ฆญ ํ›„, ๐Ÿ’พ Save dashboard ํด๋ฆญ

์งœ์ž”! ๐ŸŽ‰ ์ฒซ ๋ฒˆ์งธ ๊ทธ๋ž˜ํ”„๊ฐ€ ์™„์„ฑ๋์–ด! ์‹ค์‹œ๊ฐ„์œผ๋กœ CPU ์‚ฌ์šฉ๋ฅ ์ด ๋ณ€ํ•˜๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์„ ๊ฑฐ์•ผ. ์‹ ๊ธฐํ•˜์ง€?

๐Ÿ”ฅ PromQL ๋งˆ์Šคํ„ฐํ•˜๊ธฐ

PromQL(Prometheus Query Language)์€ Prometheus์˜ ํ•ต์‹ฌ์ด์•ผ. SQL์„ ์•Œ๋ฉด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ž์œ ์ž์žฌ๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋“ฏ์ด, PromQL์„ ์•Œ๋ฉด ๋ชจ๋‹ˆํ„ฐ๋ง ๋ฐ์ดํ„ฐ๋ฅผ ๋งˆ์Œ๋Œ€๋กœ ๋ถ„์„ํ•  ์ˆ˜ ์žˆ์–ด! ์ฒ˜์Œ์—” ์ข€ ๋‚ฏ์„ค ์ˆ˜ ์žˆ์ง€๋งŒ, ๊ธฐ๋ณธ ๊ฐœ๋…๋งŒ ์ดํ•ดํ•˜๋ฉด ๊ธˆ๋ฐฉ ์ต์ˆ™ํ•ด์งˆ ๊ฑฐ์•ผ. ๐Ÿ’ช

๐Ÿ“š PromQL ๊ธฐ๋ณธ ๊ฐœ๋…

1. ๋ฉ”ํŠธ๋ฆญ ์„ ํƒ

๊ฐ€์žฅ ๊ธฐ๋ณธ์€ ๋ฉ”ํŠธ๋ฆญ ์ด๋ฆ„์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฑฐ์•ผ:

# ๋‹จ์ˆœ ๋ฉ”ํŠธ๋ฆญ ์กฐํšŒ
node_cpu_seconds_total

# ๋ ˆ์ด๋ธ”๋กœ ํ•„ํ„ฐ๋ง
node_cpu_seconds_total{mode="idle"}

# ์—ฌ๋Ÿฌ ์กฐ๊ฑด ์กฐํ•ฉ
node_cpu_seconds_total{mode="idle", cpu="0"}

2. ์‹œ๊ฐ„ ๋ฒ”์œ„ ์„ ํƒ

ํŠน์ • ์‹œ๊ฐ„ ๋ฒ”์œ„์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์–ด:

# ์ตœ๊ทผ 5๋ถ„๊ฐ„์˜ ๋ฐ์ดํ„ฐ
node_cpu_seconds_total[5m]

# ์ตœ๊ทผ 1์‹œ๊ฐ„
node_cpu_seconds_total[1h]

# ์ตœ๊ทผ 1์ผ
node_cpu_seconds_total[1d]

3. ์ง‘๊ณ„ ํ•จ์ˆ˜

์—ฌ๋Ÿฌ ์‹œ๊ณ„์—ด์„ ํ•˜๋‚˜๋กœ ํ•ฉ์น˜๊ฑฐ๋‚˜ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ์–ด:

# ํ‰๊ท 
avg(node_cpu_seconds_total)

# ํ•ฉ๊ณ„
sum(node_cpu_seconds_total)

# ์ตœ๋Œ€๊ฐ’
max(node_cpu_seconds_total)

# ์ตœ์†Œ๊ฐ’
min(node_cpu_seconds_total)

# ๊ฐœ์ˆ˜
count(node_cpu_seconds_total)

๐ŸŽฏ ์‹ค์ „ PromQL ์ฟผ๋ฆฌ ์˜ˆ์ œ

์ด๋ก ์€ ์ด ์ •๋„๋ฉด ์ถฉ๋ถ„ํ•ด. ์ด์ œ ์‹ค์ œ๋กœ ์œ ์šฉํ•œ ์ฟผ๋ฆฌ๋“ค์„ ์‚ดํŽด๋ณด์ž! ์ด ์ฟผ๋ฆฌ๋“ค์€ ๋ฐ”๋กœ ๋ณต์‚ฌํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด. ๐Ÿ˜Š

๐Ÿ’ป CPU ๊ด€๋ จ ์ฟผ๋ฆฌ

# CPU ์‚ฌ์šฉ๋ฅ  (์ „์ฒด ํ‰๊ท )
100 - (avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

# CPU ์ฝ”์–ด๋ณ„ ์‚ฌ์šฉ๋ฅ 
100 - (avg by(cpu) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

# CPU ๋ถ€ํ•˜ (Load Average)
node_load1  # 1๋ถ„ ํ‰๊ท 
node_load5  # 5๋ถ„ ํ‰๊ท 
node_load15 # 15๋ถ„ ํ‰๊ท 

# CPU ์‚ฌ์šฉ๋ฅ ์ด 80% ์ด์ƒ์ธ ์„œ๋ฒ„
avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100 < 20

๐Ÿง  ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ จ ์ฟผ๋ฆฌ

# ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋ฅ  (%)
(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100

# ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฉ”๋ชจ๋ฆฌ (GB)
node_memory_MemAvailable_bytes / 1024 / 1024 / 1024

# ์Šค์™‘ ์‚ฌ์šฉ๋ฅ 
(node_memory_SwapTotal_bytes - node_memory_SwapFree_bytes) / node_memory_SwapTotal_bytes * 100

# ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ (GB)
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / 1024 / 1024 / 1024

๐Ÿ’พ ๋””์Šคํฌ ๊ด€๋ จ ์ฟผ๋ฆฌ

# ๋””์Šคํฌ ์‚ฌ์šฉ๋ฅ  (%)
(1 - (node_filesystem_avail_bytes / node_filesystem_size_bytes)) * 100

# ๋””์Šคํฌ ์—ฌ์œ  ๊ณต๊ฐ„ (GB)
node_filesystem_avail_bytes{mountpoint="/"} / 1024 / 1024 / 1024

# ๋””์Šคํฌ I/O ์ฝ๊ธฐ ์†๋„ (MB/s)
rate(node_disk_read_bytes_total[5m]) / 1024 / 1024

# ๋””์Šคํฌ I/O ์“ฐ๊ธฐ ์†๋„ (MB/s)
rate(node_disk_written_bytes_total[5m]) / 1024 / 1024

# ๋””์Šคํฌ ์‚ฌ์šฉ๋ฅ ์ด 90% ์ด์ƒ์ธ ํŒŒํ‹ฐ์…˜
(1 - (node_filesystem_avail_bytes / node_filesystem_size_bytes)) * 100 > 90

๐ŸŒ ๋„คํŠธ์›Œํฌ ๊ด€๋ จ ์ฟผ๋ฆฌ

# ๋„คํŠธ์›Œํฌ ์ˆ˜์‹  ์†๋„ (MB/s)
rate(node_network_receive_bytes_total[5m]) / 1024 / 1024

# ๋„คํŠธ์›Œํฌ ์†ก์‹  ์†๋„ (MB/s)
rate(node_network_transmit_bytes_total[5m]) / 1024 / 1024

# ์ด ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ (์ˆ˜์‹  + ์†ก์‹ )
(rate(node_network_receive_bytes_total[5m]) + rate(node_network_transmit_bytes_total[5m])) / 1024 / 1024

# ๋„คํŠธ์›Œํฌ ์—๋Ÿฌ ๋ฐœ์ƒ๋ฅ 
rate(node_network_receive_errs_total[5m]) + rate(node_network_transmit_errs_total[5m])
๐Ÿ’ก PromQL ํ•™์Šต ํŒ:

1. Prometheus UI์˜ Graph ํƒญ์—์„œ ์ง์ ‘ ์ฟผ๋ฆฌ๋ฅผ ํ…Œ์ŠคํŠธํ•ด๋ด. ์ฆ‰์‹œ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์–ด์„œ ํ•™์Šตํ•˜๊ธฐ ์ข‹์•„!
2. rate()์™€ irate()์˜ ์ฐจ์ด๋ฅผ ์ดํ•ดํ•˜์ž. rate๋Š” ํ‰๊ท , irate๋Š” ์ˆœ๊ฐ„ ๋ณ€ํ™”์œจ์ด์•ผ.
3. ๋ณต์žกํ•œ ์ฟผ๋ฆฌ๋Š” ๋‹จ๊ณ„๋ณ„๋กœ ๋‚˜๋ˆ ์„œ ์ž‘์„ฑํ•ด๋ด. ํ•œ ๋ฒˆ์— ์™„์„ฑํ•˜๋ ค๊ณ  ํ•˜์ง€ ๋ง๊ณ !
4. ๊ณต์‹ ๋ฌธ์„œ์˜ ์˜ˆ์ œ๋“ค์„ ์ง์ ‘ ์‹คํ–‰ํ•ด๋ณด๋ฉด์„œ ์ตํžˆ๋Š” ๊ฒŒ ๊ฐ€์žฅ ๋นจ๋ผ.

๐ŸŽจ ํ”„๋กœํŽ˜์…”๋„ ๋Œ€์‹œ๋ณด๋“œ ๋””์ž์ธํ•˜๊ธฐ

์ด์ œ PromQL๋„ ์–ด๋А ์ •๋„ ์ตํ˜”์œผ๋‹ˆ, ์ •๋ง ๋ฉ‹์ง„ ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ๋งŒ๋“ค์–ด๋ณผ ์‹œ๊ฐ„์ด์•ผ! ๋‹จ์ˆœํžˆ ๊ทธ๋ž˜ํ”„๋งŒ ๋‚˜์—ดํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ, ํ•œ๋ˆˆ์— ์‹œ์Šคํ…œ ์ƒํƒœ๋ฅผ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๋Š” ์ง๊ด€์ ์ด๊ณ  ์•„๋ฆ„๋‹ค์šด ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ๋””์ž์ธํ•ด๋ณด์ž. ๐ŸŽจ

๐Ÿ“ ๋Œ€์‹œ๋ณด๋“œ ๋ ˆ์ด์•„์›ƒ ์ „๋žต

์ข‹์€ ๋Œ€์‹œ๋ณด๋“œ๋Š” ์ •๋ณด์˜ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋ช…ํ™•ํ•ด. ๋‹ค์Œ ์›์น™์„ ๋”ฐ๋ผ๋ณด์ž:

๐Ÿ” ์ƒ๋‹จ: ํ•ต์‹ฌ ์ง€ํ‘œ
๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ฉ”ํŠธ๋ฆญ์„ ํฐ ์ˆซ์ž๋กœ ํ‘œ์‹œ. CPU, ๋ฉ”๋ชจ๋ฆฌ, ๋””์Šคํฌ ์‚ฌ์šฉ๋ฅ  ๊ฐ™์€ ๊ฒƒ๋“ค!
๐Ÿ“Š ์ค‘๋‹จ: ์‹œ๊ณ„์—ด ๊ทธ๋ž˜ํ”„
์‹œ๊ฐ„์— ๋”ฐ๋ฅธ ๋ณ€ํ™”๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๊ทธ๋ž˜ํ”„๋“ค. ํŠธ๋ Œ๋“œ ํŒŒ์•…์— ํ•„์ˆ˜!
๐Ÿ“‹ ํ•˜๋‹จ: ์ƒ์„ธ ์ •๋ณด
ํ…Œ์ด๋ธ”์ด๋‚˜ ๋กœ๊ทธ ๊ฐ™์€ ์ƒ์„ธํ•œ ์ •๋ณด. ๋ฌธ์ œ ๋ฐœ์ƒ ์‹œ ๋“œ๋ฆด๋‹ค์šด์šฉ!

๐ŸŽฏ ํŒจ๋„ ํƒ€์ž…๋ณ„ ํ™œ์šฉ๋ฒ•

1. Stat ํŒจ๋„ - ํ•ต์‹ฌ ์ง€ํ‘œ ํ‘œ์‹œ

ํฐ ์ˆซ์ž๋กœ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ํ•œ๋ˆˆ์— ๋ณด์—ฌ์ค˜. ์ƒ‰์ƒ ์ž„๊ณ„๊ฐ’์„ ์„ค์ •ํ•˜๋ฉด ์œ„ํ—˜ ์ƒํ™ฉ์„ ์ฆ‰์‹œ ์•Œ ์ˆ˜ ์žˆ์–ด!

์„ค์ • ์˜ˆ์‹œ:
โ€ข Visualization: Stat
โ€ข Value: Last (์ตœ์‹  ๊ฐ’)
โ€ข Unit: Percent (0-100)
โ€ข Thresholds: 0 (green), 70 (yellow), 90 (red)
โ€ข Color mode: Background

2. Gauge ํŒจ๋„ - ์ง„ํ–‰๋ฅ  ํ‘œ์‹œ

๊ฒŒ์ด์ง€ ํ˜•ํƒœ๋กœ ํ˜„์žฌ ์ˆ˜์น˜๋ฅผ ์ง๊ด€์ ์œผ๋กœ ํ‘œํ˜„. ๋””์Šคํฌ ์‚ฌ์šฉ๋ฅ  ๊ฐ™์€ ๊ฑธ ํ‘œ์‹œํ•˜๊ธฐ ์ข‹์•„!

3. Time Series - ์‹œ๊ฐ„๋ณ„ ์ถ”์ด

๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๊ทธ๋ž˜ํ”„ ํƒ€์ž…. ์‹œ๊ฐ„์— ๋”ฐ๋ฅธ ๋ณ€ํ™”๋ฅผ ์„ ๋ช…ํ•˜๊ฒŒ ๋ณด์—ฌ์ค˜.

4. Heatmap - ๋ถ„ํฌ ์‹œ๊ฐํ™”

์‘๋‹ต ์‹œ๊ฐ„ ๋ถ„ํฌ๋‚˜ ์š”์ฒญ ๋นˆ๋„ ๊ฐ™์€ ๊ฑธ ์ƒ‰์ƒ์œผ๋กœ ํ‘œํ˜„. ํŒจํ„ด์„ ์ฐพ๊ธฐ ์ข‹์•„!

5. Table - ์ƒ์„ธ ๋ฐ์ดํ„ฐ

์—ฌ๋Ÿฌ ์„œ๋ฒ„์˜ ์ƒํƒœ๋ฅผ ํ•œ ๋ฒˆ์— ๋น„๊ตํ•˜๊ฑฐ๋‚˜, ์ƒ์„ธํ•œ ์ˆ˜์น˜๋ฅผ ๋ณด์—ฌ์ค„ ๋•Œ ์œ ์šฉํ•ด.

๐ŸŽจ ์ƒ‰์ƒ๊ณผ ํ…Œ๋งˆ ํ™œ์šฉ

Grafana๋Š” ๋‹ค์–‘ํ•œ ์ƒ‰์ƒ ์˜ต์…˜์„ ์ œ๊ณตํ•ด. ํšจ๊ณผ์ ์œผ๋กœ ํ™œ์šฉํ•˜๋ฉด ๊ฐ€๋…์„ฑ์ด ํ›จ์”ฌ ์ข‹์•„์ ธ!

# ์ž„๊ณ„๊ฐ’ ๊ธฐ๋ฐ˜ ์ƒ‰์ƒ ์„ค์ • ์˜ˆ์‹œ
Thresholds:
  - 0: Green (#73BF69)      โ†’ ์ •์ƒ
  - 70: Yellow (#FADE2A)    โ†’ ์ฃผ์˜
  - 85: Orange (#FF9830)    โ†’ ๊ฒฝ๊ณ 
  - 95: Red (#F2495C)       โ†’ ์œ„ํ—˜

# ๊ทธ๋ผ๋””์–ธํŠธ ์ƒ‰์ƒ (์‹œ๊ณ„์—ด ๊ทธ๋ž˜ํ”„)
Color scheme: Green-Yellow-Red
Gradient mode: Scheme

๐Ÿ“ฑ ๋ณ€์ˆ˜(Variables) ํ™œ์šฉํ•˜๊ธฐ

๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•˜๋‚˜์˜ ๋Œ€์‹œ๋ณด๋“œ๋กœ ์—ฌ๋Ÿฌ ์„œ๋ฒ„๋‚˜ ํ™˜๊ฒฝ์„ ๋ชจ๋‹ˆํ„ฐ๋งํ•  ์ˆ˜ ์žˆ์–ด. ์ •๋ง ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ์ด์•ผ! ๐Ÿš€

๋ณ€์ˆ˜ ์ƒ์„ฑ ๋ฐฉ๋ฒ•:

1. Dashboard settings (โš™๏ธ) โ†’ Variables โ†’ Add variable

2. ๋‹ค์Œ ์ •๋ณด ์ž…๋ ฅ:

# ์„œ๋ฒ„ ์ธ์Šคํ„ด์Šค ์„ ํƒ ๋ณ€์ˆ˜
Name: instance
Type: Query
Data source: Prometheus
Query: label_values(node_cpu_seconds_total, instance)
Multi-value: true
Include All option: true

# ํ™˜๊ฒฝ ์„ ํƒ ๋ณ€์ˆ˜
Name: env
Type: Query
Query: label_values(node_cpu_seconds_total, env)
Multi-value: false

3. ์ฟผ๋ฆฌ์—์„œ ๋ณ€์ˆ˜ ์‚ฌ์šฉ:

# ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ ์ฟผ๋ฆฌ
node_cpu_seconds_total{instance="$instance", env="$env"}

# ์ •๊ทœํ‘œํ˜„์‹์œผ๋กœ ์—ฌ๋Ÿฌ ๊ฐ’ ๋งค์นญ
node_cpu_seconds_total{instance=~"$instance"}

์ด์ œ ๋Œ€์‹œ๋ณด๋“œ ์ƒ๋‹จ์— ๋“œ๋กญ๋‹ค์šด์ด ์ƒ๊ฒจ์„œ ์„œ๋ฒ„๋‚˜ ํ™˜๊ฒฝ์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ์–ด. ํ•˜๋‚˜์˜ ๋Œ€์‹œ๋ณด๋“œ๋กœ ๋ชจ๋“  ์„œ๋ฒ„๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋งํ•  ์ˆ˜ ์žˆ๋‹ค๋‹ˆ, ํŽธ๋ฆฌํ•˜์ง€? ๐Ÿ˜Š

๐Ÿ’š ๋Œ€์‹œ๋ณด๋“œ ๋””์ž์ธ ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค:

1. ์ผ๊ด€์„ฑ ์œ ์ง€: ๊ฐ™์€ ์ข…๋ฅ˜์˜ ๋ฉ”ํŠธ๋ฆญ์€ ๊ฐ™์€ ์ƒ‰์ƒ๊ณผ ์Šคํƒ€์ผ ์‚ฌ์šฉ
2. ์—ฌ๋ฐฑ ํ™œ์šฉ: ํŒจ๋„ ์‚ฌ์ด์— ์ ์ ˆํ•œ ๊ฐ„๊ฒฉ์„ ๋‘์–ด ๊ฐ€๋…์„ฑ ํ–ฅ์ƒ
3. ๊ทธ๋ฃนํ™”: Row๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ด€๋ จ ํŒจ๋„๋“ค์„ ๋…ผ๋ฆฌ์ ์œผ๋กœ ๋ฌถ๊ธฐ
4. ์„ค๋ช… ์ถ”๊ฐ€: ํŒจ๋„ ์ œ๋ชฉ๊ณผ ์„ค๋ช…์„ ๋ช…ํ™•ํ•˜๊ฒŒ ์ž‘์„ฑ
5. ๋ชจ๋ฐ”์ผ ๊ณ ๋ ค: ์ž‘์€ ํ™”๋ฉด์—์„œ๋„ ์ž˜ ๋ณด์ด๋„๋ก ๋ ˆ์ด์•„์›ƒ ์กฐ์ •

๐Ÿšจ ์•Œ๋ฆผ(Alerting) ์„ค์ •ํ•˜๊ธฐ

๋ชจ๋‹ˆํ„ฐ๋ง์˜ ์ง„์ •ํ•œ ๊ฐ€์น˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์ฆ‰์‹œ ์•Œ๋ ค์ฃผ๋Š” ๊ฒƒ์ด์•ผ. 24์‹œ๊ฐ„ ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ์ง€์ผœ๋ณผ ์ˆ˜๋Š” ์—†์ž–์•„? ๊ทธ๋ž˜์„œ ์•Œ๋ฆผ ์„ค์ •์ด ์ •๋ง ์ค‘์š”ํ•ด! ๐Ÿ˜ดโ†’๐Ÿ˜ฑโ†’๐Ÿ˜Š

๐Ÿ”” Prometheus Alertmanager ์„ค์ •

Prometheus๋Š” Alertmanager๋ผ๋Š” ๋ณ„๋„ ์ปดํฌ๋„ŒํŠธ๋กœ ์•Œ๋ฆผ์„ ๊ด€๋ฆฌํ•ด. ๋จผ์ € Alertmanager๋ฅผ ์„ค์น˜ํ•˜๊ณ  ์„ค์ •ํ•ด๋ณด์ž.

# Alertmanager ๋‹ค์šด๋กœ๋“œ ๋ฐ ์„ค์น˜
wget https://github.com/prometheus/alertmanager/releases/download/v0.26.0/alertmanager-0.26.0.linux-amd64.tar.gz
tar xvfz alertmanager-0.26.0.linux-amd64.tar.gz
cd alertmanager-0.26.0.linux-amd64

# ์„ค์ • ํŒŒ์ผ ์ƒ์„ฑ (alertmanager.yml)
cat > alertmanager.yml << EOF
global:
  resolve_timeout: 5m
  
route:
  group_by: ['alertname', 'cluster']
  group_wait: 10s
  group_interval: 10s
  repeat_interval: 12h
  receiver: 'default'
  
receivers:
  - name: 'default'
    slack_configs:
      - api_url: 'YOUR_SLACK_WEBHOOK_URL'
        channel: '#alerts'
        title: '๐Ÿšจ Alert: {{ .GroupLabels.alertname }}'
        text: '{{ range .Alerts }}{{ .Annotations.description }}{{ end }}'
EOF

# Alertmanager ์‹คํ–‰
./alertmanager --config.file=alertmanager.yml

๐Ÿ“ ์•Œ๋ฆผ ๊ทœ์น™ ์ž‘์„ฑํ•˜๊ธฐ

์ด์ œ ์–ด๋–ค ์ƒํ™ฉ์—์„œ ์•Œ๋ฆผ์„ ๋ณด๋‚ผ์ง€ ๊ทœ์น™์„ ์ •์˜ํ•ด์•ผ ํ•ด. alerts.yml ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด๋ณด์ž:

groups:
  - name: system_alerts
    interval: 30s
    rules:
      # CPU ์‚ฌ์šฉ๋ฅ  ๋†’์Œ
      - alert: HighCPUUsage
        expr: 100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "High CPU usage on {{ $labels.instance }}"
          description: "CPU usage is {{ $value }}% for 5 minutes"
      
      # ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ
      - alert: HighMemoryUsage
        expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 90
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "High memory usage on {{ $labels.instance }}"
          description: "Memory usage is {{ $value }}%"
      
      # ๋””์Šคํฌ ๊ณต๊ฐ„ ๋ถ€์กฑ
      - alert: DiskSpaceLow
        expr: (1 - (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"})) * 100 > 85
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Low disk space on {{ $labels.instance }}"
          description: "Disk usage is {{ $value }}%"
      
      # ์„œ๋ฒ„ ๋‹ค์šด
      - alert: InstanceDown
        expr: up == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Instance {{ $labels.instance }} is down"
          description: "{{ $labels.instance }} has been down for more than 1 minute"

Prometheus ์„ค์ • ํŒŒ์ผ์— ์•Œ๋ฆผ ๊ทœ์น™ ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๋„ ์žŠ์ง€ ๋ง์ž:

# prometheus.yml์— ์ถ”๊ฐ€
rule_files:
  - "alerts.yml"

alerting:
  alertmanagers:
    - static_configs:
        - targets:
            - localhost:9093

๐Ÿ“ฑ Grafana ์•Œ๋ฆผ ์„ค์ •

Grafana์—์„œ๋„ ์ง์ ‘ ์•Œ๋ฆผ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์–ด. ํŠน์ • ํŒจ๋„์— ๋Œ€ํ•œ ์•Œ๋ฆผ์„ ๋งŒ๋“ค์–ด๋ณด์ž!

1. Contact Point ์„ค์ •

Alerting โ†’ Contact points โ†’ New contact point

# Slack ์—ฐ๋™ ์˜ˆ์‹œ
Name: Slack Alerts
Integration: Slack
Webhook URL: https://hooks.slack.com/services/YOUR/WEBHOOK/URL
Username: Grafana Bot
Channel: #monitoring

# ์ด๋ฉ”์ผ ์—ฐ๋™ ์˜ˆ์‹œ
Name: Email Alerts
Integration: Email
Addresses: admin@example.com, team@example.com

2. Alert Rule ์ƒ์„ฑ

ํŒจ๋„ ํŽธ์ง‘ โ†’ Alert ํƒญ โ†’ Create alert rule from this panel

์•Œ๋ฆผ ๊ทœ์น™ ์˜ˆ์‹œ:

Rule name: High CPU Alert
Condition: WHEN last() OF query(A) IS ABOVE 80
Evaluate every: 1m
For: 5m
Contact point: Slack Alerts
Message: CPU usage is critically high! Current: {{ $values.A }}%
โš ๏ธ ์•Œ๋ฆผ ํ”ผ๋กœ๋„ ์ฃผ์˜!

๋„ˆ๋ฌด ๋งŽ์€ ์•Œ๋ฆผ์€ ์˜คํžˆ๋ ค ์—ญํšจ๊ณผ์•ผ. ์ •๋ง ์ค‘์š”ํ•œ ๊ฒƒ๋งŒ ์•Œ๋ฆผ์œผ๋กœ ์„ค์ •ํ•˜๊ณ , ๋‚˜๋จธ์ง€๋Š” ๋Œ€์‹œ๋ณด๋“œ์—์„œ ํ™•์ธํ•˜๋„๋ก ํ•˜์ž. ์•Œ๋ฆผ ์ž„๊ณ„๊ฐ’๋„ ๋„ˆ๋ฌด ๋‚ฎ๊ฒŒ ์„ค์ •ํ•˜๋ฉด false positive๊ฐ€ ๋งŽ์•„์ ธ์„œ ๊ฒฐ๊ตญ ๋ฌด์‹œํ•˜๊ฒŒ ๋ผ. ์ ์ ˆํ•œ ๊ท ํ˜•์ด ์ค‘์š”ํ•ด! ๐ŸŽฏ

๐ŸŽฏ ์•Œ๋ฆผ ์šฐ์„ ์ˆœ์œ„ ์ „๋žต

์‹ฌ๊ฐ๋„ ์กฐ๊ฑด ์•Œ๋ฆผ ๋ฐฉ๋ฒ• ์˜ˆ์‹œ
Critical ์ฆ‰์‹œ ๋Œ€์‘ ํ•„์š” ์ „ํ™” + SMS + Slack ์„œ๋ฒ„ ๋‹ค์šด, DB ์ ‘์† ๋ถˆ๊ฐ€
Warning ๊ณง ๋ฌธ์ œ ๋ฐœ์ƒ ๊ฐ€๋Šฅ Slack + ์ด๋ฉ”์ผ CPU 80% ์ด์ƒ, ๋””์Šคํฌ 85% ์ด์ƒ
Info ์ฐธ๊ณ ์šฉ ์ •๋ณด ์ด๋ฉ”์ผ๋งŒ ๋ฐฐํฌ ์™„๋ฃŒ, ์ •๊ธฐ ๋ฐฑ์—… ์™„๋ฃŒ

๐ŸŽ“ ์‹ค์ „ ํ™œ์šฉ ์‹œ๋‚˜๋ฆฌ์˜ค

์ด๋ก ์€ ์ถฉ๋ถ„ํžˆ ๋ฐฐ์› ์œผ๋‹ˆ, ์ด์ œ ์‹ค์ œ ์ƒํ™ฉ์—์„œ ์–ด๋–ป๊ฒŒ ํ™œ์šฉํ•˜๋Š”์ง€ ์•Œ์•„๋ณด์ž! ์‹ค๋ฌด์—์„œ ์ž์ฃผ ๋งˆ์ฃผ์น˜๋Š” ์‹œ๋‚˜๋ฆฌ์˜ค๋“ค์„ ์ค€๋น„ํ–ˆ์–ด. ๐Ÿ˜Š

๐ŸŒ ์‹œ๋‚˜๋ฆฌ์˜ค 1: ์›น ์„œ๋น„์Šค ๋ชจ๋‹ˆํ„ฐ๋ง

์›น ์„œ๋น„์Šค๋ฅผ ์šด์˜ํ•œ๋‹ค๋ฉด ์ด๋Ÿฐ ๊ฒƒ๋“ค์„ ๋ชจ๋‹ˆํ„ฐ๋งํ•ด์•ผ ํ•ด:

ํ•„์ˆ˜ ๋ชจ๋‹ˆํ„ฐ๋ง ํ•ญ๋ชฉ

1. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฉ”ํŠธ๋ฆญ

# HTTP ์š”์ฒญ ์ˆ˜ (์ดˆ๋‹น)
rate(http_requests_total[5m])

# ์‘๋‹ต ์‹œ๊ฐ„ (ํ‰๊ท )
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))

# ์—๋Ÿฌ์œจ
rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) * 100

# ํ™œ์„ฑ ์‚ฌ์šฉ์ž ์ˆ˜
http_active_connections

2. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฉ”ํŠธ๋ฆญ

# ์ฟผ๋ฆฌ ์‹คํ–‰ ์‹œ๊ฐ„
mysql_global_status_slow_queries

# ์ปค๋„ฅ์…˜ ์ˆ˜
mysql_global_status_threads_connected

# ๋ฐ๋“œ๋ฝ ๋ฐœ์ƒ ์ˆ˜
mysql_global_status_innodb_deadlocks

3. ๋น„์ฆˆ๋‹ˆ์Šค ๋ฉ”ํŠธ๋ฆญ

# ํšŒ์›๊ฐ€์ž… ์ˆ˜ (์‹œ๊ฐ„๋‹น)
increase(user_registrations_total[1h])

# ์ฃผ๋ฌธ ๊ฑด์ˆ˜
increase(orders_total[1h])

# ๊ฒฐ์ œ ์„ฑ๊ณต๋ฅ 
rate(payments_successful[5m]) / rate(payments_total[5m]) * 100

๐Ÿณ ์‹œ๋‚˜๋ฆฌ์˜ค 2: Kubernetes ํด๋Ÿฌ์Šคํ„ฐ ๋ชจ๋‹ˆํ„ฐ๋ง

Kubernetes๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๋” ๋งŽ์€ ๊ฒƒ๋“ค์„ ๋ชจ๋‹ˆํ„ฐ๋งํ•ด์•ผ ํ•ด. ๋‹คํ–‰ํžˆ Prometheus๋Š” Kubernetes์™€ ์™„๋ฒฝํ•˜๊ฒŒ ํ†ตํ•ฉ๋ผ!

# Pod CPU ์‚ฌ์šฉ๋ฅ 
sum(rate(container_cpu_usage_seconds_total{pod!=""}[5m])) by (pod)

# Pod ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰
sum(container_memory_usage_bytes{pod!=""}) by (pod) / 1024 / 1024 / 1024

# Pod ์žฌ์‹œ์ž‘ ํšŸ์ˆ˜
kube_pod_container_status_restarts_total

# ๋…ธ๋“œ ์ƒํƒœ
kube_node_status_condition{condition="Ready", status="true"}

# Pending ์ƒํƒœ Pod
count(kube_pod_status_phase{phase="Pending"})

๐Ÿ’พ ์‹œ๋‚˜๋ฆฌ์˜ค 3: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ฑ๋Šฅ ๋ชจ๋‹ˆํ„ฐ๋ง

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ์„œ๋น„์Šค์˜ ์‹ฌ์žฅ์ด์•ผ. ์„ธ์‹ฌํ•œ ๋ชจ๋‹ˆํ„ฐ๋ง์ด ํ•„์š”ํ•ด!

MySQL/MariaDB
โ€ข ์Šฌ๋กœ์šฐ ์ฟผ๋ฆฌ
โ€ข ์ปค๋„ฅ์…˜ ํ’€ ์‚ฌ์šฉ๋ฅ 
โ€ข ํ…Œ์ด๋ธ” ๋ฝ
โ€ข ๋ณต์ œ ์ง€์—ฐ
โ€ข InnoDB ๋ฒ„ํผ ํ’€
PostgreSQL
โ€ข ํŠธ๋žœ์žญ์…˜ ์ˆ˜
โ€ข ์บ์‹œ ํžˆํŠธ์œจ
โ€ข ๋ฐ๋“œ๋ฝ
โ€ข ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…
โ€ข WAL ํฌ๊ธฐ
MongoDB
โ€ข ์ž‘์—… ํ ๊ธธ์ด
โ€ข ๋ณต์ œ ์ง€์—ฐ
โ€ข ์ปค๋„ฅ์…˜ ์ˆ˜
โ€ข ์ธ๋ฑ์Šค ์‚ฌ์šฉ๋ฅ 
โ€ข ๋””์Šคํฌ I/O

๐Ÿ”ฅ ์‹œ๋‚˜๋ฆฌ์˜ค 4: ์žฅ์•  ๋Œ€์‘ ํ”„๋กœ์„ธ์Šค

์•Œ๋ฆผ์ด ์™”์„ ๋•Œ ์–ด๋–ป๊ฒŒ ๋Œ€์‘ํ•ด์•ผ ํ• ๊นŒ? ์ฒด๊ณ„์ ์ธ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์žˆ์œผ๋ฉด ๋‹นํ™ฉํ•˜์ง€ ์•Š๊ณ  ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ์–ด!

๐Ÿ“‹ ์žฅ์•  ๋Œ€์‘ ์ฒดํฌ๋ฆฌ์ŠคํŠธ

1๋‹จ๊ณ„: ์ƒํ™ฉ ํŒŒ์•… (1-2๋ถ„)
โ€ข Grafana ๋Œ€์‹œ๋ณด๋“œ์—์„œ ์ „์ฒด ์‹œ์Šคํ…œ ์ƒํƒœ ํ™•์ธ
โ€ข ์–ด๋–ค ์„œ๋ฒ„/์„œ๋น„์Šค์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ์‹๋ณ„
โ€ข ์˜ํ–ฅ ๋ฒ”์œ„ ํŒŒ์•… (์ผ๋ถ€ ์‚ฌ์šฉ์ž? ์ „์ฒด?)

2๋‹จ๊ณ„: ๊ธด๊ธ‰ ์กฐ์น˜ (2-5๋ถ„)
โ€ข ์„œ๋น„์Šค ์žฌ์‹œ์ž‘ ๋˜๋Š” ํŠธ๋ž˜ํ”ฝ ์šฐํšŒ
โ€ข ์Šค์ผ€์ผ ์•„์›ƒ (ํ•„์š”์‹œ)
โ€ข ๊ด€๋ จ ํŒ€์— ์ƒํ™ฉ ๊ณต์œ 

3๋‹จ๊ณ„: ์›์ธ ๋ถ„์„ (10-30๋ถ„)
โ€ข ๋กœ๊ทธ ํ™•์ธ
โ€ข ๋ฉ”ํŠธ๋ฆญ ํžˆ์Šคํ† ๋ฆฌ ๋ถ„์„
โ€ข ์ตœ๊ทผ ๋ฐฐํฌ๋‚˜ ์„ค์ • ๋ณ€๊ฒฝ ํ™•์ธ

4๋‹จ๊ณ„: ๊ทผ๋ณธ ํ•ด๊ฒฐ (์‹œ๊ฐ„ ๊ฐ€๋ณ€)
โ€ข ์ž„์‹œ ์กฐ์น˜๋ฅผ ์˜๊ตฌ ํ•ด๊ฒฐ์ฑ…์œผ๋กœ ์ „ํ™˜
โ€ข ์žฌ๋ฐœ ๋ฐฉ์ง€ ๋Œ€์ฑ… ์ˆ˜๋ฆฝ
โ€ข ๋ฌธ์„œํ™” ๋ฐ ํŒ€ ๊ณต์œ 
๐Ÿ’ก ํ”„๋กœ ํŒ: ์žฅ์•  ๋Œ€์‘ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๋ฏธ๋ฆฌ ๋ฌธ์„œํ™”ํ•ด๋‘๊ณ , ์ •๊ธฐ์ ์œผ๋กœ ๋ชจ์˜ ํ›ˆ๋ จ์„ ํ•ด๋ณด์ž. ์‹ค์ œ ์ƒํ™ฉ์—์„œ ํ›จ์”ฌ ์นจ์ฐฉํ•˜๊ฒŒ ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ์–ด! ์žฌ๋Šฅ๋„ท ๊ฐ™์€ ํ”Œ๋žซํผ์—์„œ ๋ชจ๋‹ˆํ„ฐ๋ง ์ „๋ฌธ๊ฐ€์˜ ์ปจ์„คํŒ…์„ ๋ฐ›๋Š” ๊ฒƒ๋„ ์ข‹์€ ๋ฐฉ๋ฒ•์ด์•ผ. ๐ŸŽฏ

โšก ์„ฑ๋Šฅ ์ตœ์ ํ™”์™€ ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค

Prometheus์™€ Grafana๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์šด์˜ํ•˜๋ ค๋ฉด ๋ช‡ ๊ฐ€์ง€ ์ตœ์ ํ™” ๊ธฐ๋ฒ•์„ ์•Œ์•„์•ผ ํ•ด. ์‹œ์Šคํ…œ์ด ์ปค์งˆ์ˆ˜๋ก ์ด๋Ÿฐ ๊ฒƒ๋“ค์ด ์ •๋ง ์ค‘์š”ํ•ด์ ธ! ๐Ÿ’ช

๐ŸŽฏ Prometheus ์ตœ์ ํ™”

1. ๋ฉ”ํŠธ๋ฆญ ์ˆ˜์ง‘ ์ตœ์ ํ™”

# ๋ถˆํ•„์š”ํ•œ ๋ฉ”ํŠธ๋ฆญ ์ œ์™ธ
scrape_configs:
  - job_name: 'node'
    metric_relabel_configs:
      # ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋ฉ”ํŠธ๋ฆญ ๋“œ๋กญ
      - source_labels: [__name__]
        regex: 'node_network_receive_bytes_total|node_network_transmit_bytes_total'
        action: drop
      
      # ํŠน์ • ๋ ˆ์ด๋ธ” ์ œ๊ฑฐ
      - regex: 'unnecessary_label'
        action: labeldrop

์™œ ์ค‘์š”ํ• ๊นŒ? ๋ฉ”ํŠธ๋ฆญ์ด ๋งŽ์•„์งˆ์ˆ˜๋ก ์ €์žฅ ๊ณต๊ฐ„๊ณผ ์ฟผ๋ฆฌ ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ์ค˜. ์ •๋ง ํ•„์š”ํ•œ ๋ฉ”ํŠธ๋ฆญ๋งŒ ์ˆ˜์ง‘ํ•˜์ž!

2. ์ €์žฅ์†Œ ๊ด€๋ฆฌ

# Prometheus ์‹คํ–‰ ์‹œ ์Šคํ† ๋ฆฌ์ง€ ์˜ต์…˜ ์„ค์ •
./prometheus \
  --config.file=prometheus.yml \
  --storage.tsdb.path=/data/prometheus \
  --storage.tsdb.retention.time=30d \
  --storage.tsdb.retention.size=50GB \
  --storage.tsdb.wal-compression

๋ณด๊ด€ ๊ธฐ๊ฐ„ ์ „๋žต:

โ€ข ์ƒ์„ธ ๋ฐ์ดํ„ฐ: 7-30์ผ
โ€ข ์ง‘๊ณ„ ๋ฐ์ดํ„ฐ: 90์ผ-1๋…„
โ€ข ์žฅ๊ธฐ ๋ณด๊ด€์ด ํ•„์š”ํ•˜๋ฉด Thanos๋‚˜ Cortex ๊ฐ™์€ ์†”๋ฃจ์…˜ ๊ณ ๋ ค

3. ์ฟผ๋ฆฌ ์„ฑ๋Šฅ ๊ฐœ์„ 

โŒ ๋‚˜์œ ์ฟผ๋ฆฌ ์˜ˆ์‹œ:
# ๋„ˆ๋ฌด ๊ธด ์‹œ๊ฐ„ ๋ฒ”์œ„
rate(http_requests_total[1d])

# ๋ถˆํ•„์š”ํ•œ ์ง‘๊ณ„
sum(rate(http_requests_total[5m])) without (instance)
โœ… ์ข‹์€ ์ฟผ๋ฆฌ ์˜ˆ์‹œ:
# ์ ์ ˆํ•œ ์‹œ๊ฐ„ ๋ฒ”์œ„
rate(http_requests_total[5m])

# ํ•„์š”ํ•œ ๋ ˆ์ด๋ธ”๋งŒ ์œ ์ง€
sum(rate(http_requests_total[5m])) by (job, method)

๐Ÿ“Š Grafana ์ตœ์ ํ™”

1. ๋Œ€์‹œ๋ณด๋“œ ์„ฑ๋Šฅ ๊ฐœ์„ 

์ฟผ๋ฆฌ ์ตœ์ ํ™”:

โ€ข ํŒจ๋„๋‹น ์ฟผ๋ฆฌ ์ˆ˜๋ฅผ ์ตœ์†Œํ™” (๊ฐ€๋Šฅํ•˜๋ฉด 1-2๊ฐœ)
โ€ข ๋ณ€์ˆ˜๋ฅผ ํ™œ์šฉํ•ด์„œ ๋™์ ์œผ๋กœ ํ•„ํ„ฐ๋ง
โ€ข ๋ถˆํ•„์š”ํ•œ ์‹œ๊ณ„์—ด ์ œ๊ฑฐ (topk, bottomk ํ™œ์šฉ)

# ์ƒ์œ„ 10๊ฐœ๋งŒ ํ‘œ์‹œ
topk(10, rate(http_requests_total[5m]))

# ํŠน์ • ์ž„๊ณ„๊ฐ’ ์ด์ƒ๋งŒ ํ‘œ์‹œ
rate(http_requests_total[5m]) > 100

์ƒˆ๋กœ๊ณ ์นจ ๊ฐ„๊ฒฉ ์กฐ์ •:

โ€ข ์‹ค์‹œ๊ฐ„ ๋ชจ๋‹ˆํ„ฐ๋ง: 5-10์ดˆ
โ€ข ์ผ๋ฐ˜ ๋ชจ๋‹ˆํ„ฐ๋ง: 30์ดˆ-1๋ถ„
โ€ข ํžˆ์Šคํ† ๋ฆฌ ๋ถ„์„: ์ˆ˜๋™ ์ƒˆ๋กœ๊ณ ์นจ

2. ๋Œ€์‹œ๋ณด๋“œ ๊ตฌ์„ฑ ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค

๐ŸŽจ ๋””์ž์ธ
โ€ข ์ผ๊ด€๋œ ์ƒ‰์ƒ ์Šคํ‚ค๋งˆ
โ€ข ๋ช…ํ™•ํ•œ ํŒจ๋„ ์ œ๋ชฉ
โ€ข ์ ์ ˆํ•œ ๋‹จ์œ„ ํ‘œ์‹œ
โ€ข ํˆดํŒ ์„ค๋ช… ์ถ”๊ฐ€
๐Ÿ“ ๋ ˆ์ด์•„์›ƒ
โ€ข ์ค‘์š”๋„ ์ˆœ์œผ๋กœ ๋ฐฐ์น˜
โ€ข Row๋กœ ๋…ผ๋ฆฌ์  ๊ทธ๋ฃนํ™”
โ€ข ๋ชจ๋ฐ”์ผ ์นœํ™”์  ํฌ๊ธฐ
โ€ข ์ ์ ˆํ•œ ์—ฌ๋ฐฑ ์œ ์ง€
๐Ÿ”ง ๊ธฐ๋Šฅ
โ€ข ๋ณ€์ˆ˜๋กœ ์œ ์—ฐ์„ฑ ํ™•๋ณด
โ€ข ๋งํฌ๋กœ ๋“œ๋ฆด๋‹ค์šด
โ€ข ์ฃผ์„์œผ๋กœ ์ด๋ฒคํŠธ ํ‘œ์‹œ
โ€ข ํ…œํ”Œ๋ฆฟ ํ™œ์šฉ

๐Ÿ”’ ๋ณด์•ˆ ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค

โš ๏ธ ๋ณด์•ˆ ์ฒดํฌ๋ฆฌ์ŠคํŠธ

1. ์ธ์ฆ ๋ฐ ๊ถŒํ•œ:
โ€ข ๊ธฐ๋ณธ admin ๋น„๋ฐ€๋ฒˆํ˜ธ ์ฆ‰์‹œ ๋ณ€๊ฒฝ
โ€ข LDAP/OAuth ์—ฐ๋™์œผ๋กœ ์ค‘์•™ ์ธ์ฆ ๊ด€๋ฆฌ
โ€ข ์—ญํ•  ๊ธฐ๋ฐ˜ ์ ‘๊ทผ ์ œ์–ด(RBAC) ์„ค์ •
โ€ข API ํ‚ค ์ •๊ธฐ์  ๊ฐฑ์‹ 

2. ๋„คํŠธ์›Œํฌ ๋ณด์•ˆ:
โ€ข HTTPS ์‚ฌ์šฉ (Let's Encrypt ํ™œ์šฉ)
โ€ข ๋ฐฉํ™”๋ฒฝ์œผ๋กœ ์ ‘๊ทผ ์ œํ•œ
โ€ข VPN ๋˜๋Š” ํ”„๋ผ์ด๋น— ๋„คํŠธ์›Œํฌ ์‚ฌ์šฉ
โ€ข ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ ์„ค์ • (Nginx, Apache)

3. ๋ฐ์ดํ„ฐ ๋ณดํ˜ธ:
โ€ข ๋ฏผ๊ฐํ•œ ๋ฉ”ํŠธ๋ฆญ ๋ ˆ์ด๋ธ” ๋งˆ์Šคํ‚น
โ€ข ์ •๊ธฐ์ ์ธ ๋ฐฑ์—…
โ€ข ๊ฐ์‚ฌ ๋กœ๊ทธ ํ™œ์„ฑํ™”
โ€ข ๋ฐ์ดํ„ฐ ๋ณด๊ด€ ์ •์ฑ… ์ˆ˜๋ฆฝ

๐Ÿ“ˆ ํ™•์žฅ์„ฑ ๊ณ ๋ ค์‚ฌํ•ญ

์‹œ์Šคํ…œ์ด ์„ฑ์žฅํ•˜๋ฉด์„œ ๋ชจ๋‹ˆํ„ฐ๋ง ์ธํ”„๋ผ๋„ ํ•จ๊ป˜ ์„ฑ์žฅํ•ด์•ผ ํ•ด. ๋ฏธ๋ฆฌ ์ค€๋น„ํ•˜๋ฉด ๋‚˜์ค‘์— ๊ณ ์ƒํ•˜์ง€ ์•Š์•„!

๊ทœ๋ชจ ๋ฉ”ํŠธ๋ฆญ ์ˆ˜ ๊ถŒ์žฅ ๊ตฌ์„ฑ ๊ณ ๋ ค์‚ฌํ•ญ
์†Œ๊ทœ๋ชจ ~100K ๋‹จ์ผ Prometheus + Grafana ๊ธฐ๋ณธ ์„ค์ •์œผ๋กœ ์ถฉ๋ถ„
์ค‘๊ทœ๋ชจ 100K~1M Prometheus HA + ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ ์ €์žฅ์†Œ ์šฉ๋Ÿ‰ ๋ชจ๋‹ˆํ„ฐ๋ง ํ•„์š”
๋Œ€๊ทœ๋ชจ 1M~10M Prometheus Federation + Thanos ์ƒค๋”ฉ ๋ฐ ์žฅ๊ธฐ ์ €์žฅ์†Œ ํ•„์ˆ˜
์ดˆ๋Œ€๊ทœ๋ชจ 10M+ Cortex ๋˜๋Š” Mimir ์ „๋ฌธ ์ปจ์„คํŒ… ๊ถŒ์žฅ

๐ŸŽ“ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ๊ณผ ํ™•์žฅ

๊ธฐ๋ณธ์„ ๋งˆ์Šคํ„ฐํ–ˆ๋‹ค๋ฉด, ์ด์ œ ๋” ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ๋“ค์„ ํ™œ์šฉํ•ด๋ณผ ์‹œ๊ฐ„์ด์•ผ! ์ด๋Ÿฐ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ๋“ค์„ ์•Œ๋ฉด ์ง„์งœ ์ „๋ฌธ๊ฐ€๊ฐ€ ๋  ์ˆ˜ ์žˆ์–ด. ๐Ÿš€

๐Ÿ”— Recording Rules๋กœ ์ฟผ๋ฆฌ ์ตœ์ ํ™”

๋ณต์žกํ•œ ์ฟผ๋ฆฌ๋ฅผ ๋งค๋ฒˆ ์‹คํ–‰ํ•˜๋Š” ๊ฑด ๋น„ํšจ์œจ์ ์ด์•ผ. Recording Rules๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฏธ๋ฆฌ ๊ณ„์‚ฐํ•ด์„œ ์ €์žฅํ•  ์ˆ˜ ์žˆ์–ด!

# recording_rules.yml
groups:
  - name: cpu_rules
    interval: 30s
    rules:
      # CPU ์‚ฌ์šฉ๋ฅ ์„ ๋ฏธ๋ฆฌ ๊ณ„์‚ฐ
      - record: instance:cpu_usage:rate5m
        expr: 100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
      
      # ์„œ๋ฒ„๋ณ„ ํ‰๊ท  ์‘๋‹ต ์‹œ๊ฐ„
      - record: instance:http_response_time:avg
        expr: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))
      
      # ์ผ๋ณ„ ์š”์ฒญ ์ˆ˜ ์ง‘๊ณ„
      - record: job:http_requests:rate1h
        expr: sum by(job) (rate(http_requests_total[1h]))

์ด์ œ ๋Œ€์‹œ๋ณด๋“œ์—์„œ ๋ณต์žกํ•œ ์ฟผ๋ฆฌ ๋Œ€์‹  instance:cpu_usage:rate5m ๊ฐ™์€ ๊ฐ„๋‹จํ•œ ๋ฉ”ํŠธ๋ฆญ ์ด๋ฆ„๋งŒ ์‚ฌ์šฉํ•˜๋ฉด ๋ผ. ํ›จ์”ฌ ๋น ๋ฅด๊ณ  ํšจ์œจ์ ์ด์ง€! โšก

๐ŸŽจ ์ปค์Šคํ…€ Exporter ๋งŒ๋“ค๊ธฐ

๊ธฐ๋ณธ Exporter๋กœ ๋ถ€์กฑํ•˜๋‹ค๋ฉด? ์ง์ ‘ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด! Python์œผ๋กœ ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž.

# custom_exporter.py
from prometheus_client import start_http_server, Gauge
import time
import psutil

# ๋ฉ”ํŠธ๋ฆญ ์ •์˜
cpu_usage = Gauge('custom_cpu_usage', 'CPU usage percentage')
memory_usage = Gauge('custom_memory_usage', 'Memory usage percentage')
disk_usage = Gauge('custom_disk_usage', 'Disk usage percentage', ['partition'])

def collect_metrics():
    """์‹œ์Šคํ…œ ๋ฉ”ํŠธ๋ฆญ ์ˆ˜์ง‘"""
    while True:
        # CPU ์‚ฌ์šฉ๋ฅ 
        cpu_usage.set(psutil.cpu_percent(interval=1))
        
        # ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋ฅ 
        memory = psutil.virtual_memory()
        memory_usage.set(memory.percent)
        
        # ๋””์Šคํฌ ์‚ฌ์šฉ๋ฅ  (ํŒŒํ‹ฐ์…˜๋ณ„)
        for partition in psutil.disk_partitions():
            try:
                usage = psutil.disk_usage(partition.mountpoint)
                disk_usage.labels(partition=partition.device).set(usage.percent)
            except:
                pass
        
        time.sleep(15)  # 15์ดˆ๋งˆ๋‹ค ์ˆ˜์ง‘

if __name__ == '__main__':
    # 8000 ํฌํŠธ์—์„œ ๋ฉ”ํŠธ๋ฆญ ์ œ๊ณต
    start_http_server(8000)
    print("Exporter running on port 8000")
    collect_metrics()

์ด๋ ‡๊ฒŒ ๋งŒ๋“  Exporter๋ฅผ Prometheus ์„ค์ •์— ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฐ”๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด!

๐ŸŒ Service Discovery ํ™œ์šฉ

์„œ๋ฒ„๊ฐ€ ๋™์ ์œผ๋กœ ์ถ”๊ฐ€/์ œ๊ฑฐ๋˜๋Š” ํ™˜๊ฒฝ์ด๋ผ๋ฉด Service Discovery๊ฐ€ ํ•„์ˆ˜์•ผ. Kubernetes ์˜ˆ์ œ๋ฅผ ๋ณด์ž:

# Kubernetes Service Discovery ์„ค์ •
scrape_configs:
  - job_name: 'kubernetes-pods'
    kubernetes_sd_configs:
      - role: pod
    
    relabel_configs:
      # prometheus.io/scrape ์–ด๋…ธํ…Œ์ด์…˜์ด ์žˆ๋Š” Pod๋งŒ ์ˆ˜์ง‘
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      
      # ํฌํŠธ ์„ค์ •
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port]
        action: replace
        target_label: __address__
        regex: (.+)
        replacement: $1
      
      # ๋ฉ”ํŠธ๋ฆญ ๊ฒฝ๋กœ ์„ค์ •
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)
      
      # ๋ ˆ์ด๋ธ” ์ถ”๊ฐ€
      - source_labels: [__meta_kubernetes_namespace]
        target_label: kubernetes_namespace
      - source_labels: [__meta_kubernetes_pod_name]
        target_label: kubernetes_pod_name

๐Ÿ“Š Grafana ํ”Œ๋Ÿฌ๊ทธ์ธ ํ™œ์šฉ

Grafana๋Š” ๋‹ค์–‘ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ์œผ๋กœ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์–ด. ์œ ์šฉํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ๋“ค์„ ์†Œ๊ฐœํ• ๊ฒŒ!

๐Ÿ—บ๏ธ Worldmap Panel
์ง€๋ฆฌ์  ๋ฐ์ดํ„ฐ๋ฅผ ์„ธ๊ณ„ ์ง€๋„์— ํ‘œ์‹œ. ๊ธ€๋กœ๋ฒŒ ์„œ๋น„์Šค ๋ชจ๋‹ˆํ„ฐ๋ง์— ์™„๋ฒฝ!
๐Ÿ“ˆ Plotly Panel
๊ณ ๊ธ‰ ํ†ต๊ณ„ ์ฐจํŠธ์™€ 3D ์‹œ๊ฐํ™”. ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ๋ถ„์„์— ์œ ์šฉ!
๐Ÿ”” Alertlist Panel
ํ˜„์žฌ ๋ฐœ์ƒ ์ค‘์ธ ์•Œ๋ฆผ์„ ํ•œ๋ˆˆ์— ํ‘œ์‹œ. ๋Œ€์‹œ๋ณด๋“œ์— ์ถ”๊ฐ€ํ•˜๋ฉด ํŽธ๋ฆฌ!
# ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค์น˜ ๋ช…๋ น์–ด
grafana-cli plugins install grafana-worldmap-panel
grafana-cli plugins install natel-plotly-panel
grafana-cli plugins install camptocamp-prometheus-alertmanager-datasource

# ์„ค์น˜ ํ›„ Grafana ์žฌ์‹œ์ž‘
sudo systemctl restart grafana-server

๐Ÿ”„ Prometheus Federation

์—ฌ๋Ÿฌ Prometheus ์„œ๋ฒ„๋ฅผ ๊ณ„์ธต์ ์œผ๋กœ ๊ตฌ์„ฑํ•ด์„œ ๋Œ€๊ทœ๋ชจ ํ™˜๊ฒฝ์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด!

# ์ค‘์•™ Prometheus ์„ค์ •
scrape_configs:
  - job_name: 'federate'
    scrape_interval: 15s
    honor_labels: true
    metrics_path: '/federate'
    
    params:
      'match[]':
        - '{job="prometheus"}'
        - '{__name__=~"job:.*"}'  # Recording rules
    
    static_configs:
      - targets:
        - 'prometheus-dc1:9090'
        - 'prometheus-dc2:9090'
        - 'prometheus-dc3:9090'

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฐ ๋ฐ์ดํ„ฐ์„ผํ„ฐ์˜ Prometheus๊ฐ€ ๋กœ์ปฌ ๋ฉ”ํŠธ๋ฆญ์„ ์ˆ˜์ง‘ํ•˜๊ณ , ์ค‘์•™ Prometheus๊ฐ€ ์ง‘๊ณ„๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€. ํšจ์œจ์ ์ด์ง€? ๐Ÿ˜Š

๐ŸŽฏ ์‹ค๋ฌด ํŒ๊ณผ ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ…

์‹ค์ œ๋กœ ์šด์˜ํ•˜๋‹ค ๋ณด๋ฉด ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋ฌธ์ œ๋“ค์„ ๋งŒ๋‚˜๊ฒŒ ๋ผ. ์ž์ฃผ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋“ค๊ณผ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์ •๋ฆฌํ•ด๋ดค์–ด!

๐Ÿ”ง ์ž์ฃผ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋“ค

๋ฌธ์ œ 1: "Target Down" ์—๋Ÿฌ

์ฆ์ƒ: Prometheus UI์—์„œ ํƒ€๊ฒŸ์ด ๋นจ๊ฐ„์ƒ‰์œผ๋กœ ํ‘œ์‹œ๋˜๊ณ  "context deadline exceeded" ์—๋Ÿฌ

์›์ธ:

โ€ข ๋ฐฉํ™”๋ฒฝ์ด๋‚˜ ๋ณด์•ˆ ๊ทธ๋ฃน์—์„œ ํฌํŠธ ์ฐจ๋‹จ
โ€ข ํƒ€๊ฒŸ ์„œ๋ฒ„์˜ Exporter๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์Œ
โ€ข ๋„คํŠธ์›Œํฌ ์ง€์—ฐ์ด๋‚˜ ํƒ€์ž„์•„์›ƒ
โ€ข ์ž˜๋ชป๋œ IP ์ฃผ์†Œ๋‚˜ ํฌํŠธ ์„ค์ •

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•:

# 1. ํƒ€๊ฒŸ ์„œ๋ฒ„์—์„œ Exporter ์ƒํƒœ ํ™•์ธ
curl http://target-server:9100/metrics

# 2. ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ
telnet target-server 9100

# 3. Prometheus ๋กœ๊ทธ ํ™•์ธ
tail -f /var/log/prometheus/prometheus.log

# 4. ํƒ€์ž„์•„์›ƒ ์„ค์ • ์กฐ์ •
scrape_configs:
  - job_name: 'node'
    scrape_timeout: 30s  # ๊ธฐ๋ณธ 10s์—์„œ ์ฆ๊ฐ€

๋ฌธ์ œ 2: Grafana ๋Œ€์‹œ๋ณด๋“œ๊ฐ€ ๋А๋ฆผ

์ฆ์ƒ: ๋Œ€์‹œ๋ณด๋“œ ๋กœ๋”ฉ์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๊ฑฐ๋‚˜ ํƒ€์ž„์•„์›ƒ ๋ฐœ์ƒ

์›์ธ:

โ€ข ๋„ˆ๋ฌด ๋งŽ์€ ํŒจ๋„์ด๋‚˜ ๋ณต์žกํ•œ ์ฟผ๋ฆฌ
โ€ข ๊ธด ์‹œ๊ฐ„ ๋ฒ”์œ„ ์กฐํšŒ
โ€ข ๋†’์€ ์ƒˆ๋กœ๊ณ ์นจ ๋นˆ๋„
โ€ข Prometheus ์„œ๋ฒ„ ๊ณผ๋ถ€ํ•˜

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•:

# 1. ์ฟผ๋ฆฌ ์ตœ์ ํ™” - ์‹œ๊ฐ„ ๋ฒ”์œ„ ์ œํ•œ
rate(http_requests_total[5m])  # โœ… ์ข‹์Œ
rate(http_requests_total[1d])  # โŒ ๋‚˜์จ

# 2. ๋ถˆํ•„์š”ํ•œ ์‹œ๊ณ„์—ด ์ œ๊ฑฐ
topk(10, rate(http_requests_total[5m]))  # ์ƒ์œ„ 10๊ฐœ๋งŒ

# 3. Recording Rules ์‚ฌ์šฉ
# ๋ณต์žกํ•œ ์ฟผ๋ฆฌ๋ฅผ ๋ฏธ๋ฆฌ ๊ณ„์‚ฐํ•ด์„œ ์ €์žฅ

# 4. ํŒจ๋„ ์ˆ˜ ์ค„์ด๊ธฐ
# ๋น„์Šทํ•œ ๋ฉ”ํŠธ๋ฆญ์€ ํ•˜๋‚˜์˜ ํŒจ๋„์— ํ†ตํ•ฉ

๋ฌธ์ œ 3: ๋””์Šคํฌ ๊ณต๊ฐ„ ๋ถ€์กฑ

์ฆ์ƒ: Prometheus๊ฐ€ "out of disk space" ์—๋Ÿฌ์™€ ํ•จ๊ป˜ ์ค‘๋‹จ

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•:

# 1. ํ˜„์žฌ ์‚ฌ์šฉ๋Ÿ‰ ํ™•์ธ
du -sh /data/prometheus

# 2. ๋ณด๊ด€ ๊ธฐ๊ฐ„ ๋‹จ์ถ•
./prometheus \
  --storage.tsdb.retention.time=15d \  # 30d โ†’ 15d
  --storage.tsdb.retention.size=30GB

# 3. ์˜ค๋ž˜๋œ ๋ฐ์ดํ„ฐ ์ˆ˜๋™ ์‚ญ์ œ
# Prometheus๋ฅผ ์ค‘์ง€ํ•˜๊ณ 
rm -rf /data/prometheus/01XXXXXX*  # ์˜ค๋ž˜๋œ ๋ธ”๋ก ์‚ญ์ œ

# 4. ๋ถˆํ•„์š”ํ•œ ๋ฉ”ํŠธ๋ฆญ ์ œ์™ธ
metric_relabel_configs:
  - source_labels: [__name__]
    regex: 'unused_metric_.*'
    action: drop

๋ฌธ์ œ 4: ์•Œ๋ฆผ์ด ์˜ค์ง€ ์•Š์Œ

์ฆ์ƒ: ์•Œ๋ฆผ ๊ทœ์น™์ด ๋ฐœ๋™ํ–ˆ๋Š”๋ฐ ์•Œ๋ฆผ์„ ๋ฐ›์ง€ ๋ชปํ•จ

์ฒดํฌ๋ฆฌ์ŠคํŠธ:

1. Prometheus์—์„œ ์•Œ๋ฆผ ๊ทœ์น™ ํ™•์ธ
โ€ข Prometheus UI โ†’ Alerts ํƒญ์—์„œ ๊ทœ์น™์ด Firing ์ƒํƒœ์ธ์ง€ ํ™•์ธ

2. Alertmanager ์—ฐ๊ฒฐ ํ™•์ธ
โ€ข Prometheus UI โ†’ Status โ†’ Runtime & Build Information
โ€ข Alertmanagers ์„น์…˜์—์„œ ์—ฐ๊ฒฐ ์ƒํƒœ ํ™•์ธ

3. Alertmanager ๋กœ๊ทธ ํ™•์ธ
tail -f /var/log/alertmanager/alertmanager.log

4. ์•Œ๋ฆผ ์ฑ„๋„ ์„ค์ • ํ™•์ธ
โ€ข Slack Webhook URL์ด ์˜ฌ๋ฐ”๋ฅธ์ง€
โ€ข ์ด๋ฉ”์ผ SMTP ์„ค์ •์ด ์ •ํ™•ํ•œ์ง€
โ€ข ๋ฐฉํ™”๋ฒฝ์—์„œ ์•„์›ƒ๋ฐ”์šด๋“œ ์—ฐ๊ฒฐ ํ—ˆ์šฉ ์—ฌ๋ถ€

๐Ÿ’ก ์„ฑ๋Šฅ ํŠœ๋‹ ํŒ

๐Ÿš€ Prometheus ํŠœ๋‹
โ€ข WAL ์••์ถ• ํ™œ์„ฑํ™”
โ€ข ๋ฉ”๋ชจ๋ฆฌ ๋งต ์ฒญํฌ ์‚ฌ์šฉ
โ€ข ์ ์ ˆํ•œ ์Šคํฌ๋žฉ ๊ฐ„๊ฒฉ ์„ค์ •
โ€ข ์ƒค๋”ฉ ๊ณ ๋ ค (๋Œ€๊ทœ๋ชจ ํ™˜๊ฒฝ)
๐Ÿ“Š Grafana ํŠœ๋‹
โ€ข ์ฟผ๋ฆฌ ์บ์‹ฑ ํ™œ์šฉ
โ€ข ํŒจ๋„๋ณ„ ์ƒˆ๋กœ๊ณ ์นจ ๊ฐ„๊ฒฉ ์กฐ์ •
โ€ข ๋ณ€์ˆ˜ ์ฟผ๋ฆฌ ์ตœ์ ํ™”
โ€ข ์ด๋ฏธ์ง€ ๋ Œ๋”๋ง ์„œ๋ฒ„ ๋ถ„๋ฆฌ
๐Ÿ” ์ฟผ๋ฆฌ ํŠœ๋‹
โ€ข Recording Rules ์ ๊ทน ํ™œ์šฉ
โ€ข ๋ ˆ์ด๋ธ” ์นด๋””๋„๋ฆฌํ‹ฐ ๊ด€๋ฆฌ
โ€ข ์ง‘๊ณ„ ํ•จ์ˆ˜ ํšจ์œจ์  ์‚ฌ์šฉ
โ€ข ๋ถˆํ•„์š”ํ•œ ์ •๊ทœํ‘œํ˜„์‹ ์ œ๊ฑฐ

๐Ÿ“š ์œ ์šฉํ•œ ๋ฆฌ์†Œ์Šค

๊ณ„์† ํ•™์Šตํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์ด๋Ÿฐ ๋ฆฌ์†Œ์Šค๋“ค์„ ํ™œ์šฉํ•ด๋ด:

๐ŸŒ ๊ณต์‹ ๋ฌธ์„œ:
โ€ข Prometheus ๊ณต์‹ ๋ฌธ์„œ: prometheus.io/docs
โ€ข Grafana ๊ณต์‹ ๋ฌธ์„œ: grafana.com/docs
โ€ข PromQL ์น˜ํŠธ์‹œํŠธ: promlabs.com/promql-cheat-sheet

๐Ÿ‘ฅ ์ปค๋ฎค๋‹ˆํ‹ฐ:
โ€ข Prometheus ์Šฌ๋ž™: slack.cncf.io
โ€ข Grafana ํฌ๋Ÿผ: community.grafana.com
โ€ข Stack Overflow: prometheus, grafana ํƒœ๊ทธ

๐Ÿ“– ํ•™์Šต ์ž๋ฃŒ:
โ€ข Prometheus Up & Running (์ฑ…)
โ€ข Grafana ๊ณต์‹ ํŠœํ† ๋ฆฌ์–ผ
โ€ข YouTube ์ฑ„๋„: Grafana Labs, Prometheus

๐ŸŽ“ ์ „๋ฌธ๊ฐ€ ๋„์›€:
โ€ข ์žฌ๋Šฅ๋„ท์—์„œ ๋ชจ๋‹ˆํ„ฐ๋ง ์ „๋ฌธ๊ฐ€ ์ฐพ๊ธฐ
โ€ข ์ปจ์„คํŒ… ์„œ๋น„์Šค ํ™œ์šฉ
โ€ข ์˜จ๋ผ์ธ ๊ฐ•์˜ ์ˆ˜๊ฐ•

๐ŸŽฌ ๋งˆ๋ฌด๋ฆฌํ•˜๋ฉฐ

์™€! ์—ฌ๊ธฐ๊นŒ์ง€ ์ฝ์—ˆ๋‹ค๋ฉด ์ •๋ง ๋Œ€๋‹จํ•ด! ๐Ÿ‘ Prometheus์™€ Grafana์— ๋Œ€ํ•ด ๊ฝค ๋งŽ์€ ๊ฑธ ๋ฐฐ์› ์„ ๊ฑฐ์•ผ. ์ฒ˜์Œ์—” ๋ณต์žกํ•ด ๋ณด์˜€๊ฒ ์ง€๋งŒ, ํ•˜๋‚˜์”ฉ ๋”ฐ๋ผํ•˜๋‹ค ๋ณด๋ฉด ์–ด๋А์ƒˆ ์ „๋ฌธ๊ฐ€๊ฐ€ ๋˜์–ด ์žˆ์„ ๊ฑฐ์•ผ.

๋ชจ๋‹ˆํ„ฐ๋ง์€ ๋‹จ์ˆœํžˆ ๋„๊ตฌ๋ฅผ ์„ค์น˜ํ•˜๊ณ  ๋๋‚˜๋Š” ๊ฒŒ ์•„๋‹ˆ์•ผ. ์ง€์†์ ์ธ ๊ฐœ์„ ๊ณผ ์ตœ์ ํ™”๊ฐ€ ํ•„์š”ํ•œ ์—ฌ์ •์ด์ง€. ์‹œ์Šคํ…œ์ด ์„ฑ์žฅํ•˜๋ฉด์„œ ๋ชจ๋‹ˆํ„ฐ๋ง๋„ ํ•จ๊ป˜ ์ง„ํ™”ํ•ด์•ผ ํ•ด. ๊ทธ๋ฆฌ๊ณ  ๊ทธ ๊ณผ์ •์—์„œ ๋งŽ์€ ๊ฒƒ์„ ๋ฐฐ์šฐ๊ฒŒ ๋  ๊ฑฐ์•ผ! ๐Ÿ“ˆ

๐ŸŽฏ ํ•ต์‹ฌ ์š”์•ฝ

1. Prometheus๋Š” ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘๊ณผ ์ €์žฅ์„ ๋‹ด๋‹น

โ€ข Pull ๋ฐฉ์‹์œผ๋กœ ๋ฉ”ํŠธ๋ฆญ ์ˆ˜์ง‘
โ€ข ์‹œ๊ณ„์—ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ํšจ์œจ์ ์œผ๋กœ ์ €์žฅ
โ€ข PromQL๋กœ ๊ฐ•๋ ฅํ•œ ์ฟผ๋ฆฌ ๊ฐ€๋Šฅ
โ€ข Alertmanager๋กœ ์•Œ๋ฆผ ๊ด€๋ฆฌ

2. Grafana๋Š” ์‹œ๊ฐํ™”๋ฅผ ๋‹ด๋‹น

โ€ข ์•„๋ฆ„๋‹ต๊ณ  ์ง๊ด€์ ์ธ ๋Œ€์‹œ๋ณด๋“œ
โ€ข ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ์†Œ์Šค ์ง€์›
โ€ข ํ’๋ถ€ํ•œ ์‹œ๊ฐํ™” ์˜ต์…˜
โ€ข ์•Œ๋ฆผ ๋ฐ ๊ณต์œ  ๊ธฐ๋Šฅ

3. ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ์™„๋ฒฝํ•œ ๋ชจ๋‹ˆํ„ฐ๋ง ์‹œ์Šคํ…œ

โ€ข ์‹ค์‹œ๊ฐ„ ๋ชจ๋‹ˆํ„ฐ๋ง
โ€ข ๋ฌธ์ œ ์กฐ๊ธฐ ๋ฐœ๊ฒฌ
โ€ข ์„ฑ๋Šฅ ์ตœ์ ํ™”
โ€ข ๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ ์˜์‚ฌ๊ฒฐ์ •

๐Ÿ’š ๋งˆ์ง€๋ง‰ ์กฐ์–ธ

์™„๋ฒฝํ•œ ๋ชจ๋‹ˆํ„ฐ๋ง ์‹œ์Šคํ…œ์„ ํ•œ ๋ฒˆ์— ๊ตฌ์ถ•ํ•˜๋ ค๊ณ  ํ•˜์ง€ ๋งˆ. ์ž‘๊ฒŒ ์‹œ์ž‘ํ•ด์„œ ์ ์ง„์ ์œผ๋กœ ๊ฐœ์„ ํ•ด๋‚˜๊ฐ€๋Š” ๊ฒŒ ์ข‹์•„. ๊ธฐ๋ณธ์ ์ธ ์‹œ์Šคํ…œ ๋ฉ”ํŠธ๋ฆญ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ, ํ•„์š”์— ๋”ฐ๋ผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฉ”ํŠธ๋ฆญ, ๋น„์ฆˆ๋‹ˆ์Šค ๋ฉ”ํŠธ๋ฆญ์„ ์ถ”๊ฐ€ํ•ด๊ฐ€๋ฉด ๋ผ.

๊ทธ๋ฆฌ๊ณ  ํ˜ผ์ž ๊ณ ๋ฏผํ•˜์ง€ ๋ง๊ณ  ์ปค๋ฎค๋‹ˆํ‹ฐ๋ฅผ ํ™œ์šฉํ•˜์ž! ์žฌ๋Šฅ๋„ท ๊ฐ™์€ ํ”Œ๋žซํผ์—์„œ ์ „๋ฌธ๊ฐ€์˜ ๋„์›€์„ ๋ฐ›๋Š” ๊ฒƒ๋„ ์ข‹์€ ๋ฐฉ๋ฒ•์ด์•ผ. ๋•Œ๋กœ๋Š” ๊ฒฝํ—˜ ๋งŽ์€ ์‚ฌ๋žŒ์˜ ์กฐ์–ธ ํ•œ๋งˆ๋””๊ฐ€ ๋ฉฐ์น ๊ฐ„์˜ ์‚ฝ์งˆ์„ ์ค„์—ฌ์ค„ ์ˆ˜ ์žˆ๊ฑฐ๋“ ! ๐Ÿ˜Š

์„œ๋ฒ„ ๋ชจ๋‹ˆํ„ฐ๋ง์€ ๋งˆ๋ผํ†ค์ด์ง€ ๋‹จ๊ฑฐ๋ฆฌ ๋‹ฌ๋ฆฌ๊ธฐ๊ฐ€ ์•„๋‹ˆ์•ผ. ์ฒœ์ฒœํžˆ, ๊พธ์ค€ํžˆ ๊ฐœ์„ ํ•ด๋‚˜๊ฐ€๋‹ค ๋ณด๋ฉด ์–ด๋А์ƒˆ ์•ˆ์ •์ ์ด๊ณ  ํšจ์œจ์ ์ธ ์‹œ์Šคํ…œ์„ ๊ฐ–์ถ”๊ฒŒ ๋  ๊ฑฐ์•ผ. ํ™”์ดํŒ…! ๐Ÿ’ช

๐Ÿ“Š ๐Ÿš€ โœจ Happy Monitoring! ๋‹น์‹ ์˜ ์„œ๋ฒ„๋ฅผ ์ง€์ผœ์ฃผ๋Š” ๋“ ๋“ ํ•œ ํŒŒ์ˆ˜๊พผ

์ด ๊ธ€์ด ๋„์›€์ด ๋˜์—ˆ๋‹ค๋ฉด, ์žฌ๋Šฅ๋„ท์—์„œ ๋” ๋งŽ์€ IT ์ง€์‹์„ ํƒํ—˜ํ•ด๋ณด์„ธ์š”! ๐ŸŒŸ
์งˆ๋ฌธ์ด๋‚˜ ํ”ผ๋“œ๋ฐฑ์€ ์–ธ์ œ๋“  ํ™˜์˜์ž…๋‹ˆ๋‹ค. ํ•จ๊ป˜ ์„ฑ์žฅํ•ด์š”! ๐Ÿ’ช

๋Œ“๊ธ€ ์ž‘์„ฑ

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

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

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