[Prometheus] PromQL

Prometheus๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๊ธฐ ์œ„ํ•œ ์šฉ๋„๋กœ ์ž์‹ ๋งŒ์˜ Query syntax๋ฅผ ์ œ๊ณตํ•˜๋Š”๋ฐ, ๊ทธ๊ฒŒ ๋ฐ”๋กœ PromQL์ด๋‹ค.

Prometheus ๊ธฐ๋ฐ˜์œผ๋กœ ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ๊ตฌ์„ฑํ–ˆ๋‹ค๋ฉด Grafana์—์„œ ์ง์ ‘ ์ฟผ๋ฆฌ๋ฅผ ์กฐ์ •ํ•  ์ผ์ด ์ข…์ข… ์žˆ์„ ๊ฒƒ์ด๋‹ค.




๊ธฐ๋ณธ ๊ตฌ์กฐ - ๋‹จ์ˆœ ์กฐํšŒ

PromQL๋„ ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์Šค์บ”ํ•ด์˜ค๋Š” ๊ฒƒ์ด ๋จผ์ €๋‹ค.
๋ฐ์ดํ„ฐ ์Šค์บ”, ํ•„ํ„ฐ ํ‘œํ˜„์‹์€ ์ค‘๊ด„ํ˜ธ ๋‚ด์˜ ํ‚ค=๊ฐ’ ์Œ์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ ์ฟผ๋ฆฌ๋Š” __name__์ด http_client_duration_milliseconds_count์ธ ๋ฐ์ดํ„ฐ๋งŒ ํ•„ํ„ฐ๋งํ•ด์˜ค๋Š” ๊ตฌ๋ฌธ์ด๋‹ค.

{__name__="http_client_duration_milliseconds_count"}

์—ฌ๊ธฐ์„œ __name__์€ metric ์ด๋ฆ„์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํŠน์ˆ˜ํ•œ ํ•„๋“œ๋‹ค. ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋น„๊ตํ•˜๋ฉด ํ…Œ์ด๋ธ”๊ณผ ๋™๋“ฑํ•œ ๋‹จ์œ„๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ด๊ฑด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œํ˜„ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

http_client_duration_milliseconds_count{}

์ด๊ฑด ๋ฐ”๋กœ ์ด์ „์˜ ์ฟผ๋ฆฌ์™€ ์ •ํ™•ํžˆ ๋™์ผํ•œ ๋™์ž‘์„ ํ•œ๋‹ค.
๋ณ„ ์ฐจ์ด๋Š” ์—†์ง€๋งŒ ๋ณดํ†ต ์ด๋Ÿฐ ์‹์œผ๋กœ ๋” ์ž์ฃผ ์‚ฌ์šฉ๋œ๋‹ค.




ํ•„ํ„ฐ

๋ฉ”ํŠธ๋ฆญ ์กฐํšŒ์— ์ถ”๊ฐ€์ ์ธ ์กฐ๊ฑด ํ•„ํ„ฐ๋ฅผ ๊ฑธ๊ณ  ์‹ถ๋‹ค๋ฉด, ์ค‘๊ด„ํ˜ธ ์ ˆ์— ํ‚ค=๊ฐ’ ์Œ์„ ์šฐ๊ฒจ๋„ฃ์œผ๋ฉด ๋œ๋‹ค.
์—ฌ๊ธฐ์„œ ์ค‘๊ด„ํ˜ธ ์ ˆ์„ ์ •ํ™•ํ•œ ์šฉ์–ด๋กœ๋Š” Time series selector๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

http_server_request_duration_seconds_count{service_namespace="prod", service_name="...-API"}

์ด๋Ÿฌ๋ฉด service_namespace์ด prod๊ณ , service_name์ด API์ธ ๋ฉ”ํŠธ๋ฆญ ๋ฐ์ดํ„ฐ๋งŒ ์กฐํšŒ๊ฐ€ ๋œ๋‹ค.
์ด์ฒ˜๋Ÿผ ๊ธฐ๋ณธ์ ์œผ๋กœ ์‹œ์Šคํ…œ ์Šคํ…Œ์ด์ง€์™€ ์‹œ์Šคํ…œ ์ด๋ฆ„ ์ •๋„๋Š” ํ•„ํ„ฐ๋กœ ์ฃผ๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์„ ๊ฒƒ์ด๋‹ค.

promQL์˜ ํ•„ํ„ฐ ์กฐ๊ฑด์€ ์ œํ•œ์ด ์ข€ ๊ฐ•ํ•œ ํŽธ์ด๋‹ค.
๋Œ€์†Œ๋น„๊ต ๊ฐ™์€ ๋ณต์žกํ•  ์ˆ˜ ์žˆ๋Š” ์กฐ๊ฑด์‹์€ ์ค„ ์ˆ˜ ์—†๊ณ , ์ผ์น˜ ๋น„๊ต(=), ๋ถˆ์ผ์น˜ ๋น„๊ต(!=), ์ •๊ทœ์‹ ๋น„๊ต(=), ์ •๊ทœ์‹ ๋ถˆ์ผ์น˜ ๋น„๊ต(!) 4๊ฐœ ์ •๋„๋งŒ ์ œ๊ณต์ด ๋œ๋‹ค.

์ •๊ทœ์‹ ํ‘œํ˜„ ์ฒ˜๋ฆฌ๋Š” ์œตํ†ต์„ฑ์ด ์žˆ๋Š” ํŽธ์ด๋‹ค.
env="foo" ๊ฐ™์€ ์‹์œผ๋กœ ์“ฐ๋ฉด, ์•”์‹œ์ ์œผ๋กœ env="^foo$"๋กœ ํ•ด์„ํ•ด์„œ ํฌํ•จ ๊ฒ€์ƒ‰์„ ํ•ด์ค€๋‹ค.




offset

offset์€ ์กฐํšŒ ์‹œ์ ์„ ๊ณผ๊ฑฐ๋กœ ๋Œ๋ฆฌ๊ฒŒ ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์ด๋‹ค. ์ •ํ™•ํžˆ ๋งํ•˜๋ฉด "ํ˜„์žฌ ์‹œ๊ฐ„"์„ ํŠน์ • ์‹œ์ ์œผ๋กœ ๊ณ ์ •ํ•œ๋‹ค.
ํ•„ํ„ฐ ํ‘œํ˜„์‹ ๋ฐ”๋กœ ์˜ค๋ฅธํŽธ์— ๋ถ™์ผ ์ˆ˜ ์žˆ๋‹ค.

์ด๋Ÿฐ ์‹์œผ๋กœ ์“ฐ๋ฉด, ์ผ์ฃผ์ผ ์ „ ์‹œ์ ์„ ํ˜„์žฌ๋กœ ์žก๊ณ , ์ผ์ฃผ์ผ ์ „์—์„œ ๋˜ 30๋ถ„ ์ „๊นŒ์ง€์˜ ๋ฒ”์œ„๋ฅผ ์กฐํšŒํ•˜๊ฒŒ ๋œ๋‹ค.




Range Vector

PromQL ์ฟผ๋ฆฌ๋“ค์„ ๋ณด๋ฉด, ๋Œ€๊ด„ํ˜ธ ํ‘œํ˜„์‹์„ ์ž์ฃผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์‰ฝ๊ฒŒ ๋งํ•ด, ์‹œ๊ฐ„ ๋ฒ”์œ„ ํ•„ํ„ฐ ๊ฐ™์€ ๊ฑฐ๋‹ค.
์ด๊ฑด ๋‹จ๋…์œผ๋กœ ์‚ฌ์šฉ๋˜์ง€๋Š” ์•Š๊ณ , ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜๋Š” ์ง‘๊ณ„ ํ•จ์ˆ˜์— ๋”ฐ๋ผ์„œ ์ •ํ™•ํ•œ ๋™์ž‘ ๋ฐฉ์‹์ด ๋‹ฌ๋ผ์ง„๋‹ค.

์ €๊ธฐ์—” 5m๋‚˜ 30(์ดˆ ๋‹จ์œ„) ๊ฐ™์€ ์‹œ๊ฐ„ ๋‹จ์œ„ ๊ฐ’์„ ๋„ฃ๋Š”๋ฐ, incrase๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ์—๋Š” Grafana์˜ ์‹œ๊ฐ„ ํ•„ํ„ฐ๋ฅผ ์ ์šฉํ•˜๊ธธ ์›ํ•œ๋‹ค๋ฉด ํ•˜๋“œ์ฝ”๋”ฉํ•˜๋Š”๊ฒƒ๋ณด๋‹จ $__range ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ํŽธ๋ฆฌํ•˜๋‹ค.




increase ํ•จ์ˆ˜

range vector์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•œ๋‹ค.

range vector๋ฅผ [5m] ๊ฐ™์€ ์‹์œผ๋กœ ์ฃผ๋ฉด ํ˜„์žฌ ์‹œ์ ์—์„œ 5m ์ „๊นŒ์ง€์˜ ๋ฉ”ํŠธ๋ฆญ ๋ฐ์ดํ„ฐ๋งŒ์„ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์ด๋‹ค.

increase(http_server_request_duration_seconds_count{service_namespace="prod", service_name="...-API"}[5m])

๊ทธ๋Ÿฌ๋ฉด ํŠน์ • ๋ฒ”์œ„ ๋™์•ˆ์˜ ์ˆ˜์น˜ ์ฐจ์ด๋งŒ์„ ๊ฐ€์ ธ์˜จ๋‹ค.
์‘์šฉ ๋ฒ”์œ„๊ฐ€ ๋„“์€ ๊ธฐ๋ณธ ํ•จ์ˆ˜ ์ค‘ ํ•˜๋‚˜๋‹ค.




sum ํ•จ์ˆ˜

sum ํ•จ์ˆ˜๋Š” ๋ง ๊ทธ๋Œ€๋กœ ์ดํ•ฉ์„ ์ง‘๊ณ„ํ•˜๋Š” ํ•จ์ˆ˜๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ, ํ•จ์ˆ˜๋“ค์€ ๊ทธ๋ƒฅ ์ค‘๊ด„ํ˜ธ ํ•„ํ„ฐ์‹ ์œ„์— ๊ฐ์‹ธ๋Š” ํ˜•ํƒœ๋กœ๋„ ๊ฐ„๋‹จํ•˜๊ฒŒ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

sum(http_server_request_duration_seconds_count{service_namespace="prod", service_name="...-API"})

๊ทผ๋ฐ ์ด๋ ‡๊ฒŒ ๋ณด๋ฉด ์˜๋„ํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๊ธฐ์—” ์• ๋งคํ•˜๊ณ ,

Grafana Panel์„ Stat์œผ๋กœ ์“ฐ๋Š”๊ฒŒ ์ข€ ๋” ์ผ๋ฐ˜์ ์ด๋‹ค.

๊ทผ๋ฐ ์ด ์ƒํƒœ์—์„œ ์‹œ๊ฐ„ ๋ฒ”์œ„๋ฅผ ์กฐ์ ˆํ•˜๋ฉด์„œ ์ˆ˜์น˜๋ฅผ ํ™•์ธํ•ด๋ณด๋ฉด, ๋ญ”๊ฐ€ ์ด์ƒํ•œ๊ฒŒ ๋ˆˆ์— ๋ณด์ผ ๊ฒƒ์ด๋‹ค.
์™œ๋ƒํ•˜๋ฉด, sum์€ ํ˜„์žฌ ์‹œ๊ฐ„ ๋ฒ”์œ„๋ฅผ ๊ณ ๋ คํ•˜์ง€ ์•Š๊ณ  ํ‰์ƒ๋™์•ˆ ์Œ“์ธ ๊ฐœ์ˆ˜๋ฅผ ์ง‘๊ณ„ํ•˜๋Š” ํ•จ์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๊ทธ๋ž˜์„œ ํ˜„์žฌ ์‹œ๊ฐ„ ํ•„ํ„ฐ๋ฅผ ๊ณ ๋ คํ•ด์„œ

sum(increase(http_server_request_duration_seconds_count{service_namespace="prod", service_name="...-API"}[$__range]))




Group by

ํŠน์ • ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ๋ฌถ๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ ์ฟผ๋ฆฌ๋Š” span_name(API ์ด๋ฆ„)์„ ๊ธฐ์ค€์œผ๋กœ ๋ฉ”ํŠธ๋ฆญ์„ ๊ทธ๋ฃนํ™”ํ•œ๋‹ค.

sum(increase(http_server_request_duration_seconds_count{span_kind="SPAN_KIND_SERVER", service_name="$app", service_namespace="$env", http_route=~"$route"}[$__range])) by(span_name)

์ด๋Ÿฐ ๊ฒฝ์šฐ์—๋Š” chart ๊ณ„์—ด panel์ด ์ ํ•ฉํ•œ ํŽธ์ด๋‹ค.




rate

rate๋Š” ํŠน์ • ์‹œ๊ฐ„ ๋‹จ์œ„๋งˆ๋‹ค ๋ฉ”ํŠธ๋ฆญ์ด ๋ช‡๊ฐœ ์Œ“์˜€๋Š”์ง€๋ฅผ ๋น„์œจ๋กœ ์ธก์ •ํ•˜๋Š” ์ง‘๊ณ„ ํ•จ์ˆ˜๋‹ค. TPS ๊ฐ™์€ ๊ฒƒ์„ ํ‘œํ˜„ํ•˜๊ธฐ์— ๊ฐ€์žฅ ์ ํ•ฉํ•˜๋‹ค.
๋ณดํ†ต range vector์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฟผ๋ฆฌ๋ฅผ ์ง ๋‹ค๋ฉด

rate(http_server_request_duration_seconds_count{service_namespace="prod", service_name="...-API"}[1m])

1๋ถ„ ๋‚ด์— ๋ช‡๊ฑด์ง€ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€๋ฅผ ๋ฝ‘์•„๋‚ธ ๋‹ค์Œ์—, ์ดˆ๋‹น ๊ฐœ์ˆ˜๋ฅผ ์ถ”์ถœํ•œ๋‹ค.
1๋ถ„ ์•ˆ์— ์Œ“์ธ ๋ฉ”ํŠธ๋ฆญ์ด 120๊ฐœ๋ผ๋ฉด tps๋Š” 2๊ฐ€ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.


์ด์™ธ์—๋„ ํ•จ์ˆ˜๋“ค์€ ๊ฝค ๋งŽ๋‹ค. ๋ชจ๋“ ๊ฑธ ์—ฌ๊ธฐ์„œ ๋‹ค ๋‹ค๋ฃฐ ์ˆ˜๋Š” ์—†๊ณ  ๊ธฐ๋ณธ์ ์ธ ๊ฒƒ๋“ค๋งŒ ๋‹ค๋ค˜๋‹ค.
ํ•จ์ˆ˜๋“ค์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์›ํ•œ๋‹ค๋ฉด ๋ณ„๋„ ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜๊ธธ ๋ฐ”๋ž€๋‹ค.
https://prometheus.io/docs/prometheus/latest/querying/functions/


์ฐธ์กฐ
https://prometheus.io/docs/prometheus/latest/querying/basics/
https://prometheus.io/docs/prometheus/latest/querying/functions/