Juju ile metric toplamak için 2 şeye ihtiyacımız var:
- Charm'ın metricleri tanıması için metrics.yaml dosyası
- Metricleri toplamak için 5 dakika aralıklarla çalışan collect-metrics hook'u
Örnek bir metrics.yaml:
metrics:
cpu_util:
type: gauge # Zorunlu
description: İşlemci kullanım yüzdesi # Zorunlu
mem_free:
type: gauge
description: Serbest RAM yüzdesi
type
bölümüne iki farklı değer verebiliriz:
gauge
: Anlık değer okumak içinabsolute
: Son ölçümden bu yana değerleri takip etmek için
Ek olarak, type
ve description
alanları dışında Juju command
alanı da kabul etmekte. Ancak son sürümde bu alanın metric toplarken bir etki etmediği gözlemlenmiştir.
collect-metrics
hook'u Juju tarafından 5 dakika aralıklarla çalıştırılır. Charm kodunda bu hook çalıştırıldığında on.collect-metrics
event'i tetiklenir. Bu event'in davranışını değiştirerek metric toplayabiliriz.
Örnek event aşağıdaki gibidir (Charm sınıfının içerisinde):
def on_collect_metrics(self, event):
mem_free = get_metric("free | grep Mem | awk '{print 100*$3/$2}'")
cpu_util = get_metric("top -b -n2 | grep \"Cpu(s)\"|tail -n 1 | awk '{print $2 + $4}'")
logger.debug(f"Free memory: {mem_free}")
logger.debug(f"Cpu utilization: {cpu_util}")
event.add_metrics({"mem_free": int(mem_free), "cpu_util": int(cpu_util)})
get_metric
:
def get_metric(cmd: str) -> float:
out = subprocess.check_output(cmd, shell=True)
out = out.decode("utf-8").strip()
return float(out)
on_collect_metrics
fonksiyonunu register etmek için Charm sınıfının __init__
fonksiyonu içerisinde:
self.framework.observe(self.on.collect_metrics, self.on_collect_metrics)
on_collect_metrics
fonksiyonunun içerisinde bizim için önemli olan yer
event.add_metrics({"mem_free": int(mem_free), "cpu_util": int(cpu_util)})
kısmıdır. add_metrics
fonksiyonu parametre olarak dict
alır. Bu dict
içerisindeki her key, metrics.yaml
içerisinde tanımladığımız metric'e denk gelir ve dict
içerisindeki her value ise alınan metric'in değiridir. add_metrics
methodu verdiğimiz key:value eşlerine göre Juju'ya metric ekliyor, böylelikle metricleri görebiliyoruz.
Önemli not: Eğer dikkat ettiyseniz, add_metrics
fonksiyonuna metricleri verirken, metric değerleri integer'a çevriliyor. Bunun nedeni, float verildiğinde (virgülden sonra kaç basamak olduğu önemli değil) değer Juju'ya giderken virgülden sonraki kısım bozuluyor. Örneğin değer 1.29 ise, Juju'ya 1.2899999999999999999999999999999999999999... (9'lardan sonra rastgele rakamlar geliyor) olarak gidiyor. Bundan dolayı iste Juju
ERROR cannot record metric: metric value is too large
hatası veriyor.
Not: Bu şekilde metric topladığımızda charm ilk deploy edildiğinde metric değerleri alamıyoruz. Ancak 5 dakika sonra Juju tekrar otomatik olarak collect-metrics
hook'unu çağırdığı zaman metriclerin geldiğini
juju metrics <app-name>
veya unit için
juju metrics <app-name>/<unit-number>
veya bütün metricler için
juju metrics --all
ile görebiliyoruz.
Juju'nun içerisinde el ile collect-metrics
hook'unu tetiklemek için collet-metrics
komutu bulunmakta. Bu komut çalıştırıldığında on_collect_metrics
event'i tetikleniyor. Charm'ın içerisinde karşılık gelen kod çalışıyor, ancak Juju'ya metric eklenmiyor ve
failed to collect metrics: could not read stdout
çıktısı geliyor.
- (Eski) Metric collecting charms (
metrics.yaml
dosyası için) - Charm hooks (
collect-metrics
hook'u için) - Collect Metrics Event (
on_collect_metrics
veadd-metrics
için)