---
title: "Python loglamayı doğru log seviyeleri ve istisna yakalamayla kur"
description: "Python logging sen yapılandırana kadar yalnızca WARNING ve üstünü yazdırır. 3 satırlık kurulum, 5 log seviyesi ve bir istisnayı traceback'iyle loglama, Python 3.13 üzerindeki çalıştırmalardan."
canonical: "https://logbrew.co/tr/guides/python-logging"
last_updated: "2026-11-10"
---

# Python loglamayı doğru log seviyeleri ve istisna yakalamayla kur

Python `logging` sen yapılandırana kadar yalnızca WARNING ve üstünü yazdırır. 3 satırlık kurulum, 5 log seviyesi ve bir istisnayı traceback'iyle loglama, Python 3.13 üzerindeki çalıştırmalardan.

10 Kasım 2026 tarihinde Python 3.13.5 ve logbrew-sdk 0.1.29 ile test edildi

[Furkan Erday](https://github.com/furkanerday) tarafından. Furkan Erday, LogBrew'un kurucusu. LogBrew'u her gün Claude Code ve Codex ile geliştiriyor.

Canonical: https://logbrew.co/tr/guides/python-logging

## Her Python log seviyesi ayarsız ne yapar, LogBrew'da ne olur

| Loglama çağrısı | Ayarsız yazdırılan | LogBrew'daki kendi seviyesi |
| --- | --- | --- |
| `log.debug()` | Atıldı | `info` ile birleştirildi |
| `log.info()` | Atıldı | `info` |
| `log.warning()` | `WARNING:root:` | `warning` |
| `log.error()` | `ERROR:root:` | `error` |
| `log.critical()` | `CRITICAL:root:` | `critical` |

Hiç yapılandırma olmadan root logger üzerinde 5 çağrı, sonra aynı 5 çağrı LogBrew handler'ı üzerinden. Dolu kupa, yazdırıldığı ya da kendi seviyesiyle tutulduğu anlamına gelir.

## Loglamayı 3 satırda kur

### İlk log çağrısından önce basicConfig() fonksiyonunu 1 kez çağır

`basicConfig()` root logger'ın seviyesini ve satır formatını belirler. Hiç ayar yapılmazsa Python yalnızca WARNING ve üstünü `WARNING:root:keg below 10%` biçiminde yazdırır, DEBUG ve INFO'yu atar.

```bash
import logging

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s %(levelname)s %(name)s %(message)s",
)
log = logging.getLogger("taproom")

log.debug("keg pressure read")
log.info("tap opened")
log.warning("keg below 10%")
log.error("keg empty")
log.critical("cooler offline")
```

Çıktı

```text
2026-11-10 08:34:04,828 INFO taproom tap opened
2026-11-10 08:34:04,828 WARNING taproom keg below 10%
2026-11-10 08:34:04,828 ERROR taproom keg empty
2026-11-10 08:34:04,828 CRITICAL taproom cooler offline
```

### Her modüle kendi adıyla bir logger ver

`logging.getLogger(__name__)` her modüle kendi logger'ını verir, böylece her satır hangi modülden geldiğini söyler. Root logger'ı yalnızca `basicConfig()` için kullan.

### Seviyeyi ortam değişkeninden oku

`basicConfig()` seviye adını metin olarak kabul eder. Bunu `LOG_LEVEL=DEBUG` ile çalıştır, debug satırı kod değişmeden görünür.

```bash
import logging
import os

logging.basicConfig(level=os.environ.get("LOG_LEVEL", "INFO"))
log = logging.getLogger("taproom")
log.debug("keg pressure read")
log.info("tap opened")
```

Çıktı

```text
DEBUG:taproom:keg pressure read
INFO:taproom:tap opened
```

### Yeniden yapılandırmak için force=True geç

Root logger'da zaten bir handler varsa Python 2. `basicConfig()` çağrısını yok sayar. Handler'ları değiştirmek için, örneğin testlerde, `force=True` geç.

```bash
import logging

logging.basicConfig(level=logging.WARNING)
logging.basicConfig(level=logging.DEBUG)
logging.debug("second basicConfig: not printed")
logging.basicConfig(level=logging.DEBUG, force=True)
logging.debug("basicConfig with force=True: printed")
```

Çıktı

```text
DEBUG:root:basicConfig with force=True: printed
```

## Her istisnayı traceback'iyle logla

### except içinde log.exception() çağır

`log.exception()` ERROR seviyesinde loglar ve traceback'i ekler. Başka bir seviyedeki çağrıda aynısını yapmak için `exc_info=True` geç.

```bash
import logging

logging.basicConfig(level=logging.INFO, format="%(levelname)s %(name)s %(message)s")
log = logging.getLogger("taproom")
taps = {"ipa": 12}

def pour(beer):
    return taps[beer]

try:
    pour("stout")
except KeyError:
    log.exception("pour failed")
```

Çıktı

```text
ERROR taproom pour failed
Traceback (most recent call last):
  File "app.py", line 11, in <module>
    pour("stout")
    ~~~~^^^^^^^^^
  File "app.py", line 8, in pour
    return taps[beer]
           ~~~~^^^^^^
KeyError: 'stout'
```

### Her satırı logging handler'ıyla LogBrew'a gönder

Logger'ına `LogBrewLoggingHandler` ekle. Her kayıt seviyesi, logger adı, dosyası ve satırıyla bir LogBrew logu olur. İstisnanın adı ve mesajı da, `extra={}` içindeki değerler de birlikte gelir.

```bash
import logging
import os

from logbrew_sdk import HttpTransport, LogBrewClient, LogBrewLoggingHandler

client = LogBrewClient.create(api_key=os.environ["LOGBREW_SERVER_API_KEY"])
transport = HttpTransport()
log = logging.getLogger("taproom")
log.addHandler(LogBrewLoggingHandler(client, transport, metadata={"service": "taproom"}))
log.setLevel(logging.INFO)

taps = {"ipa": 12}

def pour(beer):
    return taps[beer]

try:
    pour("stout")
except KeyError:
    log.exception("pour failed", extra={"order_id": "ord_42"})

response = client.flush(transport)
print("HTTP", response.status_code, "accepted", response.accepted_events, "logs")
```

Çıktı

```text
HTTP 200 accepted 1 logs
```

### Logu istisna alanlarıyla geri oku

`logbrew read logs --severity error --json` satırı `exceptionName`, `exceptionMessage`, dosya, fonksiyon, satır numarası ve senin `order_id` değerinle döndürür.

```bash
logbrew read logs --project <project_id> --severity error --since 1h --json | jq '.[0] | {level, message, logger: .attributes.logger, metadata: .attributes.metadata}'
```

Çıktı

```text
{
  "level": "error",
  "message": "pour failed",
  "logger": "taproom",
  "metadata": {
    "exceptionMessage": "'stout'",
    "exceptionName": "KeyError",
    "fileName": "send.py",
    "functionName": "<module>",
    "levelName": "ERROR",
    "levelNumber": 40,
    "lineNumber": 20,
    "module": "send",
    "order_id": "ord_42",
    "processName": "MainProcess",
    "service": "taproom",
    "threadName": "MainThread"
  }
}
```

### Süreci bitiren çökmeyi yakala

`install_process_error_capture()` kendini `sys.excepthook` üzerine bağlar. Kimsenin yakalamadığı bir istisna `handled: false` ile `critical` seviyesinde bir sorun olur ve süreç 1 koduyla çıkmadan önce yakalanır.

```bash
import atexit
import json
import os

from logbrew_sdk import LogBrewClient, RecordingTransport, install_process_error_capture

transport = RecordingTransport.always_accept()
client = LogBrewClient.create(api_key=os.environ["LOGBREW_SERVER_API_KEY"], transport=transport)
install_process_error_capture(client, on_capture_error=print)


@atexit.register
def show_captured_issue() -> None:
    issue = json.loads(transport.last_body())["events"][0]["attributes"]
    print(json.dumps({k: issue[k] for k in ("title", "level")}), json.dumps(issue["exception"]))


kegs = {"ipa": 3}
kegs["stout"] -= 1
```

Çıktı

```text
Traceback (most recent call last):
  File "<stdin>", line 19, in <module>
KeyError: 'stout'
{"title": "KeyError", "level": "critical"} {"type": "KeyError", "mechanism": {"type": "python.excepthook", "handled": false}}
```

## Test ederken gördüklerimiz

Hiç yapılandırma olmadan root logger üzerindeki 5 çağrı stderr'e 3 satır yazdırdı, DEBUG ve INFO çağrılarını attı. Varsayılan satır `WARNING:root:keg below 10%` örneğindeki gibi seviye, logger adı ve mesajdan oluşur.

2. `basicConfig()` çağrısı biz `force=True` geçene kadar hiçbir şeyi değiştirmedi. LogBrew handler'ı üzerinden DEBUG ve INFO kayıtları `info`, WARNING `warning`, ERROR `error`, CRITICAL `critical` olarak geldi.

`log.exception()` LogBrew loguna `exceptionName` ve `exceptionMessage` ekledi. Handler'da `include_exception_text=True` ile tam traceback `exceptionText` olarak geldi.

```bash
import logging

logging.debug("keg pressure read")
logging.info("tap opened")
logging.warning("keg below 10%")
logging.error("keg empty")
logging.critical("cooler offline")
```

Çıktı

```text
WARNING:root:keg below 10%
ERROR:root:keg empty
CRITICAL:root:cooler offline
```

## 5 log seviyesi ve her birini ne zaman kullanacağın

DEBUG, bir hatayı düzeltirken ihtiyaç duyduğun değerler içindir. Fıçı basıncı, SQL metni ya da tekrar deneme sayısı gibi. Canlı ortamda kapalı tut.

INFO programın ne yaptığını kaydeder, açılan bir musluk ya da ödenen bir sipariş gibi. WARNING ters giden ama ele alınan şeyi kaydeder, %10'un altına düşen bir fıçı gibi. ERROR başarısız bir isteği ya da işi kaydeder, boşalan bir fıçı gibi. CRITICAL programı durduran şeyi kaydeder, devre dışı kalan bir soğutucu gibi.

Her istisnayı 1 kez, ele aldığın yerde logla. Çağrı yığınının her seviyesinde bir satır, 1 hata için 3 uyarı gönderir.

```bash
import logging

for name in ("DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"):
    print(name, logging.getLevelName(name))
print("root logger level:", logging.getLevelName(logging.getLogger().level))
```

Çıktı

```text
DEBUG 10
INFO 20
WARNING 30
ERROR 40
CRITICAL 50
root logger level: WARNING
```

## LogBrew ne kaydeder

Her kayıt seviyesi, logger adı, dosya adı, fonksiyonu, satır numarası ve modülüyle 1 log olur. `extra={}` içindeki ilkel değerler filtreleyebileceğin alanlara dönüşür, handler'daki `metadata={}` ise yukarıdaki `service` gibi her satıra bir alan ekler.

Bir istisnada log `exceptionName` ve `exceptionMessage` alır. Traceback metnini de saklamak için handler'a `include_exception_text=True` geç.

`install_process_error_capture()` yakalanmayan bir istisnayı `critical` seviyesinde bir soruna dönüştürür. İstisna türü, stack frame'leri ve `python.excepthook` mekanizması birlikte kaydedilir.

## Sık sorulan sorular

### Python'da varsayılan log seviyesi nedir?

WARNING. `basicConfig()` çağrısı olmadan root logger WARNING, ERROR ve CRITICAL'ı `WARNING:root:message` biçiminde stderr'e yazdırır, DEBUG ve INFO'yu atar.

### logging.basicConfig neden hiçbir şey yapmıyor?

Root logger'da zaten bir handler var. Önceki bir `basicConfig()` çağrısından ya da bir kütüphaneden gelmiştir, bu yüzden Python çağrıyı yok sayar. Handler'ları değiştirmek için `force=True` geç.

### logging.error ile logging.exception arasındaki fark nedir?

`log.exception()`, `exc_info=True` geçilmiş `log.error()` demektir. ERROR seviyesinde loglar ve traceback'i ekler. Yalnızca bir `except` bloğunun içinde çağır.

### Python log seviyeleri sırasıyla nedir?

DEBUG 10, INFO 20, WARNING 30, ERROR 40, CRITICAL 50. Logger, bir kaydı numarası ayarladığın seviyeye eşit ya da üstündeyse geçirir.

### Python'da print() mi logging mi kullanmalıyım?

`logging` kullan. `print()` fonksiyonunda seviye, zaman damgası, logger adı ve handler yoktur. `logging` ile satırları modül başına açar, bir dosyaya ya da LogBrew'a gönderirsin.

## Her Python istisnasını traceback'iyle gör

LogBrew Python SDK'sı her log satırını seviyesi, logger'ı, dosyası ve satırıyla gönderir, yakalanmayan bir istisnayı stack trace'iyle bir soruna dönüştürür. Cömert ücretsiz planla başla, kart gerekmez.

[Ücretsiz başla](https://logbrew.co/tr)

## Kaynaklar

- [Python docs, Logging HOWTO](https://docs.python.org/3/howto/logging.html)
- [Python docs, logging module](https://docs.python.org/3/library/logging.html)
- [python/cpython#78078](https://github.com/python/cpython/issues/78078)

## Ajanlar ve Python için diğer rehberler

- [Claude Code ve Codex'e MCP sunucusu ekle](https://logbrew.co/tr/guides/mcp-server-claude-code-codex)
- [Claude Code ve Codex'te AGENTS.md kullan](https://logbrew.co/tr/guides/agents-md)
- [Claude overloaded 529 ve rate limit 429 hatalarını çöz](https://logbrew.co/tr/guides/claude-overloaded-rate-limit-error)
- [Alana göre arayabileceğin log formatı ve log seviyeleriyle yapılandırılmış loglama](https://logbrew.co/tr/guides/structured-logging)
- [Claude Code, Codex, JavaScript ve Python'daki hataları çöz](https://logbrew.co/tr/guides)
