Merhaba,
Bugün sizelere en basit anlamda nasıl loglama yapabiliriz anlatacağım.
Loglama konusunda bir çok ileri seviye araç bulunmakta. DB’ye yazan, dosyaya yazan, hepsini alıp text search sisteme aktaran vs gibi ileri seviye araçlar mevcut.
Ben bugün benim için yeterli olacak, küçük seviyede bir log sisteminden bahsetmek istiyorum.
Yapacağım işlem: Projede bir hata olduğunda, .txt dosyasına sadece bu hatayı basmak olacak.
Bu işlemler için .Net Core bize, ILogger isimli bir interface sunmakta. Tüm işlemleri bu arkadaş üzerinden yapabiliyoruz.
Hali hazırda bizlere Consola Log, Debug Log ve Event Log atma işlevlerini sunuyor.
Ben ise bir dosyaya log atmak istiyorum. Bunun için bizim gidip ILogger Interfacinden türüyen bir extension yazmamız gerekiyor.
İşte bu noktada ben bu extensionu kendim yazmak yerine, hali hazırdaki Serilog.Extensions.Logging.File kütüphanesini kullanacağım.
* Boş bir api projesi açıp başlayalım.
* Nugetlardan Serilog.Extensions.Logging.File kütüphanesini yükleyelim. (Projeye sağ tık > Manage Nuget Packages…)
Gerekli kodları yazalım.
.Net Core 6.0 ve üstü için Program.cs aşağıdaki tanımları yapıyoruz.
Log dosyasının oluşturulacağı dizini ve loglamanın yapılmasını istediğim minimum seviyeyi belirttim.
builder.Services.AddLogging(log => { log.ClearProviders(); log.AddFile($"{Directory.GetCurrentDirectory()}\\LogFile\\log.txt", LogLevel.Error); });
.Net Core 5.0 ve altı için ConfigureServices altına şu kodlar eklenir.
services.AddLogging(log => { log.ClearProviders(); log.AddFile($"{Directory.GetCurrentDirectory()}\\APILog\\log.txt", LogLevel.Error); });
* Log atmak istediğimiz bir controllerı açıp log kısımlarını yazıyoruz.
ILogger
Daha sonra kullanmak istediğimiz yerde _logger.LogError(“mesaj”); kodu ile istediğmiz yerde hata mesajını dosyaya yazabiliyoruz.
Aşağıda WeatherForecastController clasına TestMethod isimli yeni bir method ekledim. a değişkeni içine eğer test yazarsak hata veren ve log atan bir if bluğu koydum.
using Microsoft.AspNetCore.Mvc; namespace LogExample.Controllers { [ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; private readonly ILogger<WeatherForecastController> _logger; public WeatherForecastController(ILogger<WeatherForecastController> logger) { _logger = logger; } [HttpGet(Name = "GetWeatherForecast")] public IEnumerable<WeatherForecast> Get() { return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = Random.Shared.Next(-20, 55), Summary = Summaries[Random.Shared.Next(Summaries.Length)] }) .ToArray(); } [HttpGet] [Route("TestMethod")] public ActionResult TestMethod(string a) { if(a == "test") { _logger.LogError("Error, test yazılamaz."); return BadRequest("test yazılamaz"); } return Ok("Ok"); } } }
Çalıştırıp bakıyoruz…
BadRequest aldığımızı görebilirsiniz. Projeme gidip Log klasörüm ve log.txt oluşmuş mu bakıyorum.
Gördüğünüz üzere, log.txt dosyam oluşmuş ve içini doldurabilmişim. İşlemler bu kadar.
Basit anlamda log yönetimini bu şekilde yapabilirsiniz.
Bu size yeterli gelmiyorsa, ben tüm hataları tek bir yerden ele alıp loglamak yönetmek istiyorum diyorsanız. Bir Error handling mekanizması kurup uygulamayı sarmallayıp, tüm hataları yönetmelisiniz.
Bunun için bir Middleware classı yapmalısınız. Bu middleware içinde gelen giden istekleri kontrol edip, hata dönenleri loglayabilirsiniz.
Bunun için bizim projemize şu eklemeleri yaptım.
ErrorLogMiddleware isimli bir class yaptım;
using LogExample.Controllers; namespace LogExample { public class ErrorLogMiddleware { private readonly RequestDelegate _next; private readonly ILogger<ErrorLogMiddleware> _logger; public ErrorLogMiddleware(RequestDelegate next, ILogger<ErrorLogMiddleware> logger) { _next = next; _logger = logger; } public async Task Invoke(HttpContext httpContext) { try { await _next.Invoke(httpContext); } catch (Exception ex) { httpContext.Response.StatusCode = 500; await httpContext.Response.WriteAsync(ex.ToString()); _logger.LogError("Sistem hatası: " + ex.Message); } } } }
Program.cs dosyama aşağıdaki satırı ekledim.
app.UseMiddleware<ErrorLogMiddleware>();
.Net 5.0 kullanıyorsanız Configure methodu altına yazmalısınız.
Sonrasında WeatherForecastController.cs dosyama gelip, aşağıdaki methodu ekledim.
[HttpGet] [Route("TestMethod2")] public ActionResult TestMethod2(string a) { if (a == "test") { throw new Exception("Parametre olarak test değeri yazılamaz."); } return Ok("Ok"); }
Evet artık hazırız. Deneme yapalım. Bu kez Postman aracılığıyla istek gönderdim. Çıktıyı daha güzel gösteriyor.
Cevap 500 geldi. Log dosyamıza da bakıyoruz. (Öncesinde log.txt içini temizledim, tek satır görebilmek için).
Logumuz atılmış gördüğünüz gibi. İşlemler bu kadar.
İster bir ara katman yapıp try catch ile bunları yönetin, isterseniz controllerda badrequest ya da catch atacağınız yerlerde istediğiniz logları alıp işleyin.
Umarım işinize yarar.
Projenin tam halini githup sayfamda bulabilirsiniz: https://github.com/semihcelikol/LogExample
Bu konuda daha detaylı ve ileri seviye bilgiler edinmek istiyorsanız Salih abinin kanalını önerebilirim. Temiz ve yalın bir anlatımı var. Tavsiye ederim.
Bazı videoları:
https://www.youtube.com/watch?v=RcmdLfcFduE
https://www.youtube.com/watch?v=b8OpBUUo3c8
Sağlıklı günler dilerim. İyi çalışmalar