Çok Katmanlı Mimari: nerede hata günlüğü \ işleme uygulamak gerekir?


17

Şu anda çok katmanlı bir mimariye sahip büyük bir alt sistemi yeniden düzenliyorum ve etkili bir hata günlüğü tutma / işleme stratejisi tasarlamaya çalışıyorum.

Diyelim ki mimarim aşağıdaki üç katmandan oluşuyor:

  • Genel Arayüz (IE ve MVC Kontrol Cihazı)
  • Alan Adı Katmanı
  • Veri Erişim Katmanı

Benim karışıklık kaynağı nerede hata günlüğü \ işleme uygulamak gerekir:

  1. En kolay çözüm, günlük kaydını en üst düzeyde uygulamaktır (IE Genel Arabirim \ MVC Denetleyicisi). Ancak bu yanlış hissettirir, çünkü farklı katmanlar arasında istisnayı patlatmak ve sonra günlüğe kaydetmek anlamına gelir; istisnayı kaynağında günlüğe kaydetmek yerine.

  2. İstisna kaynağında günlüğe kaydedilir, en iyi çözümdür çünkü en fazla bilgiye sahibim. Bununla ilgili sorunum, TÜM istisnaları yakalamadan kaynaktaki her istisnayı yakalayamıyorum ve etki alanı / genel arabirim katmanında, bu, aşağıdaki katman tarafından zaten yakalanmış, günlüğe kaydedilmiş ve yeniden atılan istisnaların yakalanmasına yol açacaktır. .

  3. Başka bir olası strateji, # 1 ve # 2'nin bir karışımıdır; böylece atılacakları en olası katmandaki özel istisnaları yakalarım (IE Yakalama, günlüğe kaydetme ve SqlExceptionsVeri Erişim Katmanında yeniden atma ) ve daha sonra yakalanmamış diğer istisnaları en üst düzeyde günlüğe kaydederim. Ancak bu, üst düzeydeki her istisnayı yakalamamı ve yeniden kaydetmemi gerektiriyor, çünkü zaten kaydedilmiş \ ele alınmamış hataları vs olmayanlar arasında ayırt edemiyorum.

Şimdi, açıkçası bu, çoğu yazılım uygulamasında bir sorundur, bu nedenle, istisnaların kaynağa yakalanması ve bir kez kaydedilmesi ile sonuçlanan bu soruna standart bir çözüm bulunmalıdır; ancak bunu kendim nasıl yapacağımı göremiyorum.

Bu sorunun başlığı, ' Çok katmanlı bir uygulamada günlüğe kaydetme istisnaları ' ile çok benzer , ancak bu yayındaki yanıtların ayrıntıları eksik ve sorumu yanıtlamak için yeterli değil.


1
Bazen kullandığım bir yaklaşım, kendi Exception (veya RuntimeException) alt sınıfımı oluşturmak ve iç içe geçmiş olarak orijinal istisna dahil olmak üzere atmaktır. Tabii ki, bir üst düzeydeki istisnaları yakalarken, istisnanın türünü kontrol etmem gerektiği anlamına gelir (kendi istisnalarım yeniden gözden geçirilir, diğer istisnalar kaydedilir ve istisnalarımın yeni örneklerine dahil edilir). Ama uzun zamandır solo çalışıyorum, bu yüzden "resmi" tavsiyede bulunamıyorum.
SJuan76

4
The easiest solution would be to implement the logging at the top level- Bunu yap. İstisnaları kaynağında kaydetmek iyi bir fikir değildir ve karşılaştığım her uygulama hata ayıklamak için bir PITA idi. İstisnaları ele almak arayanın sorumluluğunda olmalıdır.
Justin

Aklınızda belirli bir uygulama tekniği / dili var gibi görünüyor, aksi takdirde "günlüğe kaydedilen istisnalar olmayanlardan ayırt edilemez" ifadesini anlamak zor. Daha fazla bağlam verebilir misiniz?
Vroomfondel

@Vroomfondel - Haklısın. C # kullanıyorum try{ ... } catch(Exception ex) { Log(ex); }ve her bir katmanda kodu kaydırma aynı istisna her katmanda günlüğe neden olur. (Ayrıca, kod tabanındaki her katmandaki her istisnayı yakalamak da oldukça kötü bir uygulama gibi görünüyor.)
KidCode

Yanıtlar:


18

Sorularınız için:

En kolay çözüm, günlük kaydını en üst düzeyde uygulamak olacaktır

İstisna balonunun en üst düzeye çıkarılması kesinlikle doğru ve makul bir yaklaşımdır. Yüksek katman yöntemlerinin hiçbiri, başarısızlıktan sonra, genellikle başarılı olamayan bazı işlemlere devam etmeye çalışmaz. İyi donanımlı bir istisna, günlük kaydı için gerekli tüm bilgileri içerir. İstisnalar hakkında hiçbir şey yapmamanız, kodunuzu temiz tutmanıza ve hatalar yerine ana göreve odaklanmanıza yardımcı olur.

İstisna kaynağında günlüğe kaydedilir, en iyi çözümdür çünkü en fazla bilgiye sahibim.

Bu yarı doğrudur. Evet, en faydalı bilgilere buradan ulaşabilirsiniz. Ancak tüm bunları, hemen oturum açmak yerine (zaten orada değilse) istisna nesnesine koymanızı öneririm. Düşük bir düzeyde oturum açarsanız, arayanlara işinizi tamamlamadığınızı bildirmek için yine de bir istisna oluşturmanız gerekir. Bu, aynı olayın birden çok günlüğüne sonuçlanır.

İstisnalar

Temel kılavuzum, istisnaları yalnızca en üst düzeyde yakalamak ve günlüğe kaydetmektir. Ve aşağıdaki tüm katmanlar, gerekli tüm arıza bilgilerinin en üst seviyeye taşınmasını sağlamalıdır. Örneğin Java gibi tek işlemli bir uygulamada, bu genellikle en üst seviyenin dışındaki hiçbir yerde denemeyi / yakalamayı veya günlüğe kaydetmemeyi ifade eder.

Bazen, kural dışı durum günlüğünde, özgün kural dışı durumda bulunmayan bazı bağlam bilgilerinin bulunmasını istersiniz, örneğin, SQL deyimi ve kural dışı durum atıldığında yürütülen parametreler. Ardından orijinal istisnayı yakalayabilir ve orijinali ve bağlamı içeren yeni bir tane atabilirsiniz.

Tabii ki, gerçek hayat bazen müdahale eder:

  • Java'da, bazen bazı sabit yöntem imzalarına uymak için bir istisna yakalamanız ve farklı bir istisna türüne sarmanız gerekir. Ancak bir istisnayı yeniden atarsanız, yeniden atılanın daha sonra günlüğe kaydetmek için gereken tüm bilgileri içerdiğinden emin olun.

  • İşlemler arası bir kenarlığı geçiyorsanız, genellikle yığın izini içeren tam istisna nesnesini teknik olarak aktaramazsınız. Ve elbette bağlantı kaybolabilir. Bu nedenle, bir hizmetin istisnaları günlüğe kaydetmesi ve ardından hata bilgisini mümkün olduğunca çok satır boyunca istemcisine iletmek için elinden gelenin en iyisini yapmaya çalıştığı bir nokta. Hizmet, istemcinin bir hata yanıtı alarak veya bağlantı kopması durumunda zaman aşımına uğrayarak bir hata bildirimi aldığından emin olmalıdır. Bu genellikle aynı hatanın iki kez, bir kez hizmetin içinde (daha ayrıntılı olarak) ve bir kez de müşterinin en üst düzeyinde kaydedilmesine neden olur.

Kerestecilik

Sadece istisna günlüğü değil, genel olarak günlüğe kaydetmeyle ilgili bazı cümleler ekliyorum.

İstisnai durumların yanı sıra, uygulamanızın önemli etkinliklerinin de günlüğe kaydedilmesini istersiniz. Bu nedenle, bir günlük kaydı çerçevesi kullanın.

Günlük düzeylerine dikkat edin (hata ayıklama bilgilerinin ve ciddi hataların farklı şekilde işaretlenmediği günlükleri okumak acıdır!). Tipik günlük seviyeleri:

  • HATA: Bazı işlevler geri döndürülemez şekilde başarısız oldu. Bu, tüm programınızın çöktüğü anlamına gelmez, ancak bazı görevler tamamlanamadı. Genellikle, hatayı açıklayan bir özel durum nesneniz vardır.
  • UYARI: Garip bir şey oldu, ancak herhangi bir görevin başarısız olmasına neden olmadı (garip yapılandırma algılandı, bazı yeniden denemelere neden olan geçici bağlantı arızası vb.)
  • BİLGİ: Bazı önemli program eylemlerini yerel sistem yöneticisine iletmek istiyorsunuz (yapılandırma ve yazılım sürümüyle bazı hizmetlere başlama, veri dosyalarını veritabanına alma, sisteme giriş yapan kullanıcılar, fikri anlıyorsunuz ...).
  • HATA AYIKLAMA: Bir sorunu giderirken geliştirici olarak görmek istediğiniz şeyler (ancak bu veya belirli bir hata durumunda gerçekten neye ihtiyacınız olduğunu asla bilemezsiniz - öngörürseniz, hatayı düzeltirsiniz) ). Her zaman kullanışlı olan bir şey, dış arabirimlerdeki etkinlikleri günlüğe kaydetmektir.

Üretimde, kayıt seviyesini INFO olarak ayarlayın. Sonuçlar bir sistem yöneticisi için faydalı olmalıdır, böylece neler olduğunu bilir. Günlükte ve UYARILARIN yarısındaki her HATA için yardım veya hata düzeltme için sizi aramasını bekleyin.

DEBUG seviyesini yalnızca gerçek hata ayıklama oturumlarında etkinleştirin.

Günlük girişlerini, programınızın belirli bölümleri için hata ayıklama günlüklerini açmanıza olanak tanıyan uygun kategoriler halinde gruplayın (örneğin, girdiyi oluşturan kodun tam nitelikli sınıf adına göre).


Bu kadar ayrıntılı bir cevap için teşekkürler, kayıt kısmını gerçekten takdir ediyorum.
KidCode

-1

İnişler için kendimi destekliyorum, ama bir uzuv çıkacağım ve bunu kabul edebileceğimden emin olmadığımı söyleyeceğim.

Köpüren istisnalar, daha az tekrar kayıt yapmak, çok az fayda ile ekstra çaba. İstisna kaynağında (evet, en kolay) yakalanır, günlüğe kaydedilir, ancak istisna yeniden atılmaz, yalnızca arayan kişiye "hata" bildirilir. "-1", null, boş dize, bazı numaralandırma, her neyse. Arayanın sadece aramanın başarısız olduğunu bilmesi gerekir, neredeyse hiçbir zaman korkunç ayrıntılar. Ve bunlar sizin günlüğünüzde olacak, değil mi? Arayanın ayrıntılara ihtiyacı olduğu nadir durumlarda, devam edin ve havaya uçurun, ancak otomatik bir düşünülmeyen varsayılan olarak değil.


3
Hatayı dönüş değerlerine göre bildirmeyle ilgili sorun: 1. Arayan kişi arızaları önemsiyorsa, özel değeri kontrol etmek zorundadır. Ama bekleyin, nullboş dizgi mi? -1 veya negatif bir sayı mı? 2. Arayan umursamıyorsa (yani kontrol etmiyorsa), bu, orijinal nedenle ilgili olmayan takip hatalarına yol açar, örneğin a NullPointerException. Veya daha kötüsü: Hesaplama yanlış değerlerle devam eder. 3. Arayan kişi umursar ama programcı bu yöntemin başarısız olduğunu düşünmezse, derleyici ona hatırlatmaz. İstisnalar bu sorunları yaşamazlar, ya yakalarsınız ya da tekrarlarsınız.
siegi

1
Üzgünüm, bunu küçümsemek zorunda kaldım. Açıkladığınız yaklaşım (istisnaları özel dönüş değerleriyle değiştirin), C dilinin ortaya çıktığı 1970'lerde en son teknolojiydi ve modern dillerin istisnalara sahip olmasının birçok iyi nedeni var ve benim için asıl istisnaları düzgün kullanmak sağlam kod yazmayı çok daha kolay hale getirir. Ve "Köpüren istisnalar yukarı [...] ekstra çaba [...]" basit yanlıştır: sadece istisnalar hakkında hiçbir şey yapmazlar ve tek başlarına patlarlar.
Ralf Kleberhoff
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.