Güvenli Olay Günlükçüsü(EventLog) Kullanımı - I

Güvenli Olay Günlükçüsü(EventLog) Kullanımı - I İki makaleden oluşan bu yazı dizimizde güvenli olay günlükçüsü (event log) kullanımından bahsedeceğiz. Bu makalemizde olay günlükçüsünü neden güvenli bir şekilde kullanmamız gerektiğinden bahsedeceğiz. Zorluk Derecesi: 1 2 3 4 5 Anahtar Sözcükler: Microsoft.NET, Olay Günlükçüsü, Event Log, Kod Erişim Güvenliği, Güvenli Uygulama Geliştirme Uygulama geliştirme kadar o uygulamaya destek verebilmek de oldukça önemlidir. Destek mekanizmanızı nasıl kurduğunuz sizin işi yapış kalitenizi oluşturur. Son kullanıcılar için her zaman içinde alınan en ufak hata bile acildir ve önemlidir. Son kullanıcılar uygulamanın hata almasını asla kabullenemezler. Bu durumda sizin bu hatadan en kısa sürede haberiniz olması ve hataya sebep olan durumu çözmeniz gerekmektedir. Uygulama geliştiricilerin buradaki en önemli problemlerinden biri hatanın tam olarak kendilerine aktarılmamasıdır. Kullanıcılarınız size "uygulama hata verdi ama ben şöyle bir şey de yapmıştım" diye farklı şeyler söyleyip sizin alakasız kodlar içinde boğulmanıza da sebep olurlar. Alınan hatanın tam olarak ne olduğunu bilebilmeniz için çok iyi bir kayıtlama (loglama) yapmalısınız.Uygulamanız hata aldığında detaylı hata tanımına en kısa sürede ulaşmak zorundasınız. Bu durumda bir çok kişinin tercihi alınan hataları veri tabanında saklamak ve gerektiğinde bu kayıtlardan hataları çözebilmektir. Eğer ki veri tabanı sunucusu ile ilgili bir probleminiz varsa (örneğin hataları veri tabanına kaydeden kullanıcının hakları elinden alınmış olabilir), bu durumda hataları, veri tabanı kadar olmasa da, kategorize edilebilir bir yerde saklamanız gerekir. Bunun için genellike olay günlükçüsü(event log) kullanılır. Ancak, özellikle web tabanlı uygulamalarda, uygulamanın çalıştığı kullanıcının (ASPNET kullanıcısı)oldukça kısıtlı hakları vardır. Bu kullanıcının olay günlükçüsüne kayıt ekleme hakkı yoksa ne olacak? Şimdi bu durumu örneklendiren bir kod parçacığı verelim:Hata Kontrollü Kod Parçacığı: try { // Hataya yol açabilecek kod } catch (Exception ex) { // Hatayı burada kayıt altına almalıyız }İyi programlama örneği olarak yapmamız gereken tüm hataları tek bir yerde kayıt altına almaya çalışmaktır. Bunun için hataları kayıt altına alan bir sınıf tanımlayalım. Sınıfımızın adı LogManager olsun. Bu sınıfa hataları iletmek için public static bir metot tanımlayalım. Bu static metot private diğer static metotları kullanarak hataları kayıt altına alsın. Sınıfımızın kodu aşağıdaki gibi olacaktır:Hataları Kayıt altına alan kod parçacığı:public sealed class LogManager { #region Public Methods public static void DispatchException(Exception ex) { if (!DispatchDB(ex)) DispatchEventLog(ex); } #endregion #region Private Methods private static bool DispatchDB(Exception ex) { return false; } private static void DispatchEventLog(Exception ex) { System.Diagnostics.EventLog.WriteEntry( System.AppDomain.CurrentDomain.FriendlyName, ex.Message, EventLogEntryType.Error, 0, 0, System.Text.Encoding.UTF8.GetBytes(ex.StackTrace)); } #endregion }Buradaki kodda hatalar öncelikle veri tabanına kaydedilmeye çalışıyor. Başarısız olunursa olay günlükçüsüne kayıt atılıyor. Şu an ki konumuz olay günlükçüleri olduğundan veri tabanına kaydetmeye çalışan koda burada yer vermiyoruz, her seferinde hata aldığımızı düşünüyoruz. İlk yazdığımızı kodu bu sınıfı kullanacak şekilde yeniden düzenleyelim:Hata Kontrollü Kod Parçacığının yeni hali:try { // Hataya yol açabilecek kod } catch (Exception ex) { LogManager.DispatchException(ex); }Peki, olay günlükçüsüne yazarken herhangi bir hatayla karşılaşırsak ne olur? Bu durumda yeni bir exception atılacak ve uygulamamız bu hatayı verecektir. Muhtemelen son kullanıcınızdan size ekran görüntüsü göndermesini istediğinizde karşılaşacağınız hata bu hata olacaktır. Olay günlükçüsüne kayıt atarken dört ayrı exception atılabilir. Bunlar: System.ComponentModel.Win32Exception, işletim sistemiyle ilgili bir durum oluşmuştur. Normal şartlar altında bu hatayı hiç bir zaman almazsınız. System.ArgumentException, hata kaynağının (Event Source) geçersiz bir ismi olmasından ya da 32K"dan daha detaylı bir bilgiyi eklemek istediğinizde atılır System.InvalidOperationException, ilgili registry anahtarlarına ulaşılamadığında atılır. İşletim sisteminin ciddi bir şekilde hasar gördüğü durumlarda oluşabilir. System.ComponentModel.InvalidEnumArgumentException, .NET ile uygulama geliştirirken bu hatayı almazsınız. Enum değerlerinin hatalı olması gerekir. Bu da derleme zamanında hata olarak verileceği için bu hatayı almazsınız.Peki başka hiç bir yerde hata alamaz mıyız? Eğer olay günlükçüsüne yazmaya çalışan kullanıcının bu işlemi yapmaya yetkisi yoksa System.Security.SecurityException atılır. Bu durumu çözmek için olay günlükçüsüne kayıt atan kodunuzu try catch blokları içine alabilir ve SecurityException atıldığında orjinal hatayı başka bir yerde saklamayı deneyebilirsiniz. (Bunun için size önerim text dosya kullanmanızdır) Ancak try-catch bloğuna alınmış bir kod oldukça yavaş çalışacaktır ve belki de daha önemlisi bu tarz bir yaklaşım bir kötü programlama örneği oluşturur. Uygulamanız kısıtlandırılma ihtimali olan bir işlem yapmak istediğinde öncelikle onu çalıştıran kullanıcının bu hakkının olup olmadığını denetlemelidir. Bu duruma benzer bir kötü kodlamayı ve olması gerekeni aşağıda vererek bu makalemizi noktalıyoruz. Bir sonraki makalemizde bu izinleri nasıl kontrol edeceğimizi örnek kodlarıyla inceleyeceğiz. Bir sonraki makalemizde görüşünceye kadar güvende kalın !!!Kötü Kod Parçacığı:private string Foo(object pObj) { try { return ((Exception)pObj).Message; } catch { return ""; } }Olması Gereken Kod Parçacığı:private string Foo(object pObj) { if (pObj is Exception) return (pObj as Exception).Message; return ""; }Not: Aradaki performans farkı da gözardı edilemeyecek kadar fazladır. Bunu görmek için her iki fonksiyonu da arka arkaya null ile çağırmayı deneyin. Örneğin, benim bilgisayarımda arka arkaya 300.000 kez "kötü kod parçacığının" çağrılması 18 sn de gerçekleşirken "olması gereken kod parçacığının" arka arkaya 1.000.000 kez çağrılması toplam 15 milisaniyede gerçekleşti...Yazar : Yunus Emre ALPÖZENe-Posta : yunus.alpozen et msakademik.net

Döküman Arama

Başlık :

Kapat