Skip to content

Instantly share code, notes, and snippets.

@umtdg
Created August 5, 2021 11:38
Show Gist options
  • Save umtdg/b08ed43208d14205fbd1d6254ecc952f to your computer and use it in GitHub Desktop.
Save umtdg/b08ed43208d14205fbd1d6254ecc952f to your computer and use it in GitHub Desktop.
Juju ile metric toplama

Juju ile Metric Toplama

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

metrics.yaml

Ö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çin
  • absolute: 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.

Hook collect-metrics

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.

Bozuk juju collect-metrics komutu

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.

Referanslar

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment