Share via


Service Fabric uygulamanıza günlük kaydı ekleme

Uygulamanız, sorunlar oluştuğunda adli hata ayıklamak için yeterli bilgi sağlamalıdır. Günlüğe kaydetme, Service Fabric uygulamanıza ekleyebileceğiniz en önemli şeylerden biridir. Bir hata oluştuğunda, iyi günlük kaydı size hataları araştırmanız için bir yol sağlayabilir. Günlük desenlerini analiz ederek uygulamanızın performansını veya tasarımını geliştirmenin yollarını bulabilirsiniz. Bu belgede birkaç farklı günlük seçeneği gösterilmektedir.

EventFlow

EventFlow kitaplık paketi, uygulamaların hangi tanılama verilerini toplayacağını ve bunların nereye çıkış olarak çıkarılacağını tanımlamasına olanak tanır. Tanılama verileri performans sayaçlarından uygulama izlemelerine kadar her şey olabilir. Uygulamayla aynı işlemde çalıştığından iletişim yükü en aza indirilir. EventFlow ve Service Fabric hakkında daha fazla bilgi için bkz. EventFlow ile Azure Service Fabric Olay Toplama.

Yapılandırılmış EventSource olaylarını kullanma

kullanım örneğine göre ileti olaylarını tanımlama, olayla ilgili verileri olay bağlamında paketlemenize olanak tanır. Belirtilen olay özelliklerinin adlarına veya değerlerine göre daha kolay arama yapabilir ve filtreleyebilirsiniz. İzleme çıkışının yapılandırılması okumayı kolaylaştırır, ancak her kullanım örneği için bir olay tanımlamak için daha fazla düşünme ve zaman gerektirir.

Bazı olay tanımları uygulamanın tamamında paylaşılabilir. Örneğin, bir yöntem başlatma veya durdurma olayı bir uygulama içindeki birçok hizmette yeniden kullanılabilir. Sipariş sistemi gibi etki alanına özgü bir hizmetin kendi benzersiz olayı olan bir CreateOrder olayı olabilir. Bu yaklaşım birçok olay oluşturabilir ve potansiyel olarak proje ekipleri arasında tanımlayıcıların eşgüdümünün oluşturulmasını gerektirebilir.

[EventSource(Name = "MyCompany-VotingState-VotingStateService")]
internal sealed class ServiceEventSource : EventSource
{
    public static readonly ServiceEventSource Current = new ServiceEventSource();

    // The instance constructor is private to enforce singleton semantics.
    private ServiceEventSource() : base() { }

    ...

    // The ServiceTypeRegistered event contains a unique identifier, an event attribute that defined the event, and the code implementation of the event.
    private const int ServiceTypeRegisteredEventId = 3;
    [Event(ServiceTypeRegisteredEventId, Level = EventLevel.Informational, Message = "Service host process {0} registered service type {1}", Keywords = Keywords.ServiceInitialization)]
    public void ServiceTypeRegistered(int hostProcessId, string serviceType)
    {
        WriteEvent(ServiceTypeRegisteredEventId, hostProcessId, serviceType);
    }

    // The ServiceHostInitializationFailed event contains a unique identifier, an event attribute that defined the event, and the code implementation of the event.
    private const int ServiceHostInitializationFailedEventId = 4;
    [Event(ServiceHostInitializationFailedEventId, Level = EventLevel.Error, Message = "Service host initialization failed", Keywords = Keywords.ServiceInitialization)]
    public void ServiceHostInitializationFailed(string exception)
    {
        WriteEvent(ServiceHostInitializationFailedEventId, exception);
    }

    ...

EventSource'un genel olarak kullanılması

Belirli olayları tanımlamak zor olabileceğinden, birçok kişi genellikle bilgilerini dize olarak veren ortak bir parametre kümesine sahip birkaç olay tanımlar. Yapılandırılmış yönün çoğu kaybolur ve sonuçları aramak ve filtrelemek daha zordur. Bu yaklaşımda, genellikle günlük düzeylerine karşılık gelen birkaç olay tanımlanır. Aşağıdaki kod parçacığı bir hata ayıklama ve hata iletisi tanımlar:

[EventSource(Name = "MyCompany-VotingState-VotingStateService")]
internal sealed class ServiceEventSource : EventSource
{
    public static readonly ServiceEventSource Current = new ServiceEventSource();

    // The Instance constructor is private, to enforce singleton semantics.
    private ServiceEventSource() : base() { }

    ...

    private const int DebugEventId = 10;
    [Event(DebugEventId, Level = EventLevel.Verbose, Message = "{0}")]
    public void Debug(string msg)
    {
        WriteEvent(DebugEventId, msg);
    }

    private const int ErrorEventId = 11;
    [Event(ErrorEventId, Level = EventLevel.Error, Message = "Error: {0} - {1}")]
    public void Error(string error, string msg)
    {
        WriteEvent(ErrorEventId, error, msg);
    }

    ...

Yapılandırılmış ve genel izleme karmasını kullanmak da iyi sonuç verebilir. Yapılandırılmış izleme, hataları ve ölçümleri raporlamak için kullanılır. Genel olaylar, sorun giderme için mühendisler tarafından kullanılan ayrıntılı günlük kaydı için kullanılabilir.

Microsoft.Extensions.Logging

ASP.NET Core günlüğü (Microsoft.Extensions.Logging NuGet paketi), uygulamanız için standart günlük API'sini sağlayan bir günlük çerçevesidir. Diğer günlük arka uçları için destek ASP.NET Core günlüğe eklenebilir. Bu, çok fazla kod değiştirmek zorunda kalmadan uygulamanızda günlüğe kaydetme işlemi için çok çeşitli destek sağlar.

  1. İzlemek istediğiniz projeye Microsoft.Extensions.Logging NuGet paketini ekleyin. Ayrıca, tüm sağlayıcı paketlerini ekleyin. Daha fazla bilgi için bkz. ASP.NET Core oturum açma.

  2. Hizmet dosyanıza Microsoft.Extensions.Logging için bir using yönergesi ekleyin.

  3. Hizmet sınıfınızda özel bir değişken tanımlayın.

    private ILogger _logger = null;
    
  4. Hizmet sınıfınızın oluşturucusunda şu kodu ekleyin:

    _logger = new LoggerFactory().CreateLogger<Stateless>();
    
  5. Yöntemlerinizde kodunuzu izlemeye başlayın. Birkaç örnek aşağıdadır:

    _logger.LogDebug("Debug-level event from Microsoft.Logging");
    _logger.LogInformation("Informational-level event from Microsoft.Logging");
    
    // In this variant, we're adding structured properties RequestName and Duration, which have values MyRequest and the duration of the request.
    // Later in the article, we discuss why this step is useful.
    _logger.LogInformation("{RequestName} {Duration}", "MyRequest", requestDuration);
    

Diğer günlük sağlayıcılarını kullanma

Bazı üçüncü taraf sağlayıcılar serilog, NLog ve Loggr gibi önceki bölümde açıklanan yaklaşımı kullanır. Bunların her birini ASP.NET Core günlüğe bağlayabilir veya ayrı ayrı kullanabilirsiniz. Serilog, günlükçüden gönderilen tüm iletileri zenginleştiren bir özelliğe sahiptir. Bu özellik hizmet adı, türü ve bölüm bilgilerini çıkarmak için yararlı olabilir. Bu özelliği ASP.NET Core altyapısında kullanmak için şu adımları uygulayın:

  1. Serilog, Serilog.Extensions.Logging, Serilog.Sinks.Literate ve Serilog.Sinks.Observable NuGet paketlerini projeye ekleyin.

  2. ve LoggerConfiguration günlükçü örneğini oluşturun.

    Log.Logger = new LoggerConfiguration().WriteTo.LiterateConsole().CreateLogger();
    
  3. Serilog.ILogger Hizmet oluşturucusunun bağımsız değişkenini ekleyin ve yeni oluşturulan günlükçüye geçin.

    ServiceRuntime.RegisterServiceAsync("StatelessType", context => new Stateless(context, Log.Logger)).GetAwaiter().GetResult();
    
  4. Hizmet oluşturucusunda ServiceTypeName, ServiceName, PartitionId ve InstanceId için özellik zenginleştiricileri oluşturur.

    public Stateless(StatelessServiceContext context, Serilog.ILogger serilog)
        : base(context)
    {
        PropertyEnricher[] properties = new PropertyEnricher[]
        {
            new PropertyEnricher("ServiceTypeName", context.ServiceTypeName),
            new PropertyEnricher("ServiceName", context.ServiceName),
            new PropertyEnricher("PartitionId", context.PartitionId),
            new PropertyEnricher("InstanceId", context.ReplicaOrInstanceId),
        };
    
        serilog.ForContext(properties);
    
        _logger = new LoggerFactory().AddSerilog(serilog.ForContext(properties)).CreateLogger<Stateless>();
    }
    
  5. Serilog olmadan ASP.NET Core kullanıyorsanız kodu da aynı şekilde izleme.

    Not

    Önceki örnekte statik Log.Loggerkullanmamanızı öneririz. Service Fabric, tek bir işlem içinde aynı hizmet türünün birden çok örneğini barındırabilir. statik Log.Loggerkullanırsanız, özellik zenginleştiricilerinin son yazarı çalışan tüm örneklerin değerlerini gösterir. bu, _logger değişkeninin hizmet sınıfının özel üye değişkeni olmasının bir nedenidir. Ayrıca, hizmetler arasında kullanılabilecek ortak kodu kullanıma sunmalısınız _logger .

Sonraki adımlar