NLog EventLog

Daha önce ki Log4Net yazımızda log tutmanın ne kadar önemli olduğu ve .Net tarafında kullanabileceğimiz free yapılardan biri olan Log4Net implementasyonunu incelemiştik. Bu yazıda ise bir diğer free framework olan NLOG dan bahsedeceğim. Nlog ile mail atabilir, file log'a, console'a, event log'a log, db ye log atabiliriz.

NLog ile ;

Fatal Üst Seviye : Sistem çökmeleri

Error Uygulama hataları ( Exceptions )

Warn Uyarılar, yinede uygulama çalışmaya devam edebilir.

Info Bilgilendirme herhangi bir amaçlı olabilir. Kullanıcı bilgileri güncellendi vs.

Debug Çalıştırılan sorgular, oturum süresinin bitmesi vs.

Trace Bir eylem başladı diğeri bitti gibi. Örn : Fonksiyon başlangıcı ve bitişi durumları( En Alt Seviye )

seviyelerinde log tutabiliriz. Biz bu yazıda NLog ile Event Log'a nasıl log atılır bunu inceliyor olucaz.

1.Adım İlk olarak işletim daha önceden yğklenmiş olan PowerShell programını yönetici olarak açıyoruz ve MyTestAppLog adında bir event log ve bu event log altında MyTestAppSource adında bir source oluşturuyoruz. Daha sonrasında oluşturduğumuz uygulama ve source isimlerini webconfig tarafta konfigurasyon yaparken ilgili alanlara set edicez.

PowerShell de aşağıdaki gibi code satırını yazıyoruz.

  New-EventLog -LogName MyTestAppLog -Source MyTestAppSource  

Sonradan işletim sisteminde bulunan search kısmına view event log yazarak event viewer'ı açıyoruz ve oluşturduğumuz MyTestAppLogve MyTestAppSource ekranda görmemiz gerekiyor.

 

 

2.Adım İkinci olarak VS da boş bir Web projesi açıp Nuget paket yöneticisine Install-Package NLog yazıp ilgili kütüphaneyi indiriyoruz ve projemizdeki WebConfig dosyası içerisine NLog configurasyonunu sağlayan satırları yazıyoruz.

Configuration tagları arasına aşağıdakini yazıyoruz

<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>  

Daha sonrada configuration tag'inin kapandığı yerin altına da şu şekilde yazıyoruz

<nlog
    autoReload="true"
    throwExceptions="true">
    <variable name="appName" value="MyTestApp" />
 
    <targets async="true">
        <target type="EventLog"
            log="MyTestAppLog"
            name="eventlog"
            source="MyTestAppSource"
            layout="${message}${newline}${exception:format=ToString}"/>
    </targets>

    <rules>
      <logger name="*" writeTo="eventlog" minlevel="Info" />
    </rules>
  </nlog>

 Üstteki configurasyonda ;

  • <target type="EventLog" diyerek EventLog configurasyonu olduğunu belirtiyoruz,
  • log="MyTestAppLog" EventLog adı,  
  • name="eventlog" diyerek isimlendiriyoruz,
  • source="MyTestAppSource" EventLog da tanımlı olan Source adı.
  • layout="$ ile log formatını belirliyoruz.
  • <rules> tag'i arasına yazdığımız kod satırıyla eventlog adında tanımlı olan log configurasyonu için minimum Info seviyesinde log tut.

 

3.Adım Şimdi C# tarafına geçip nasıl log atacağız onu yazalım

 public class NLogManager 
    {
        //WebConfigde tanımladığımız gibi info ve yukarı seviyeler için eventLog'a log atacaktır
        public void LogError(LogModel entry)
        {
           var logger = NLog.LogManager.GetCurrentClassLogger();
           logger.Log(LogLevel.Info, "Info Logged");
           logger.Log(LogLevel.Error, "Error Logged");
        }
    }

Uygulamamızı çalıştırdığımızda event log da aşağıdaki gibi log düştüğünü göreceğiz

 

 

 

Web Config Custom Section

WebConfig Asp.Net tabanlı projelerde istemci tarafında ilk çalıştırılan XML tabanlı bir sayfadır diyebiliriz. İçerisinde bir çok bilgi barındırır ve bir istemci yani kullanıcı websitenize erişmeye çallıştığında ilk webconfig çalışır ve içerisinde set edilen bilgilere göre projenizi çalıştırır & ayağa kaldırır.

Nedir bu bilgile diye soracak olursa; 

  • Debug, Release mode ayarı,
  • .Net Framework bilgisi,
  • Varsa Database conn string bilgisi,
  • Kullanılan .Net Kütüphanelerinin versiyon bilgileri,
  • Uygulama Debug modda nasıl Release modda nasıl çalışacak bunun bilgisi,
  • Site içi ve dışı yönlendirme ayarları vs.

Görüldüğü üzre uygulama ile ilgili bir çok ayar mevcut kısacası uygulamanın configurasyonu ile ilgili sayısızca özellik & ayar set edilebilir.

Bunun gibi ayarların dışında web.config içerisinde uygulama içi kullanılan çeşitli özel bilgiler & ayarlar da saklayabilir. Peki neden bu bilgileri burda saklıyoruz veya turuyoruz ?? Uygulamada Constant diye herhangi bir class oluşturup bunun içerisinde de tutabiliriz. Ama bu sefer ne olur derseniz. Orda tuttuğunuz bilgiyi değiştirmek için tekrardan projeyi açıp class içerisinde set edilen değeri değiştirip uygulamayı tekrardan ilgili yere deploy etmemiz gerekmekte. İşte aslında WeConfig bizi bu durumdan kurtarıyor. Webconfig dosyası deploy edildiği yerde projede ki tanımlı olduğu haliyle XML formatında tutuluyor yani uygulama içinde tanımlı olan class gibi dll'e çevrilip içini tekrardan açamayacağımız bir türde durum değil. Bu nedenle değişme olasılığı yüksek olan bilgileri WebConfig içerisinde tutup ihtiyaç duyulduğunda deploy edildiği dosyada ki folder e giderek çok rahat bir şekilde içini açıp ilgili ayarı değiştirebiliriz. Örnek olarak; uygulama kullanılan iletişim sayfasında ki email adresi veya uygulamaın herhangi bir yerinde kullanılan ve sonradan değiştirmeye açık olan bir text/metin. 

<?xml version="1.0" encoding="utf-8" ?>
<configuration>   
     <system.web>
      <compilation defaultLanguage="c#" debug="true" />
    </system.web>
    
    <appSettings>
      <add key="ContanctEmailAddress" value="info@canertosuner.com" />
    </appSettings>
 </configuration>

Yukarıda da görüldüğü gibi uygulama içerisinde yönetmek istediğimiz değerleri <appSettings> içerisinde unique bir key vererek value alanlarına değerleri set edebiliriz. Bu değeri code tarafından okumak istediğimizde de bilindiği üzre şu şekilde yapıyoruz;

string emailAddress= ConfigurationSettings.AppSettings["ContactEmailAddress"];

Peki ya kendimiz aynı <appSettings> section'ı olduğu gibi bir custom secton yapmak istersek..

Case şu şekilde olsun. Kredi faizi hesaplayan bir uygulamamız var ve bu uygulamadaki faiz oranlarını webconfig den okuyup hesaplıyor. Aslında bu gibi bilgiler direkt olarak DB den de alınabilir ama bizim rojemizde webConfig den alalım. 

1.Adım WebConfigde section tanımı yapma

<configuration>
  <configSections>
    <section name="KrediFaizleri" type="MyProject.KrediFaizleriSection" />
  </configSections>
</configuration>
 

Yukarıda da görültüğü gibi KrediFaizleri adında bir section ımızın olacağı bilgisini verdik.

 

2.Adım Section ve içerisindeki elementleri yazma

</configSections>  tag'inin altında aşağıdaki gibi kodumuzu yazalım

  <KrediFaizleri> 
    <Krediler>
      <add tip="ihtiyac" oran="1.65"/>
      <add tip="tasit" oran="1.96"/>
      <add tip="konut" oran="1.20"/>
    </Krediler>
  </KrediFaizleri>

Burda Krediler diye bir array var ve içerisinde Kredi objesi olduğunu düşünelim. Bu obje içerisinde de tip ve oran adında 2 tane string property var. Aslında yukarıda ki xml kodunun tam karşılığı bu. Yukarıda 3 adet kredi için oran bilgisi girdik şimdi sırada bu değerleri webconfigden okumamızı sağlayacak C# kodlarını yazmaya geldi

 

3.Adım KrediFaizleri elementini tanımlama

Yukarıda Krediler arrayinin içerisinde Kredi objesi olduğunu söylemiştik.Aslında bu bir element. Biz adına KrediFaizleriElement diyelim ve classımız aşağıdaki gibi olacaktır.

 public class KrediFaizleriElement : ConfigurationElement
    {
        [ConfigurationProperty("tip", IsKey = true, IsRequired = true)]
        public string KrediTipi
        {
            get { return (string)this["tip"]; }
            set { this["tip"] = value; }
        }

        [ConfigurationProperty("oran", IsKey = true, IsRequired = true)]
        public string Oran
        {
            get { return (string)this["oran"]; }
            set { this["oran"] = value; }
        }
    }

 

4.Adım KrediFaizleri array'ini tanımlama

Bu adımda webconfig de ki array'i almamızı sağlayan ConfigurationElementCollection den türeyen bir class yazıyoruz. Bu class'ı kullanarak tanımladığımız section içerisinde ki collection'ı içerisindeki Element ler ile birlikte alıyoruz.

[ConfigurationCollection(typeof(KrediFaizleriElement))]
    public class KrediFaizleriCollection : ConfigurationElementCollection
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new KrediFaizleriElement();
        }

         protected override object GetElementKey(ConfigurationElement element)
        {
            return ((KrediFaizleriElement)element).KrediTipi;
        }
    }

  

5.Adım KrediFaizleriSection class ını oluşturma

Fark ettiyseniz  en içten en dışa doğru ilerliyoruz. İlk olarak Element sonra Collection şimdide sırada Section var. Aşağıda yazılan KrediFaizleriSection webconfigde tanımladığımız KrediFaizleri tag'ini okumamızı sağlayacak olan class. İçerisinde Faizler array i var ve bu array'in içerisindede KrediFaizleriElement objeleri bulunacak.

public class KrediFaizleriSection: ConfigurationSection
    {
        [ConfigurationProperty("KrediFaizleri", IsDefaultCollection = true)]
        public KrediFaizleriCollection Faizler
        {
            get { return (KrediFaizleriCollection )this["KrediFaizleri"]; }
            set { this["KrediFaizleri"] = value; }
        }
    }

   

Son Adım Webconfig de tanımlı değerleri okuma ve filtreleme işlemi.

Bu adıma kadar şu sırayla lerledik;

  1. WebConfig de Section tanımlama,
  2. WebConfig de Section içerisindeki Collection ve Elementleri tanımlama,
  3. C# tarafında Element&Model class'ını oluşturma,
  4. C# tarafında Collection class'ını oluşturma,
  5. C# tarafında Section class'ını oluşturma,

Şimdi ise sırada bu class ları kullanarak WebConfig de tanımlı değerleri okuma işlemi var. Bunun için aşağıdaki class ı kullanabiliriz. 

 public static KrediFaizleriElement KrediOranınıGetir(string krediTipi)
        {
            //KrediFaizleri section'nını içerisindeki elementler ile birlikte aldık
            var element=
                ConfigurationManager.GetSection("KrediFaizleriSection") as KrediFaizleriSection;

             //Paramaetre olarak verilen kredi tipine göre linq sorgusu yaptık
             var returnValue = element.Faizler.Cast<KrediFaizleriElement>().SingleOrDefault(c => c.KrediTipi== krediTipi);
           
           //İlgili kredi WebConfigde varmı kontrol ettik
            if (returnValue == null)
                throw new InvalidOperationException(string.Format("Kredi Tipi {0} bulunamadı !", krediTipi));
            //Bulunan krediyi geri döndürdük
            return returnValue;
        }

İşlemlerimiz bu kadar. KrediOranınıGetir metodunu gerekli yerde çağrısını yaparak kullanabiliriz.