Akademik Bilişim 2017 Gnu/Linux sistemler için Python - 3. Gün


        Akademik Bilişim 2017'deki üçüncü günün başında dün yapılan uygulamayı yazıp günün sonuna doğru her adımda daha doğru ve daha temiz bir kod haline getirdik. Bu uygulamanın amacı kullanıcıyı CPU ve RAM kullanımı hakkında uyarmak. Uygulamada getopt ve argparse modüllerini kullandık. Son olarak da logging modülü ile log işlemlerini uygulmamıza ekledik.

Uygulamadan istenen özellikler:
  • Kullanıcıya CPU, RAM veya her ikisi seçeneklerinden hangisi için uyarı alınacağı sorulsun.
  • CPU ise uyarı yüzdesi ve kritik değeri en az kaç olsun?
  • RAM ise uyarı yüzdesi ve kritik değeri en az kaç olsun?
  • Kullanıcıya çıktıların dosya yolu, stdout, stderr seçeneklerinden hangisine verileceği sorulsun?
  • Kullanıcı 'Ctrl + C' yaptığında "Çıkmak istediğinize emin misiniz?" diye sorulsun ve 'e' cevabı aldığında uygulamadan çıkılsın.
  • CPU ve RAM için iki yüzde alınsın ve düşük olan yüzde stdout'a yüksek olan yüzde ise stderr'e yazılsın.

uygulama.py:
import os
import signal
import sys
import psutil

def safe_input(prompt=None):
    try:
        return input(prompt)
    except KeyboardInterrupt:
        print()
        exit(0)

mode = safe_input("Warn for [C]pu, [R]am, [A]ll (default: A): ").lower()
if mode not in "car":
    print("Unknown Mode", file=sys.stderr)
    exit(1)
elif not mode:      # boş string gelmişse varsayılan olarak 'a' kabul et
    mode = "a"

if mode in "ca":
    cpu_warn = safe_input("Warning level for CPU (defaut: None): ")      # CPU'nun uyarı değerini alır
    if cpu_warn and not cpu_warn.isdigit():     # isdigit(): Sayı olup olmadığını kontrol eder
        print("Unknown Level", file=sys.stderr)
        exit(2)
    elif cpu_warn:
        cpu_warn = int(cpu_warn)
    else:
        cpu_warn = None

    cpu_crit = safe_input("Critic level for CPU (defaut: 80): ")
    if cpu_crit and not cpu_crit.isdigit():
        print("Unknown Level", file=sys.stderr)
        exit(2)
    elif cpu_crit:
        cpu_crit = int(cpu_crit)
    else:
        cpu_crit = 80

if mode in "ra":
    ram_warn = safe_input("Warning level for RAM (defaut: None): ")
    if ram_warn and not ram_warn.isdigit():
        print("Unknown Level", file=sys.stderr)
        exit(2)
    elif ram_warn:
        ram_warn = int(ram_warn)
    else:
        ram_warn = None

    ram_crit = safe_input("Critic level for RAM (defaut: 60): ")
    if ram_crit and not ram_crit.isdigit():
        print("Unknown Level", file=sys.stderr)
        exit(2)
    elif ram_crit:
        ram_crit = int(ram_crit)
    else:
        ram_crit = 60

warn_out = safe_input("Warning output [file path, stdout, stderr] (default:'/dev/null'): ").lower()
if os.path.exists(warn_out) and os.path.isfile(warn_out):
    try:
        warn_out = open(warn_out, "w")
    except:
        print("Unable to open file {}".format(warn_out), file=sys.stderr)
        exit(3)
elif warn_out == "stdout":
    warn_out = sys.stdout
elif warn_out == "stderr":
    warn_out = sys.stderr
else:
    warn_out = open(os.devnull, "w")

crit_out = safe_input("Critical output [file path, stdout, stderr] (default:stdout): ").lower()
if os.path.exists(crit_out) and os.path.isfile(crit_out):
    try:        # kullanıcı dosya yolu verirse bunu açmaya çalışır, açamazsa hata verir
        crit_out = open(crit_out, "w")
    except:
        print("Unable to open file {}".format(crit_out), file=sys.stderr)
        exit(3)
elif crit_out == "stdout":
    crit_out = sys.stdout
elif crit_out == "stderr":
    crit_out = sys.stderr
else:
    crit_out = sys.stdout

resolution = safe_input("Reading resolution (default:0.5): ")      # okumuak için araya konulan zaman
if resolution:
    try:
        resolution = float(resolution)
    except ValueError:
        print("Invalid resolution {}".format(resolution))
        exit(4)
else:
    resolution = 0.5

# bayraklar: döngülerde kullanılan belirli bir işlemi kontrol etmek için kullanılan araçlar
wait = False    # wait false ise döngüden çıkar, true ise devam eder

def handle_sigint(sig, stack):      # sinyal fonksiyonu
    global wait         # yapılan değişiklikler her wait değişkeni için geçerlidir
    wait = True
    choice = safe_input("\rAre you sure you want to exit? (y/N)").lower()  # \r: ^C görünmesin diye imleci geri alır
    if choice == "y":
        exit(0)
    else:
        wait = False

signal.signal(signal.SIGINT, handle_sigint)

while True:
    if wait:
        time.sleep(0.1)
        continue
    if mode in "ca":
        cpu_reading = max(psutil.cpu_percent(resolution, percpu=True))
        if cpu_reading > cpu_crit:
            print("CPU kullanımı kritik", file=crit_out)
        elif cpu_warn is not None and cpu_reading > cpu_warn:
            print("CPU kullanımı yüksek", file=warn_out)
    if mode in "ra":
        ram_reading = psutil.virtual_memory().percent
        if ram_reading > ram_crit:
            print("RAM kullanımı kritik", file=crit_out)
        elif ram_warn is not None and ram_reading > ram_warn:
            print("RAM kullanımı yüksek", file=warn_out)
    time.sleep(resolution)

Bu uygulamadaki problemler:
  • Kullanıcıdan giriş yapması bekleniyor.
  • Kullanıcıdan gelen girişi kontrol etmeye çalışıyor.
        Bu tür betikler kullanıcıdan giriş almamalıdır. Bunun yerine terminalden argüman alması daha doğru olur. Bunun için bir fonksiyon yazarak input() ile girdi alınan yerlerin yerine ekliyoruz. Daha sonra varsayılan değerleri yazdığımız fonksiyona parametre olarak ekleyerek bir koşuldan kurtulmuş oluyoruz. Uygulamanın düzenlenmiş son hali:
uygulama.py:
import os
import signal
import sys
import psutil

if "--help" in sys.argv:
    print("2. gün uygulama kullanım talimatları\n"
          "  --help Shows this help\n"
          "  --mode=       Warn for [C]pu, [R]am, [A]ll (default: A)\n"
          "  --cpu_warn=   Warning level for CPU (defaut: None)\n"
          "  --cpu_crit=   Warning level for CPU (defaut: 80)\n"
          "  --ram_warn=   Warning level for RAM (defaut: None)\n"
          "  --ram_crit=   Warning level for RAM (defaut: 60)\n"
          "  --warn_out=   Warning output [file path, stdout, stderr] (default:'/dev/null')\n"
          "  --crit_out=   Critical output [file path, stdout, stderr] (default:stdout)\n"
          "  --resolution= Reading resolution (default:0.5)\n"
          )
    exit(0)

def getarg(name, default=""):
    for arg in sys.argv:
        if arg.startswith(name) and "=" in arg:
            return arg.split("=")[1]
    else:
        return default

mode = getarg("--mode", default="a").lower()
#mode = safe_input("Warn for [C]pu, [R]am, [A]ll (default: A): ").lower()
if mode not in "car":
    print("Unknown Mode", file=sys.stderr)
    exit(1)

if mode in "ca":
    cpu_warn = getarg("--cpu_warn", default=None)
    #cpu_warn = safe_input("Warning level for CPU (defaut: None): ")      # CPU'nun uyarı değerini alır
    if cpu_warn and not cpu_warn.isdigit():     # isdigit(): Sayı olup olmadığını kontrol eder
        print("Unknown Level", file=sys.stderr)
        exit(2)
    elif cpu_warn:
        cpu_warn = int(cpu_warn)

    cpu_crit = getarg("--cpu_warn", default="80")
    #cpu_crit = safe_input("Critic level for CPU (defaut: 80): ")
    if cpu_crit and not cpu_crit.isdigit():
        print("Unknown Level", file=sys.stderr)
        exit(2)
    elif cpu_crit:
        cpu_crit = int(cpu_crit)

if mode in "ra":
    ram_warn = getarg("--ram_warn", default=None)
    #ram_warn = safe_input("Warning level for RAM (defaut: None): ")
    if ram_warn and not ram_warn.isdigit():
        print("Unknown Level", file=sys.stderr)
        exit(2)
    elif ram_warn:
        ram_warn = int(ram_warn)

    ram_crit = getarg("--ram_crit", default="60")
    #ram_crit = safe_input("Critic level for RAM (defaut: 60): ")
    if ram_crit and not ram_crit.isdigit():
        print("Unknown Level", file=sys.stderr)
        exit(2)
    elif ram_crit:
        ram_crit = int(ram_crit)

warn_out = getarg("--warn_out", default=os.devnull)
#warn_out = safe_input("Warning output [file path, stdout, stderr] (default:'/dev/null'): ").lower()
if os.path.exists(warn_out) and os.path.isfile(warn_out):
    try:
        warn_out = open(warn_out, "w")
    except:
        print("Unable to open file {}".format(warn_out), file=sys.stderr)
        exit(3)
elif warn_out == "stdout":
    warn_out = sys.stdout
elif warn_out == "stderr":
    warn_out = sys.stderr

crit_out = getarg("--crit_out", "stdout")
#crit_out = safe_input("Critical output [file path, stdout, stderr] (default:stdout): ").lower()
if os.path.exists"stdout":
    crit_out = sys.stdout
elif crit_out == "stderr":
    crit_out = sys.stderr

resolution = getarg("--resolution", default="0.5")
#resolution = safe_input("Reading resolution (default:0.5): ")        # okumuak için araya konulan zaman
if resolution:
    try:
        resolution = float(resolution)
    except ValueError:
        print("Invalid resolution {}".format(resolution))
        exit(4)

# bayraklar: döngülerde kullanılan belirli bir işlemi kontrol etmek için kullanılan araçlar
wait = False    # wait false ise döngüden çıkar, true ise devam eder

def handle_sigint(sig, stack):      # sinyal fonksiyonu
    global wait         # yapılan değişiklikler her wait değişkeni için geçerlidir
    if wait:
        print()
        exit(20)
    wait = True
    choice = input("\rAre you sure you want to exit? (y/N)").lower()        # \r: ^C görünmesin diye imleci geri alır
    if choice == "y":
        exit(0)
    else:
        wait = False

signal.signal(signal.SIGINT, handle_sigint)

while True:
    if wait:
        time.sleep(0.1)
        continue
    if mode in "ca":
        cpu_reading = max(psutil.cpu_percent(resolution, percpu=True))
        if cpu_reading > cpu_crit:
            print("CPU kullanımı kritik", file=crit_out)
        elif cpu_warn is not None and cpu_reading > cpu_warn:
            print("CPU kullanımı yüksek", file=warn_out)
    if mode in "ra":
        ram_reading = psutil.virtual_memory().percent
        if ram_reading > ram_crit:
            print("RAM kullanımı kritik", file=crit_out)
        elif ram_warn is not None and ram_reading > ram_warn:
            print("RAM kullanımı yüksek", file=warn_out)
    time.sleep(resolution)
Bu uygulmayı artık:
$ python3 uygulama.py     diyerek varsayılan ayarlarıyla çalıştırabiliriz.

        Uygulama daha düzenli bir hale gelmiş olsa da hala yönetilmesi biraz zor. Bunun için getopt modülü kullanarak daha düzenli bir uygulama kodu elde edebiliriz.

getopt Modülü:
        Bu method, komut satırı seçeneklerini ve parametre listesini ayrıştırır. Kullanımı:

getopt.getopt(args, options, [long_options])

Parametrelerin ayrıntısı:
  • args: Ayrıştırılacak (parse edilecek) argüman listesi
  • options: Komut dosyasının tanımak istediği seçenek harfler dizesidir; bağımsız değişken gerektiren seçeneklerin ardından iki nokta üst üste (:) bulunur.
  • long_options: Bu isteğe bağlı parametredir ve belirtilirse, desteklenmesi gereken uzun seçeneklerin adları içeren dizelerin listesi olmalıdır. Bir argüman gerektiren uzun seçenekler, eşittir işareti ('=') ile izlenmelidir. Yalnızca uzun seçenekleri kabul etmek için, boş bir dize olmalıdır.
        Bu method, iki öğeden oluşan değeri döndürür: birincisi (option, değer) çiftlerinin bir listesi. İkincisi ise, option listesi kaldırıldıktan sonra kalan program değişkenlerinin listesi.

getopt_mod.py:
import getopt
import sys

opts, _ = getopt.getopt(sys.argv[1:], 'hi:', ["help", "x="])
# kısa argümanlar:  h / i: i yanına bir değer alır ama arada bir boşluk olacak
# uzun argümanlar: "help" / "x" yanına bir değer alır ama arada = olmalı
opts = dict(opts)

if "--help" in opts or "-h" in opts:
    print("Kullanım: (-h --help) --x= -i ")
    exit(0)

deger = opts.get("--x", "")
tekrar = int(opts.get("-i", 0))

for j in range(tekrar):
    print(deger)
Bu modülü kullanarak uygulamamızı tekrar güncellendiğinde oluşan kod:

uygulama.py:
import getopt
import os
import signal
import sys
import psutil
import time

# def safe_input(prompt=None):
#     try:
#         return input(prompt)
#     except KeyboardInterrupt:
#         print()
#         exit(0)

try:
    opts, _ = getopt.getopt(sys.argv[1:], 'hq:w:e:r:t:y:u:o',
                            ["help", "mode=", "cpu_warn=", "cpu_crit=", "ram_warn=",
                             "ram_crit=", "warn_out=", "crit_out=", "resolution="])
except getopt.GetoptError as e:
    print(e, file=sys.stderr, flush=True)
    exit(1)

opts = dict(opts)

if "--help" in opts or "-h" in opts:
    print("2. gün Etüt kullanım talimatları\n"
          "  --help -h        Shows this help\n"
          "  --mode= -q       Warn for [C]pu, [R]am, [A]ll (default: A)\n"
          "  --cpu_warn= -w   Warning level for CPU (defaut: None)\n"
          "  --cpu_crit= -e   Warning level for CPU (defaut: 80)\n"
          "  --ram_warn= -r   Warning level for RAM (defaut: None)\n"
          "  --ram_crit= -t   Warning level for RAM (defaut: 60)\n"
          "  --warn_out= -y   Warning output [file path, stdout, stderr] (default:'/dev/null')\n"
          "  --crit_out= -u   Critical output [file path, stdout, stderr] (default:stdout)\n"
          "  --resolution= -o Reading resolution (default:0.5)\n"
          "Örnek kullanımlar:\n"
          "  python3 odev.py --mode=c -e 90 --resolution=0.1\n"
          "  python3 odev.py -q r -t 80 --resolution=1.5\n"
          )
    exit(0)

mode = opts.get("--mode", opts.get("-q", "a")).lower()
# mode = safe_input("Warn for [C]pu, [R]am, [A]ll (default: A): ").lower()
if mode not in "car":
    print("Unknown Mode {}".format(mode), file=sys.stderr)
    exit(1)

if mode in "ca":
    cpu_warn = opts.get("--cpu_warn", opts.get("w", None))
    # cpu_warn = safe_input("Warning level for CPU (defaut: None): ")
    if cpu_warn and not cpu_warn.isdigit():
        print("Unknown Level", file=sys.stderr)
        exit(2)
    elif cpu_warn:
        cpu_warn = int(cpu_warn)

    cpu_crit = opts.get("--cpu_crit", opts.get("e", "80"))
    # cpu_crit = safe_input("Warning level for CPU (defaut: 80): ")
    if cpu_crit and not cpu_crit.isdigit():
        print("Unknown Level", file=sys.stderr)
        exit(2)
    elif cpu_crit:
        cpu_crit = int(cpu_crit)
    else:
        cpu_crit = 80

if mode in "ra":
    ram_warn = opts.get("--ram_warn", opts.get("r", None))
    # ram_warn = safe_input("Warning level for RAM (defaut: None): ")
    if ram_warn and not ram_warn.isdigit():
        print("Unknown Level", file=sys.stderr)
        exit(2)
    elif ram_warn:
        ram_warn = int(ram_warn)

    ram_crit = opts.get("--ram_crit", opts.get("t", "60"))
    # ram_crit = safe_input("Warning level for RAM (defaut: 60): ")
    if ram_crit and not ram_crit.isdigit():
        print("Unknown Level", file=sys.stderr)
        exit(2)
    elif ram_crit:
        ram_crit = int(ram_crit)

warn_out = opts.get("--warn_out", opts.get("y", os.devnull))
# warn_out = safe_input("Warning output [file path, stdout, stderr] (default:'/dev/null'): ").lower()
if os.path.exists(warn_out) and os.path.isfile(warn_out):
    try:
        warn_out = open(warn_out, "w")
    except:
        print("Unable to open file {}".format(warn_out), file=sys.stderr)
        exit(3)
elif warn_out == "stdout":
    warn_out = sys.stdout
elif warn_out == "stderr":
    warn_out = sys.stderr

crit_out = opts.get("--crit_out", opts.get("u", "stdout"))
# crit_out = safe_input("Critical output [file path, stdout, stderr] (default:stdout): ").lower()
if os.path.exists(crit_out) and os.path.isfile(crit_out):
    try:
        crit_out = open(crit_out, "w")
    except:
        print("Unable to open file {}".format(crit_out), file=sys.stderr)
        exit(3)
elif crit_out == "stdout":
    crit_out = sys.stdout
elif crit_out == "stderr":
    crit_out = sys.stderr

resolution = opts.get("--resolution", opts.get("o", 0.5))
# resolution = safe_input("Reading resolution (default:0.5): ")
if resolution:
    try:
        resolution = float(resolution)
    except ValueError:
        print("Invalid resolution {}".format(resolution))
        exit(4)

wait = False

def handle_sigint(sig, stack):
    global wait
    if wait:
        print()
        exit(20)
    wait = True
    choice = input("\rAre you sure you want to exit? (y/N)").lower()
    if choice == "y":
        exit(0)
    else:
        wait = False

signal.signal(signal.SIGINT, handle_sigint)

while True:
    if wait:
        time.sleep(0.1)
        continue
    if mode in "ca":
        cpu_reading = max(psutil.cpu_percent(resolution, percpu=True))
        if cpu_reading > cpu_crit:
            print("CPU kullanımı kritik", file=crit_out)
        elif cpu_warn is not None and cpu_reading > cpu_warn:
            print("CPU kullanımı yüksek", file=warn_out)
    if mode in "ra":
        ram_reading = psutil.virtual_memory().percent
        if ram_reading > ram_crit:
            print("RAM kullanımı kritik", file=crit_out)
        elif ram_warn is not None and ram_reading > ram_warn:
            print("RAM kullanımı yüksek", file=warn_out)
    time.sleep(resolution)

argparse Modülü:
        Komut satırı seçenekleri, argümanları ve alt-komutlar için düzenlenmiş bir modüldür. Modülün amacı; komut satırı arabirimlerini daha kolay ve anlaşılır yazmaktır. Gereken argümanlar belirlendikten sonra, argparse modülü sys.argv'den bunları nasıl alacağını belirler. Otomatik olarak kullanım ve yardım menüleri oluşturabilir ve kullanıcılar programa geçersiz argümanlar verirse uygun hata mesajlarını gösterebilir.

Bu modülü kullanarak uygulamanın son haline gelmiş olduk:

uygulama.py:
import getopt
import os
import signal
import sys
import psutil
import argparse
import time

def file_or_stdio(arg):
    """This is a validator to open files for writing or opening stdio"""
    if os.path.exists(arg) and os.path.isfile(arg):
    # .exists(): dizinin var olup olmadığına bakar, .isfile(): dosya olup olmadığına bakar
        try:
            arg = open(arg, "w")
        except:
            argparse.ArgumentTypeError("Unable to open file {}".format(arg))
    elif arg.lower() == "stdout":
        arg = sys.stdout
    elif arg.lower() == "stderr":
        arg = sys.stderr
    return arg

parser = argparse.ArgumentParser(description="Warns user about CPU and RAM usages")     # ArgumentParser() dan bir obje oluşturduk ve tanımlamasını yaptık

parser.add_argument("-q", "--mode",
                    help="Warn for given type, [C]pu, [R]am, [A]ll",
                    default="A", type=str, choices="CAR")
# uzun olan argümandan -- silinr ve değişkenin ismi olur. Eğer - ile -- yer değişirse path'de görünme sırası değişir
parser.add_argument("-w", "--cpu_warn",
                    help="Warning level for CPU",
                    default=None, type=int)

parser.add_argument("-e", "--cpu_crit",
                    help="Warning level for CPU",
                    default=80, type=int)

parser.add_argument("-r", "--ram_warn",
                    help="Warning level for RAM",
                    default=None, type=int)

parser.add_argument("-t", "--ram_crit",
                    help="Warning level for RAM",
                    default=60, type=int)

parser.add_argument("-y", "--warn_out",
                    help="Warning output (file path, stdout, stderr)",
                    default="/dev/null", type=file_or_stdio)

parser.add_argument("-u", "--crit_out",
                    help="Critical output (file path, stdout, stderr)",
                    default="stdout", type=file_or_stdio)

parser.add_argument("-o", "--resolution",
                    help="Warning level for CPU",
                    default=0.5, type=float)

arglar = parser.parse_args(sys.argv[1:])    ##opts: alınan argümanlar / verileri pars eder

def handle_sigint(sig, stack):
    """When user sends SIGINT (via Ctrl-C) we ask if it's sure or not"""
    global _wait  # If we're already interrupted, just exit and keep it in the global variables
    if _wait:
        print()
        exit(20)
    _wait = True
    choice = input("\rAre you sure you want to exit? (y/N)").lower()
    if choice == "y":
        exit(0)

signal.signal(signal.SIGINT, handle_sigint)

while True:
    if arglar.mode in "ca":
        cpu_reading = max(psutil.cpu_percent(arglar.resolution, percpu=True))
        if cpu_reading > arglar.cpu_crit:
            print("CPU usage is high", file=arglar.crit_out)
        elif arglar.cpu_warn is not None and cpu_reading > arglar.cpu_warn:
            print("CPU usage is critical", file=arglar.warn_out)

    if arglar.mode in "ra":
        ram_reading = psutil.virtual_memory().percent
        if ram_reading > arglar.ram_crit:
            print("RAM usage is high", file=arglar.crit_out)
        elif arglar.ram_warn is not None and ram_reading > arglar.ram_warn:
            print("RAM usage is critical", file=arglar.warn_out)

    time.sleep(arglar.resolution)


Python'da Log Tutma:

        Python'da log tutmak için logging adlı modül kullanılır. İlk olarak getLogger ile yeni bir kayıt tutucu oluşturulur.

logger = logging.getLogger(__name__)

logging modülünün varsayılan log seviyesi warning'dir. Bunun anlamı sadece mevcut seviye olan warning veya daha üstü seviyelerin mesajları gösterilir. Bunun için bir sıralama mevcuttur:

DEBUG << INFO << WARNING << ERROR << CRITICAL

Log seviyesi değiştirilmek istenirse;

logging.getLogger().setLevel(logging.DEBUG)

Logların mesajlarını daha düzgün bir biçimde (formatting) yazdırmak için .Formatter kullanılır:

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

logging'in uygulamaya eklenmesiyle günü tamamladık.

uygulama.py:
import os
import signal
import sys
import psutil
import argparse
import time
import logging
import logging.handlers

__all__ = ["get_args", "connect_signals", "monitor"]

logger = logging.getLogger(__name__)    # yeni bir kayıt tutucu oluşturuldu

def file_or_stdio(arg):
    """This is a validator to open files for writing or opening stdio"""
    if os.path.exists(arg) and os.path.isfile(arg): # dizinin var olup olmadığına bakar, isfile dosya olup olmadığına bakar
        try:
            arg = open(arg, "w")
        except:
            argparse.ArgumentTypeError("Unable to open file {}".format(arg))
    elif arg.lower() == "stdout":
        arg = sys.stdout
    elif arg.lower() == "stderr":
        arg = sys.stderr
    return arg

def get_args(argv):
    parser = argparse.ArgumentParser(description="Warns user about CPU and RAM usages")
    # ArgumentParser() dan bir obje oluşturduk ve tanımlamasını yaptık

    parser.add_argument("-q", "--mode",
                        help="Warn for given type, [C]pu, [R]am, [A]ll",
                        default="A", type=str, choices="CAR")
    # uzun olan argümandan '--' silinir ve değişkenin ismi olur. Eğer - ile -- yer değişirse path'de görünme sırası değişir
    parser.add_argument("-w", "--cpu_warn",
                        help="Warning level for CPU",
                        default=None, type=int)

    parser.add_argument("-e", "--cpu_crit",
                        help="Warning level for CPU",
                        default=80, type=int)

    parser.add_argument("-r", "--ram_warn",
                        help="Warning level for RAM",
                        default=None, type=int)

    parser.add_argument("-t", "--ram_crit",
                        help="Warning level for RAM",
                        default=60, type=int)

    parser.add_argument("-y", "--warn_out",
                        help="Warning output (file path, stdout, stderr)",
                        default="/dev/null", type=file_or_stdio)

    parser.add_argument("-u", "--crit_out",
                        help="Critical output (file path, stdout, stderr)",
                        default="stdout", type=file_or_stdio)

    parser.add_argument("-o", "--resolution",
                        help="Warning level for CPU",
                        default=0.5, type=float)

    parser.add_argument("-d", "--debug",
                        help="Activate debug logger",
                        action="store_true", default=False)

    parser.add_argument("-l", "--debug_level",
                        help="Change debug level",
                        choices=["CRITICAL", "WARNING", "ERROR", "INFO", "DEBUG"],
                        default="INFO")

    return parser.parse_args(argv)  # verileri pars eder

def handle_logger(arglar):
    logger.setLevel(logging._nameToLevel[arglar.debug_level])
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    logger.handlers = []
    if arglar.debug:
        handler = logging.handlers.RotatingFileHandler(filename="output.log",
                                                               maxBytes=1024*1024,
                                                               backupCount=3)
        handler.setFormatter(formatter)
        logger.addHandler(handler)
    else:
        logger.addHandler(logging.NullHandler())

_wait = False

def connect_signals():
    def handle_sigint(sig, stack):
        """When user sends SIGINT (via Ctrl-C) we ask if it's sure or not"""
        logger.info("Signal received")
        global _wait  # If we're already interrupted, just exit and keep it in the global variables
        if _wait:
            logger.debug("_wait is already set, exiting")
            print()
            exit(20)
        _wait = True
        logger.debug("_wait variable set")
        choice = input("\rAre you sure you want to exit? (y/N)").lower()
        if choice == "y":
            exit(0)

        logger.debug("_wait variable unset")
        _wait = False
        logger.debug("User said {}, continuing".format(choice))

    signal.signal(signal.SIGINT, handle_sigint)
    logger.info("Sigint connected")

def monitor(arglar):
    logger.info("Starting main loop")
    while True:
        if arglar.mode in "ca":
            cpu_reading = max(psutil.cpu_percent(arglar.resolution, percpu=True))
            logger.debug("Cpu percents {}".format(cpu_reading))
            if cpu_reading > arglar.cpu_crit:
                logger.debug("Cpu percentage is higher than critical level")
                print("CPU usage is high", file=arglar.crit_out)
            elif arglar.cpu_warn is not None and cpu_reading > arglar.cpu_warn:
                logger.debug("Cpu percentage is higher than warning level")
                print("CPU usage is critical", file=arglar.warn_out)

        if arglar.mode in "ra":
            ram_reading = psutil.virtual_memory().percent
            logger.debug("Sleeping")
            if ram_reading > arglar.ram_crit:
                logger.debug("Ram percentage is higher than critical level")
                print("RAM usage is high", file=arglar.crit_out)
            elif arglar.ram_warn is not None and ram_reading > arglar.ram_warn:
                logger.debug("Ram percentage is higher than warning level")
                print("RAM usage is critical", file=arglar.warn_out)

        logger.debug("Sleeping")
        time.sleep(arglar.resolution)