🐍Examining the data of our Python application
Yukarıdaki uygulama, Prometheus metriklerini kullanarak bir HTTP sunucusu başlatan basit bir uygulamadır. Uygulamanın detaylarına inecek olursak;
İlk olarak, gerekli modüller ve kütüphaneler içe aktarılır:
http.server
: Bu modül, temel bir HTTP sunucusu oluşturmak için kullanılır.prometheus_client
: Prometheus metriklerini yayınlamak için kullanılan bir kütüphanedir.
Ardından, uygulama ve metrikler için iki farklı port numarası belirlenir:
APP_PORT
: Uygulamanın dinleyeceği port numarası (8000).METRICS_PORT
: Prometheus metriklerinin yayınlanacağı port numarası (8001).
HandleRequests
adında bir sınıf tanımlanır. Bu sınıf,http.server.BaseHTTPRequestHandler
sınıfından türetilmiştir ve gelen HTTP isteklerini işlemek için kullanılır. Şu anda sadeceGET
isteklerini ele alacak şekilde tanımlanmıştır.do_GET
metodunda, sunucu, başarılı bir yanıt olarak200
durum kodunu gönderir. Daha sonra yanıtın içeriğine HTML metni ekler ve bağlantıyı kapatır. Bu HTML metni, kullanıcıya "Welcome to our first Prometheus-Python application." mesajını gösterir.__main__
içinde, metrikleri toplamak ve yayınlamak için Prometheus istemcisini başlatırız:start_http_server(METRICS_PORT)
.Daha sonra, HTTP sunucusunu başlatırız. Sunucunun IP adresi (
10.90.0.144
) ve uygulama portu (APP_PORT
) ilehttp.server.HTTPServer
sınıfından bir nesne oluştururuz. Bu nesneye, istekleri işlemek içinHandleRequests
sınıfını sağlarız.Son olarak,
server.serve_forever()
ile sunucuyu sürekli çalışır durumda tutarız. Bu sayede sunucu, gelen isteklere sürekli olarak yanıt verebilir.
Özetle, bu uygulama, temel bir HTTP sunucusu başlatır ve Prometheus istemcisi kullanarak metrikleri toplar ve yayınlar.
Uygulamamızı çalıştırıyoruz.
prometheus_client
paketi, uygulamalarımızda Prometheus metriklerini toplamamızı ve sunmamızı sağlayan bir kütüphanedir.
.
.
.
Ardından python uygulamamızı, prometheus arayüzünden metriklerini incelemek ve olası problemleri tespit etmek için, Uygulamamızın kodunda expose ettiğimiz metrik portunu prometheus.yml dosyasına target olarak ekliyoruz.
Ardından prometheus servisini yeniden başlatıp, arayüzden verinin kontrolünü sağlıyoruz.
Counter Metrics
Kodumuza, gelen istekleri inceleyebilmek için, bazı satırları ekliyoruz. Bu satırların açıklamaları şu şekilde,
random
modülü içe aktarıldı. Bu modül, rastgele sayılar üretmek için kullanılır.Prometheus istemcisinden
Counter
metriği içe aktarıldı. Counter, artan bir değeri temsil eden bir metrik türüdür.İki adet Counter metriği tanımlandı:
REQUEST_COUNT
: Uygulamanın aldığı HTTP isteklerinin sayısını takip eder. Bu metrik, 'app_name' ve 'endpoint' etiketleri ile etiketlendi.RANDOM_COUNT
: Rastgele bir değerle artırılan bir sayaçtır.
do_GET
metodunda, iki metrik güncellenir:İlk olarak,
REQUEST_COUNT
metriği etiketlerle birlikte artırılır (inc()
fonksiyonu ile). Bu, uygulamanın adı ve istek yolu ile etiketlenmiş her HTTP isteği için sayaç değerini bir artırır.Daha sonra,
random.random()
fonksiyonu kullanılarak 0 ile 1 arasında rastgele bir sayı üretiliyor. Bu sayıyı 10 ile çarparak 0 ile 10 arasında rastgele bir sayı elde ediyoruz. Bu değerrandom_val
adlı değişkene atanıyor.Ardından,
RANDOM_COUNT.inc(random_val)
satırında,RANDOM_COUNT
adında bir Prometheus Counter nesnesi bulunuyor. Counter, artan sayıları tutmak için kullanılır ve genellikle bir uygulamada gerçekleşen belirli olayların sayısını izlemek için kullanılır. Bu örnekte,RANDOM_COUNT
adlı Counter nesnesineinc()
fonksiyonu ilerandom_val
değişkeninde tutulan rastgele değeri ekliyoruz. Bu, Counter nesnesinin değerinirandom_val
kadar artırır.
Yeni eklenen kod parçaları sayesinde, uygulamanın aldığı HTTP istek sayısını ve rastgele değerlerle artan bir sayacı takip etmek mümkün hale gelmiştir. Bu metrikler, Prometheus tarafından toplanarak uygulamanın performansı ve işlem sayısı hakkında daha fazla bilgi sağlar.
Uygulamamıza ilgili satırları ekledikten sonra tekrar start ediyoruz ve prometheus ara yüzünde yeni verileri inceliyoruz.
Böylelikle uygulamamıza yapılan isteklerin miktarını görebiliyoruz.
.
.
.
Gauge Metrics
Gauge metrikleri, bir değeri artırabilen, azaltabilen veya belirli bir değere ayarlayabilen metriklerdir. Bu kod parçasında iki Gauge metrik tanımlanmıştır:
REQUEST_INPROGRESS: Bu metrik, şu anda işlenmekte olan uygulama isteklerinin sayısını temsil eder. 'app_requests_inprogress' adıyla ve 'number of application requests in progress' açıklamasıyla tanımlanmıştır.
REQUEST_LAST_SERVED: Bu metrik, uygulamanın en son ne zaman hizmet verdiğini gösterir. 'app_last_served' adıyla ve 'Time the application was last served.' açıklamasıyla tanımlanmıştır.
İlk Gauge metriği, REQUEST_INPROGRESS
, do_GET
fonksiyonu için bir dekoratör olarak kullanılır. Bu sayede, fonksiyonun başında ve sonunda otomatik olarak Gauge değeri güncellenir. Bu, işlem süresi boyunca kaç isteğin olduğunu takip etmeye yardımcı olur.
İkinci Gauge metriği, REQUEST_LAST_SERVED
, do_GET
fonksiyonunun sonunda kullanılır. Uygulamanın en son ne zaman hizmet verdiğini belirlemek için şu anki zamanı bu metriğe ayarlar.
Bu ölçümler sayesinde, uygulamanın performansını ve kullanımını daha iyi anlayabilir ve gerektiğinde iyileştirmeler yapabilirsiniz.
.
.
.
Summary Metrics
Yukarıda summary metriğini tanımladığımız kod bloğu mevcut. Uygulama kodumuza eklediğimiz 2 farklı satır mevcut. Bu satırları açıklamak gerekirse;
Summary
metriği tanımlama:
Bu satırda, Summary
tipinde bir metrik nesnesi oluşturuyoruz. Summary
metriği, gözlem süresi boyunca olayların sürelerinin veya boyutlarının istatistiksel özetini sağlar. Burada, app_response_latency_seconds
adında bir metrik tanımlıyoruz ve bu metriğin açıklaması olarak "Response latency in seconds" kullanıyoruz.
time()
dekoratörünü kullanma:
time()
dekoratörü, Python'daki dekoratörlerle ilgilidir. Dekoratörler, fonksiyonların veya sınıf metotlarının davranışını değiştirmek veya genişletmek için kullanılır. Bu örnekte, time()
dekoratörü do_GET
metodu üzerinde kullanılarak, metot çalıştığında süre ölçümü yapılır ve sonuçlar REQUEST_RESPOND_TIME
metriğine kaydedilir.
Dekoratörler, fonksiyonun veya metotun üzerinde @
işareti ile belirtilir. Bu sayede, dekoratörün arkasındaki fonksiyon veya metot, dekoratörün sağladığı ek özelliklerle çalışır. Bu durumda, time()
dekoratörü do_GET
metodunun çalışma süresini ölçer ve bu süreyi REQUEST_RESPOND_TIME
metriğine ekler.
Özetle, REQUEST_RESPOND_TIME = Summary(...)
satırıyla, süre ölçümlerini tutmak için bir Summary
metriği tanımlıyoruz. @REQUEST_RESPOND_TIME.time()
satırıyla ise, bu metriği kullanarak do_GET
metodunun çalışma süresini ölçüyoruz. Bu sayede, uygulamanın yanıt süresi hakkında istatistiksel özetler elde ederiz.
@REQUEST_RESPOND_TIME.time()
kod parçacığı, asıl olarak süre ölçümünü yapmak ve bu süreyi REQUEST_RESPOND_TIME
metriğine kaydetmekle ilgilidir. Bu dekoratör, kodun üzerine yerleştirildiği do_GET
metodu çalıştığında, metodu çalıştıran işlemi otomatik olarak ölçer ve bu süreyi REQUEST_RESPOND_TIME
metriğine ekler.
Sonuç olarak, bu dekoratör sayesinde uygulamanın yanıt süresi ölçümleri, Prometheus tarafından toplanarak analiz edilebilir ve izlenebilir hale gelir
Kodumuza 6 saniye gecikmesi için "sleep" eklediğimiz için, ilk isteğin response süresi "6 sn" olarak gözüküyor. Fakat bu değişken sürekli toplanarak ilerlediği için, ortalama response süresini incelememiz için bize yardımcı olmaz.
Ortalama yanıt süresini hesaplamak için,
rate(app_response_latency_seconds_sum[5m])
: Son 5 dakika içindekiapp_response_latency_seconds_sum
metriğinin değerinin artış hızını hesaplar. Bu, son 5 dakika boyunca toplam sürelerin ne kadar hızla arttığını gösterir.rate(app_response_latency_seconds_count[5m])
: Son 5 dakika içindekiapp_response_latency_seconds_count
metriğinin değerinin artış hızını hesaplar. Bu, son 5 dakika boyunca toplam istek sayısının ne kadar hızla arttığını gösterir.Son olarak, bu iki değeri böleriz.
Bu bölme işlemi, son 5 dakika içindeki ortalama yanıt süresini verir. Ortalama yanıt süresi, toplam sürelerin artış hızının, istek sayısının artış hızına oranı olarak hesaplanır. Bu sayede, son 5 dakikada gerçekleşen isteklerin ortalama süresini görebilirsiniz.
rate
fonksiyonu şu şekilde çalışır:
rate
fonksiyonu, belirtilen zaman aralığı (örneğin, son 5 dakika) boyunca metrik değerinin zaman serisindeki veri noktalarını alır.İki ardışık veri noktası arasındaki farkı alarak, her bir veri noktası arasındaki değişimi hesaplar.
Bu değişimlerin toplamını alır ve belirtilen zaman aralığına böler (örneğin, 5 dakika). Bu işlem, zaman aralığı boyunca metrik değerindeki ortalama değişimi hesaplar.
Örneğin, rate(app_response_latency_seconds_count[5m])
sorgusu için:
Son 5 dakikadaki
app_response_latency_seconds_count
metriği için veri noktalarını alır.İki ardışık veri noktası arasındaki farkı alarak, her bir veri noktası arasındaki değişimi hesaplar.
Bu değişimlerin toplamını alır ve 5 dakikaya böler. Bu işlem, son 5 dakika içinde işlenen istek sayısının ortalama artış hızını hesaplar.
Sonuç olarak, rate(app_response_latency_seconds_count[5m])
sorgusu, son 5 dakika içinde işlenen istek sayısının ortalama artış hızını döndürür.
.
.
.
Histogram Metrics
Yukarıdaki kod parçacığı, Prometheus için Histogram metrik türü kullanarak uygulamanın HTTP isteklerine verdiği yanıt sürelerini ölçmektedir. Histogram metrikleri, belirli bir değer aralığında meydana gelen olayların sayısını ölçen ve bu olayları belirli "kova" (bucket) adı verilen aralıklara göre gruplandıran metriklerdir.
Kod parçacığında, Histogram metriği şu şekilde tanımlanmaktadır:
app_response_latency_seconds
: Histogram metriğinin adıdır.'Response latency in seconds'
: Histogram metriğinin açıklamasıdır.buckets=[0.1,0.5,1,2,3,4,5,10]
: Histogram için tanımlanan kova sınırlarıdır. Bu, yanıt sürelerini şu aralıklara göre gruplandıracaktır: <= 0.1s, <= 0.5s, <= 1s, <= 2s, <= 3s, <= 4s, <= 5s, <= 10s ve > 10s.
Histogram metriği kullanarak yanıt sürelerini ölçmek için, HandleRequests
sınıfındaki do_GET
metodunda histogram metriğini şu şekilde kullanılıyor:
Bu dekoratör, do_GET
metodunun çalışma süresini ölçer ve bu süreyi REQUEST_RESPOND_TIME
histogramına göre ilgili kovalara dağıtır.
Sonuç olarak, bu kod parçacığı, bir web sunucusu başlatır ve gelen HTTP isteklerine yanıt verir. Aynı zamanda, Prometheus için bir Histogram metrik türü kullanarak yanıt sürelerini ölçer ve bu süreleri belirli kova aralıklarına göre gruplandırır. Bu sayede, uygulamanın yanıt sürelerini daha iyi anlayabilir ve performansını izleyebilirsiniz.
app_response_latency_seconds_bucket{le="+Inf"}
ifadesi, Prometheus tarafından histogram metriği için otomatik olarak oluşturulan özel bir kova (bucket) etiketini temsil eder. Bu özel kova, belirtilen kova sınırlarının üstünde olan tüm ölçüm değerlerini toplar.
le
etiketi "less than or equal to" (eşit veya küçük) anlamına gelir ve +Inf
(artı sonsuz) değeri, bu kovanın belirtilen tüm diğer kova sınırlarının üstünde olan değerleri toplayacağını gösterir.
Örneğin, histogram metriği için kova sınırları şu şekilde tanımlanmış olsaydı: buckets=[0.1,0.5,1,2,3,4,5,10]
, app_response_latency_seconds_bucket{le="+Inf"}
kovası, 10 saniyeden fazla süren tüm yanıt sürelerini toplayacak.
Soru 1 => bütün bucket değerleri eşit ilerliyor. Tüm istekler nasıl aynı anda bütün bucketlara eşit oluyor?
Cevap => Bu durum, örnek uygulamanızdaki tüm isteklerin 2.0 saniyeden daha kısa sürede tamamlandığını göstermektedir. Histogram metriğinin çalışma şekli nedeniyle, herhangi bir istek süresi, o süreden daha büyük veya eşit olan tüm le
değerlerine sahip bucket'lara dahil edilir.
Örneğin, bir isteğin süresi 1.5 saniye olsun. Bu durumda, histogram metriği şu şekilde güncellenir:
2.0 saniyeden daha kısa olduğu için
app_response_latency_seconds_bucket{le="2.0"}
değerini artırır.5.0 saniyeden daha kısa olduğu için
app_response_latency_seconds_bucket{le="5.0"}
değerini artırır.10.0 saniyeden daha kısa olduğu için
app_response_latency_seconds_bucket{le="10.0"}
değerini artırır.Sonsuz saniyeden daha kısa olduğu için
app_response_latency_seconds_bucket{le="+Inf"}
değerini artırır.
Eğer tüm istekler 2.0 saniyeden daha kısa sürede tamamlanırsa, bu durumda tüm bu bucket'lar eşit değerlerle artacaktır. Bu, gözlemlediğiniz durumdur. İstek sürelerinin dağılımını daha iyi görmek için, uygulamanızdaki time.sleep()
fonksiyonuyla rastgele bekleme sürelerini değiştirebilirsiniz. Örneğin, süreleri 0.1 ile 10 arasında rastgele seçerseniz, farklı bucket'larda farklı sayılar görmeye başlarsınız.
Last updated