Asp.net core Logging Serilog Giriş.
Tags: dotnet, csharp
Published: 2021-10-11 13:07:41

# Serilog Nedir ? 

.net için structural logging framework'üdür.

# Structural logging (semantic logging) 

Yapılandırılmış verilerdir. Kısaca anlatmak gerekirse kategorize edilmiş verilerdir. Bilgisayar tarafından sorgulanabilir verilerdir. Örneğin bir json dosyasının yapısal olarak düzenlenmiş bir şekilde olursa : Bilgisayar tarafından kolayca sorgulanabilirdir yani sadece insanların okuyabileceği bir veri türü değil, bilgisayar ile log'a sorgu atabiliyorsak o log structural logging'dir.

# Serilog'u asp.net core projemiz ile nasıl uygularız adım adım görelim : 

1.) Bir mvc projesi oluşturun.

2.) Mvc projesine içine : "appsettings.Production.json" dosyasını ekleyin.

3.) Program.cs adlı class'ı açın ve Main metodunun içine aşağıdaki satırları yazın : 

```
var configuration = new ConfigurationBuilder()
                .AddJsonFile("appsettings.Production.json")
                .Build();

```
Yukarıdaki satırlar "appsettings.Production.json" dosyasındaki configuration'ları çekmemizi sağlayacak.

4.) "launchSettings.json"ı açın ve "ASPNETCORE_ENVIRONMENT"ı Prdocution olarak değiştirin.

5.) Program.cs altındaki Main metoduna devam ediyoruz, aşağıdaki satırlarım Main metoduna ekleyelim : 

```
Log.Logger = new LoggerConfiguration()
                .ReadFrom.Configuration(configuration)
                .CreateLogger();
```
Yukarıdaki satırlar 3. adım da yaptığımız configurasyonları yeni bir Logger yaratırken kullanıyoruz.

6.) 5. adımdaki metotların çalışması için Serilog.AspNetCore paketini nugetten ekleyelim.

7.)  "Program.cs" serilog using olarak ekleyelim : 

```
using Serilog;
```
8.) Main metodunun içini aşağıdaki gibi değiştirelim : 

```
            var configuration = new ConfigurationBuilder()
                .AddJsonFile("appsettings.Production.json")
                .Build();

            Log.Logger = new LoggerConfiguration()
                .ReadFrom.Configuration(configuration)
                .CreateLogger();

            try
            {
                Log.Information("Uygulama Başlıyor");
                CreateHostBuilder(args).Build().Run();
            }
            catch (Exception)
            {
                Log.Fatal("Uygulama başlayamadı bile.");
            }
            finally
            {
                Log.CloseAndFlush();
            }

```

Burada try cath finally ekledik. Daha sonra CreateHostBuilder try içine aldık ve uygulamadan başlamadan önce bir information yazdırdık. Eğer uygulama başlamada başarız olursa Fatal log'u yazdırıyoruz.

9.) CreateHostBuilder metodumuza serilog'u ekleyelim. CreateHostBuilder  aşağıdaki gibi değiştirebilirisiniz.

```
   public static IHostBuilder CreateHostBuilder(string[] args)
        {
          return Host.CreateDefaultBuilder(args)
                        .UseSerilog()
                        .ConfigureWebHostDefaults(webBuilder =>
                        {
                            webBuilder.UseStartup<Startup>();
                        });
        }
```

10.) Şimdi sıra serilog'u "appsettings.Production.json"dan configure etmeye sıra geldi.

İlkbaşta aşağıdaki nuget paketlerini projemize ekleyelim : 

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/68a38gttg5k4ezsnghfa.png)

Not : Enrichers, strucutal logging'imizi zenginleştirmek için kullanacağımız bilgilerdir.

appsettings.production.json
```
{
  "Serilog": {
    "MinimumLevel": {
      "Default": "Information",
      "Microsoft": "Warning"
    },
    "Enrich": [ "WithMachineName", "FromLogContext", "WithProcessId", "WithThreadId" ],
    "WriteTo": [
      {"Name": "Console"}
    ]
  }
}
```
 11.) Serilog'u pipeline'ımıza ekleyelim : 

```
.
.
.
            app.UseStaticFiles(); // buradan sonra
            app.UseSerilogRequestLogging(); // burayı ekleyelim 
            app.UseRouting();
.
.
.

```

Configure metodumuz aşağıdakine benzeyecektir : 

```
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseSerilogRequestLogging();
            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
```

12.) Uygulamamızı çalıştıralım terminal'de aşağıdaki mesaj görmeniz gerekmektedir : 

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7qpm5m36t6zzctyw2g68.png)
 



13.)  Şimdi hatırlıyorsanız appsettings.Production.json dosyamız aşağıdaki gibiydi : 


appsettings.Production.json
```
{
  "Serilog": {
    "MinimumLevel": {
      "Default": "Information",
      "Microsoft": "Warning"
    },
    "Enrich": [ "WithMachineName", "FromLogContext", "WithProcessId", "WithThreadId" ],
    "WriteTo": [
      {"Name": "Console"}
    ]
  }
}
```
Bu configurationları açıklayalım : 

a.) MinimumLevel loglama default olarak veya namespace bağlı olarak loglama seviyesini belirler.

b.) Enrich zenginleştirme demektir. Loglarımızıa hangi bilgiler ile zengileştireceğimizi bilgilendirmek için kullanılırız.

Daha fazla enrichers'ı https://github.com/serilog/serilog/wiki/Enrichment bu sayfadan bulabilirsiniz.

c.) WriteTo sink'leri yani loglarımızı nereye yazacağımızı belirtiğimiz yerdir.

Daha fazla sink'i buradan bulabilirsiniz : https://github.com/serilog/serilog/wiki/Provided-Sinks#list-of-available-sinks

14.) appsettings.Production.json dosyamızı bir dosyaya yazdırmak istersek nasıl configure ederiz ? Sink olarak aşağıdaki eklersek File olarak yazdırabiliriz log'larımızı : 

Not: Bir klasör yaratınız ve yolunu path'deki "klasörün\\tam\\yolu" olan yere yapıştırınız.



```
"WriteTo": [
      { "Name": "Console" },
      {
        "Name": "File",
        "Args": {
          "path": "klasörün\\tam\\yolu\\example.txt",
          "outputTemplate": "{Timestamp:G} {Message} {NewLine:1} {Exception:1}"
        }
      }
    ]
```

Gördüğünüz üzere file sink'ini de configuration olarak ekledik.

Son olarak tam anlamıyla appsettings.Production.json şöyle gözükmelidir :

```
{
  "Serilog": {
    "MinimumLevel": {
      "Default": "Information",
      "Microsoft": "Warning"
    },
    "Enrich": [ "WithMachineName", "FromLogContext", "WithProcessId", "WithThreadId" ],
    "WriteTo": [
      { "Name": "Console" },
      {
        "Name": "File",
        "Args": {
          "path": "klasörün\\tam\\yolu\\example.txt",
          "outputTemplate": "{Timestamp:G} {Message} {NewLine:1} {Exception:1}"
        }
      }
    ]
  }
}
```
Uygulamayı çalıştırsanız "klasörün/tam/yolu/example.txt" olarak verdiğiniz yola loglar yazılır.

15.) Şimdiye kadar console ve txt dosyasına loglar yazmayı öğrendik. Ya  structural logging yapmak istersek ? Örneğin bir json dosyası olarak loglama yapmak istersek ?

O zaman bir file sink daha ekleyip formattını json yapmamız gerekir, hadi o zaman yapalım :

```
"WriteTo": [
      { "Name": "Console" },
      {
        "Name": "File",
        "Args": {
          "path": "klasörün\\tam\\yolu\\example.txt",
          "outputTemplate": "{Timestamp:G} {Message} {NewLine:1} {Exception:1}"
        }
      },
      {
        "Name": "File",
        "Args": {
          "path": "klasörün\\tam\\yolu\\example.json",
          "formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog"
        }
      }
    ]
```

Not : formatter için daha fazla bilgiyi şuradan edinebilirsiniz :  https://github.com/serilog/serilog-formatting-compact 

Şimdi uygulamayı çalıştıralım ve "klasörün\\tam\\yolu\\example.json" dosyamıza bakalım, gördüğünüz üzere loglarımız yazıldı.

16.) Şimdiye kadar görüğümüz şeyler güzel olsa da bize daha iyi bir şey lazım sonuçta structural logging yapmak istiyoruz.

O zaman sizi seq ile tanıştırayım : https://datalust.co/download

Seq'i indirip kurun. Ne işe yaradığını görsel olarak göreceksiniz zaten az sonra.

17.) Sink olarak seq'i nugetten projemize dahil edelim : 

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8wuvujrk059v5c0a6knv.png)

18.)  Seq configuration olarak ekleyelim : 

```
      {
        "Name": "Seq",
        "Args": {
          "serverUrl": "http://localhost:5341/"
        }
      }
```

appsettings.Production.json son hali : 
```
"WriteTo": [
      { "Name": "Console" },
      {
        "Name": "File",
        "Args": {
          "path": "C:\\Users\\musta\\Desktop\\seri.txt",
          "outputTemplate": "{Timestamp:G} {Message} {NewLine:1} {Exception:1}"
        }
      },
      {
        "Name": "File",
        "Args": {
          "path": "C:\\Users\\musta\\Desktop\\seri.json",
          "formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog"
        }

      },
      {
        "Name": "Seq",
        "Args": {
          "serverUrl": "http://localhost:5341/"
        }
      }
    ]
```

Not : serverUrl yerine seq'in portunu sizde nasılsa onu vermelisiniz.

19.) Uygulamanızı çalıştırın ve http://localhost:5341 (serverUrl) adresine gidin, ve loglarınızın aşağıdaki gibi loglandığını göreceksiniz : 

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xjkuqetbkk9pddc646vc.png)

20.) Seq arayüzü ile biraz haşır neşir olmanızı tavsiye ederim.

Bir dahaki yazımda görüşmek dileğiyle.

En iyi dileklerim ile.

Mustafa Samed Yeyin.