İçeriğe geç

ASP.NET Core Serisi 02: NLog ve GrayLog Kullanarak Log’lama İşlemlerini Merkezileştirme

Selam millet.

ASP.NET Core ile ilgili olan bu 2. serimizde, NLog library’sini kullanarak uygulama içerisinde tutmak istediğimiz çeşitli log message’larını, GrayLog üzerinde tutabilme işlemini gerçekleştireceğiz.

Eminim belki bir çoğumuz geleneksel .NET Framework üzerinde geliştirdiğimiz uygulamalarda, NLog library’si ile “NLog.Targets.Gelf” paketini kullanarak, log’lama işlemlerini GrayLog üzerinde gerçekleştirmişizdir. Bir önceki seri olan “ASP.NET Core Serisi 01: Dapper ile RESTful API Tasarlama ve Azure App Services’e Deploy” makalesinde, bu aralar ASP.NET Core üzerinde çok fazla çalıştığımdan bahsetmiştim. Şuanda çalıştığım firmada yeni geliştirdiğimiz API’ları, ASP.NET Core üzerinde geliştirmeye çalışıyoruz. Bunun yanında mevcut .NET stack’imiz içerisindeki tüm log’lama işlemlerimizi, GrayLog üzerinde gerçekleştirerek log’lama işlemlerini merkezileştirmiş durumdayız.

Kısaca öneminden bahsetmek gerekirse eğer:

Merkezi log’lama işlemleri özellikle son kullanıcıyı mutlu edebilmek için çok önemlidir. Ayrıca sistem performansını sürekli iyileştirebilmek ve hataların hızlıca farkına varabilmek için de çok önemli olduğu aşikardır.

Her neyse, ASP.NET Core üzerinde development yaparken farkettim ki, NLog‘un “NLog.Targets.Gelf” paketi henüz ASP.NET Core ile uyumlu bir hale getirilmemiş (yada ben bulamadım). Bende bir katkıda bulunabilmek için ilgili kaynak kodu GitHub üzerinden fork’layarak, “NLog.Web.AspNetCore.Targets.Gelf” ismi altında ASP.NET Core’a uyumlu bir hale getirdim ve NuGet server üzerine publish ettim.

Peki Neden Merkezi Bir Log Sistemine Sahip Olmalıyız?

Günümüz çağında sabit duran sistemlerden çok, hızla değişen ve yaşayan dinamik sistemlere sahibiz. Bununla birlikte dağıtık ve otonom bir şekilde yaşayan microservice’ler, kendini bazı rule’lara göre dinamik olarak scale eden yapılarada. Bu yaşayan sistemlerin sürekliliklerini sağlayabilmek için, infrastructure’da neler olup bittiğini bir noktada biliyor olmamız lazım. Bu sayede özellikle son kullanıcıyı mutlu edebilmek için değişen uygulamaları takip edebilmek, performansı sürekli iyileştirebilmek ve hatalar karşısında iz sürebilerek hızlı aksiyonlar alabilmek mümkün olmaktadır. Özellikle distributed bir şekilde yaşayan sisteme sahipsek ve log yapılarımızı merkezi bir platform üzerine taşırsak, bütün sistem içerisinde belirli bir anda herhangi bir aksiyon gerçekleştiği an, tek bir noktadan monitor edebilme işlemi çok daha kolay olacaktır.

Merkezi log yönetimi işlemini gerçekleştirebilmek için, Splunk, Graylog, Logstash, Logwatch gibi bir çok alternarif tool vardır. Biz bu makale içerisinde ise ASP.NET Core application’ı geliştirirken, NLog library’si ile log’larımızı GrayLog içerisinde tutabilme işlemini gerçekleştireceğiz.

Neden GrayLog?
  • Herşeyden önce başlı başına open source bir log yönetim çözümüdür.
  • Log tutma işlemi için “Syslog, GELF, TCP, UDP, AMQP” gibi bir çok input’u desteklemektedir.
  • Message’ları ElasticSearch üzerinde depolamaktadır ve buda arşivler üzerinde hızlı aramayı sağlamaktadır.
  • Istatistik işlemleri için ise MongoDB‘yi kullanmaktadır.
  • Log’ları sınıflandırabilmek ve grafiksel işlemler gerçekleştirebilmek mümkündür.
  • Istenilen durumlara göre proactive alert’lar üretebilmek kolaydır.

ve dahası…

Docker Üzerinde GrayLog Kurulumu

Aşağıdaki “docker-compose.yml” dosyasını kullanarak, GrayLog‘u Docker üzerinde çalıştıracağız.

version: '2'
services:
  some-mongo:
    image: "mongo:3"
  some-elasticsearch:
    image: "elasticsearch:2"
    command: "elasticsearch -Des.cluster.name='graylog'"
  graylog:
    image: graylog2/server:2.1.1-1
    environment:
      GRAYLOG_PASSWORD_SECRET: somepasswordpepper
      GRAYLOG_ROOT_PASSWORD_SHA2: 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
      GRAYLOG_WEB_ENDPOINT_URI: http://192.168.99.100:9000/api
    links:
      - some-mongo:mongo
      - some-elasticsearch:elasticsearch
    ports:
      - "9000:9000"
      - "12201:12201/udp"
      - "1514:1514/udp"

Bu işlem için “aspnetcore-graylog-sample-with-nlog” isminde bir folder oluşturalım ve “docker-compose.yml” dosyasını, içerisine kopyalayalım. Bu işlemin ardından herhangi bir command tool’u kullanarak aşağıdaki komutu çalıştıralım.

docker-compose up

Bu işlemin ardından GrayLog UI’ına, “http://192.168.99.100:9000” bu URL üzerinden erişebiliriz.

NOT: Log in işlemi için giriş bilgileri “admin”, “admin” şeklindedir.

GrayLog kurulumu neredeyse hazır. NLog ile logları GrayLog üzerinde tutabilmemiz için yapmamız gereken tek bir şey kaldı. Log tutabilme işlemi için GrayLog‘un, “GELF” gibi bir çok input’u desteklediğinden söz etmiştik. GELF input’unu kullanabilmek için GrayLog UI’ı üzerinden, “System / Inputs > Inputs” menüsüne girelim.

Buradan ise “Select input” drop down menüsünden, “GELF UDP” seçeneğini seçerek “Launch new input” butonuna tıklayalım. Karşımıza çıkacak olan ekrandan ise, “Title” bölümüne herhangi bir isim vererek doldurmamız yeterli olacaktır. Artık “GELF UDP“, “12201” numaralı port altından dinlemeye başlayacaktır.

ASP.NET Core NLog Implementasyonu

GrayLog kurulumuna başlamadan önce “aspnetcore-graylog-sample-with-nlog” isminde bir folder oluşturmuştuk. Command tool’u ile tekrardan aynı folder içerisine gelerek, aşağıdaki gibi bir ASP.NET Core MVC projesi oluşturalım.

dotnet new mvc

Oluşturma işleminin ardından, Visual Studio Code açılacaktır.

Implementasyon işleminden önce projeye NuGet server üzerinden “NLog.Web.AspNetCore” ve log message’larını GrayLog2‘ye push yapabilmemiz için gerekli olan “NLog.Web.AspNetCore.Targets.Gelf” paketini aşağıdaki gibi dahil etmemiz gerekmektedir.

Paketleri projeye dahil ettikten sonra aşağıdaki “nlog.config” dosyasını projenin root klasörü altına koyalım.

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      throwExceptions="false"
      internalLogLevel="Off"
      internalLogFile="c:\temp\internal-nlog.txt">
  <extensions>
    <add assembly="NLog.Web.AspNetCore"/>
    <add assembly="NLog.Web.AspNetCore.Targets.Gelf"/>
  </extensions>
  <targets>
    <target xsi:type="File" name="errorFile" filename="C:\@Logs\${shortdate}-${level}-AspNetCoreTest.txt" layout="${longdate}|${level:upperCase=true}|${logger}|${aspnet-Request-Method}|url: ${aspnet-Request-Url}${aspnet-Request-QueryString}|${message}" concurrentWrites="false" />
    <target xsi:type="Gelf" name="graylog" endpoint="udp://192.168.99.100:12201" facility="console-runner" SendLastFormatParameter="true" />
  </targets>
  <rules>
    <logger name="*" minlevel="Error" writeTo="errorFile, graylog" />
  </rules>
</nlog>

Burada iki adet target’a sahibiz. Birincisi file’a log atabilmek için, diğeri ise Gelf UDP üzerinden message’ları GrayLog2 üzerinde saklayabilmek için. Örneğimiz gereği sadece error message’larını log’layacağız.

Şimdi “Startup.cs” içerisine girelim ve aşağıdaki gibi NLog için, bir kaç satır kod ekleyelim.

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddNLog();
    app.AddNLogWeb();

    env.ConfigureNLog("nlog.config");

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseBrowserLink();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseStaticFiles();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

Yukarıdaki kod bloğunda, NLog‘u bir logger olarak kullanacağımızı belirledik. Hemen ardından ise “nlog.config” file’ının relative path’ini set ettik. Tüm işlemler bu kadar.

HomeController” içerisine girelim ve aşağıdaki gibi bir log atalım.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace aspnetcore_graylog_sample_with_nlog.Controllers
{
    public class HomeController : Controller
    {
        private ILogger _logger;

        public HomeController(ILogger logger)
        {
            _logger = logger;
        }
        
        public IActionResult Index()
        {
            _logger.LogError("Something happened.");

            return View();
        }
    }
}

ILogger” interface’i constructor üzerinden, otomatik olarak ilgili type’da inject olacaktır. Buradaki index action’a bakarsak eğer, action execute olacağı zaman “Something happened.” şeklinde bir error message’ı log’ladık.

Şimdi projeyi, terminal üzerinden “dotnet run” komutu ile çalıştıralım. Projenin çalıştırılmasından sonra “http://localhost:5000” URL’i üzerinden projeye erişim sağlayalım. Buradaki index action’ı execute edilecektir ve ardından “C:\@Logs” path’i altında aşağıdaki gibi bir log message’ı tutulacaktır.

GrayLog UI üzerinden ise “System / Inputs > Inputs > Show received messages” path’ini izlersek, GrayLog üzerine gelen message’ı da aşağıdaki gibi görebiliriz.

Sonuç

ASP.NET Core üzerinde NLog ve NLog’un GELF target’ını (.NET Core için benim transforme ettiğim) kullanarak, GrayLog2 üzerine log atabilme işlemini gerçekleştirdik. Bu makale içerisindeki asıl odak noktamız da buydu. Bunların yanında merkezi bir log yönetim sisteminin de, enterprise seviyedeki projeler için ne denli önemli olduğunu tekrardan hatırlatmak istedim.

Gelecek .NET Core makalelerinde görüşmek üzere.

https://github.com/GokGokalp/aspnetcore-graylog-sample-with-nlog/tree/master
https://github.com/GokGokalp/NLog.Web.AspNetCore.Targets.Gelf

Bazı Referanslar

https://github.com/Graylog2/graylog-docker
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging

Kategori:ASP.NET CoreLogging

13 Yorum

  1. Ahmet Ahmet

    Asp.net Core serisinin devamını bekliyoruz hocam. Teşekkürler.

  2. Naser Naser

    Com iyi
    tesekkurer

  3. Zain Zain

    Some how I am not receiving messages in Gray log by running .net core application any idea.

    • Did you create GELF UDP input on Graylog web interface? and how is your nlog.config file?

  4. Yılmaz Yılmaz

    Graylog’a query stringten bazı değerleri de göndermek istiyorum. Bu tip extra parametreleri nasıl tanımlayabilirim?

  5. Baran Baran

    Çok başarılı! Kurumsal/profesyonel uygulamalarda kullanılan çözümlerin ve tecrübelerin paylaşılması çok değerli cidden. Bir öğrenci olarak bu tarz yazıları çok bilgilendirici buluyorum. Teşekkür ederim..

  6. Samet Kaymak Samet Kaymak

    Merhabalar hocam firma içerisinde graylog kullanılıyor ama yeni gelen geliştirme maddesi için sistem de bir işlem yapılırken graylog sunucusuda çalışıyormu diye kontrol edip eğer çalışıyorsa işlemi yaptırıcam eğer graylog çalışmıyorsa yaptırmayaçağım bu konuda yardımcı olurmusunuz.

    öncesinde sunucuya ping atarak sunucu ayaktaysa bu işlemi yapıyordum ama artık grayloga bakmamız istendi.

    • Hmm, neden böyle bir ihtiyaç var? Graylog setup’ınız highly available bir setup’a sahip değil mi? Bu tarz backing service’lere de nasıl database’e güveniyorsak, onlara da güveniyor olmamız gerek aslında. Uzun zamandır graylog kullanmıyorum ama GrayLog’da bir API’a sahipti. https://docs.graylog.org/docs/rest-api Burada da mevcut. Cluster bilgilerini alabileceğiniz endpoint üzerinden istediğiniz kontrolleri yapabilirsiniz sanırım.

Zain için bir yanıt yazın Yanıtı iptal et

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Bu site, istenmeyenleri azaltmak için Akismet kullanıyor. Yorum verilerinizin nasıl işlendiği hakkında daha fazla bilgi edinin.