Hata Ayıklama ve Loglar

1.7k görüntülenme Markdown

Gerçekte ne olduğunu öğrenin: hatalar nereye kaydediliyor ve kabuktan nasıl okunur. Sessiz bir sayfa çoğu zaman eksik değil, yakalanmış bir hatadır.

Genel Bakış

Hatalar kendiliğinden görünmez. Hepsi, çağıranın ne göreceğine karar veren tek bir işleyiciden geçer. Bu bir HTML hata sayfası, bir JSON hata gövdesi ya da teşhisler kapalıysa hiçbir şey olabilir. Her durumda hata, hata günlüğüne yazılır ve okuduğunuz şey o günlüktür.

Ekranda mesaj olmaması size neredeyse hiçbir şey söylemez; günlük her şeyi söyler.

Ön Koşullar

  • Üzerinde çalıştığınız kurulumda teşhislerin açık olması.
  • Sitenin çalıştığı PHP'nin aynısına kabuk erişimi. Araç HTTP üzerinden 404 döner; yalnızca komut satırı aracıdır.

Adım Adım

Genel Görünümle Başlayın

  1. php coremio/errlog.php stats çalıştırın.
  2. Ölümcül ve hata sayılarını, bir de son yirmi dört saati okuyun. Sıçrayan sayı, bakılacak yerdir.
  3. Komut işe yarar bir şey göstermiyorsa loglama kapalıdır ya da depolama dizini yazılabilir değildir. Önce onu düzeltin.

Hatayı Bulun

  1. Son kayıtları php coremio/errlog.php list --limit=10 ile listeleyin ya da --level=FATAL ile daraltın.
  2. Her kayıt bir imza, bir sayaç, dosya ve satır ile en son görülme zamanını taşır.
  3. Birini php coremio/errlog.php show <imza> ile açın: tam kayıtta istek ve yığın vardır.

Bildirilen Kimliği İzleyin

  1. Bir kullanıcıya ya da API çağıranına ulaşan hata, bir hata kimliği taşır.
  2. php coremio/errlog.php find <kimlik> ile arayın.
  3. O tek olayın kaydını alırsınız; kullanıcı bildirimini üzerinde çalışılabilir kılan şey budur.

Referans

Tek giriş noktası, sekiz komut. Argümanlar sıralıdır, seçenekler herhangi bir sırada --ad=değer biçimindedir. Komutun okumadığı seçenek yok sayılır.

KomutArgümanSeçeneklerNe yapar
helpyokyokKomut listesi. Varsayılan da budur, -h da buna karşılık gelir.
statsyokyokSeviye ve tipe göre toplamlar, bir de son yirmi dört saat.
listyok--level --type --limit --offset --fileManifest'teki kayıtlar; en son görülen üstte, imza başına bir satır.
findhata kimliğiyokO kimlik için tüm log dosyalarını tarar ve kaydı gösterir. Eşleşme yoksa çıkış kodu 1.
showimzayokTek bir kaydı çözüp tamamını döker: istek, mesaj, bağlam, yığın, POST gövdesi.
deleteimza--forceTek bir log dosyasını ve manifest satırını siler. Zorlanmadıkça onay sorar.
cleanupyok--days --forceN günden eski dosyaları iki log tipinde de siler. Zorlanmadıkça onay sorar.
rebuildyokyokHer log dosyasını taze bir manifest'e yeniden dizinler; dosyalar elle kopyalandıktan ya da silindikten sonra.

İki sıralı argüman birbirinin yerine geçmez. İmza, bir çağrı noktasının 32 karakterlik parmak izidir ve her list satırının altında görünür. Hata kimliği ise hatayla karşılaşan kişiye gösterilen kısa koddur. İkisi de büyük küçük harf duyarsız eşleştirilir; birini diğerinin yerine vermek biçim kontrolüne takılır.

Seçenekler

--level=AD Şunlardan biri: FATAL, ERROR, WARNING, INFO, DEBUG, DEPRECATED. Büyük küçük harf önemsizdir. Koşu başına tek seviye.
--type=AD system ya da database. İkisi ayrı saklanır ve stats onları ayrı sayar.
--limit=N Kaç satır basılacağı. Varsayılan 20, en az 1.
--offset=N Kaç satır atlanacağı; sayfalama için. Varsayılan 0.
--file=DESEN Kayıtlı yolun büyük küçük harf duyarsız bir alt dizesi, glob değil. Bir dizin parçası bütün bir alt sistemi daraltır.
--days=N cleanup için gün cinsinden saklama süresi. Varsayılan 30; 1'in altındaki bir değer komutu durdurur.
--force delete ve cleanup onayını atlar.

Yazan Taraf

CLI'nin okuduğu her şey bu iki sınıf üzerinden yazıldı. İki yazma metodu da find komutunun geri aldığı hata kimliğini döndürür.

imzalar
// coremio/classes/MioException.php
public static function getInstance(): MioException;
public function logError(string $message, array $context = [], string $level = 'ERROR', string $type = 'system'): string;
public function logDatabaseError(string $query, string $error, array $params = []): string;
public function sanitizeData(array $data): array;

// coremio/classes/Logger.php
public function log(string $level, string $message, array $context = [], string $type = 'system'): string;
public static function stats(): array;
public static function entries(array $filters = [], int $start = 0, int $limit = 50, array $sort = []): array;
public static function entriesCount(array $filters = []): int;
public static function cleanup(int $daysToKeep = 30, ?int $cutoffTimestamp = null, string $type = 'system'): int;
public static function deleteOne(string $signature): bool;
public static function rebuild(): int;

list komutunun arkasındaki filtre dizisi, CLI'nin açtığından fazlasını kabul eder. Bilinmeyen bir anahtar yok sayılır, yani bir yazım hatası sonucu daraltmaz, sessizce genişletir.

Filtre anahtarıDeğerEşleşme
levelsseviye adlarından oluşan dizitam, büyük harfe çevrilir
typessystem ya da database dizisitam
signaturedizealt dize
filedizealt dize, büyük küçük harf duyarsız
messagedizekayıtlı önizlemenin alt dizesi
exception_classdizealt dize
request_uridizealt dize
http_methodGET, POST vb.tam, büyük harfe çevrilir
user_idinttam; 0 ise yok sayılır
ipdizealt dize
min_occurrenceintbu sayı ve üzeri
start_datetime / end_datetimetarih çözücünün kabul ettiği her şeyson görülme üzerinde pencere

Sıralama dizisi ['field' => 'last_seen', 'order' => 'desc'] biçimindedir. İşe yarayan alanlar last_seen, first_seen, count ve level; sonuncusunda sıralama alfabeye göre değil ciddiyete göre yapılır.

Bir Hata Nasıl Görünür

İstekTeşhis açıkTeşhis kapalı
Normal sayfa, ölümcülAyrıntılı hata sayfasıGenel hata sayfası
Normal sayfa, ölümcül değilSayfada bildirimGörünür bir şey yok
AJAX ya da APIAyrıntılı JSON hatasıKimlikli JSON hatası
Kanca dinleyicisiYakalanır ve loglanır; akış her hâlükârda devam eder
Komut satırıGünlüğe yazılır; çıktı tamponu mesajı gizleyebilir

Örnek

kabuk
# Önce sağlık: düşen bir şey var mı?
php coremio/errlog.php stats

# En son beş ölümcül hata
php coremio/errlog.php list --level=FATAL --limit=5

# Yalnız tek bir alt sistemden çıkanlar, onarlık ikinci sayfa
php coremio/errlog.php list --file=modules/Servers --limit=10 --offset=10

# Yalnız veritabanı hataları
php coremio/errlog.php list --type=database --limit=5

# Tek bir imzanın tam kaydı
php coremio/errlog.php show f05bc1f49d2963a58a7c378dc3430c48

# Kullanıcı bir hata kimliği bildirdi; o olayı ara
php coremio/errlog.php find 25EE72D6527

# Düzeltilen imzayı at, kalanı bir haftaya kırp
php coremio/errlog.php delete f05bc1f49d2963a58a7c378dc3430c48 --force
php coremio/errlog.php cleanup --days=7 --force

# Log dosyaları elle taşındıktan ya da silindikten sonra yeniden dizinle
php coremio/errlog.php rebuild

Aynı kayıtlar PHP'den. Yazmanın döndürdüğü kimlik, CLI'nin geri okuduğu kimliktir.

yaz, sonra oku
// Yazma: `errlog.php find` komutuna vereceğiniz kimliği döndürür.
$id = MioException::getInstance()->logError(
    'Provisioning refused by the panel',
    ['service_id' => 41, 'response' => $body],
    Logger::LEVEL_ERROR,
    Logger::TYPE_SYSTEM
);

// Okuma: `errlog.php list` komutunun bastığı satırların aynısı.
$rows = Logger::entries(
    ['levels' => [Logger::LEVEL_FATAL], 'file' => 'modules/Servers'],
    0,
    10,
    ['field' => 'count', 'order' => 'desc']
);

foreach ($rows as $row)
    echo $row['signature'], '  x', (int) ($row['count'] ?? 1), '  ',
         $row['file'] ?? '-', ':', (int) ($row['line'] ?? 0), '  ',
         $row['message_preview'] ?? '', PHP_EOL;

// Toplamlar: total, system, database, fatal, error, warning, info,
// last_24h, occurrences ve seviyeye göre ayrılmış recent[].
$health = Logger::stats();

Tuzaklar

Sessiz bir komut satırı başarılı demek değildir

Başlangıçta bir çıktı tamponu kurulur, yani standart çıktıya yazılan mesaj kaybolabilir. Teşhis çıktısını standart hataya yazın ve bir script'in hiçbir yanlış yapmadığına inanmadan önce günlüğe bakın.

Her uyarı bir disk yazımına mal olur

İşleyici ölümcül olmayan uyarıları da kaydeder; yani döngü içinde okunan eksik bir dizi anahtarı adım başına bir yazıma dönüşür. Değerleri varsayılanla okuyun.

--force olmadan yıkıcı komutlar cevap bekler

delete ve cleanup terminalden evet ya da hayır okur. Zamanlanmış bir işte ya da boruya bağlı bir kabukta cevap verecek kimse yoktur; komut ya bloke olur ya hiçbir şey yapmaz. Seçeneği bilerek verin.

Yüksek bir tekrar sayısı tek bir sayfa yüklemesi olabilir

Kayıtlar imzaya göre gruplanır ve sayılır. İlk ve son görülme aynı ana denk geliyorsa o satır tek istekte defalarca çalışmıştır. Bu, döngü içindeki bir uyarının parmak izidir.

Faydalı oldu mu?

Geri bildiriminiz için teşekkürler!

Hâlâ Yardıma mı İhtiyacınız Var?

Yukarıda bulamadığınız her şey için destek ekibimiz her zaman yanınızda.