Şu anda üzerinde çalıştığım sistem, olay odaklı bir mimari ve mesajlaşma kullanır, böylece sistemimizdeki çoğu eylem bir komutun sonucudur ve olaylarla sonuçlanır (standart bir delege olayı yerine gönderilen DTO sınıfları olarak). Tek amacı günlüğü işlemek olan olay işleyicileri ekliyoruz. Bu tasarım kendimizi tekrarlamamıza yardımcı olur ve ayrıca işlevsellik eklemek / değiştirmek için mevcut kodu değiştirmek zorunda kalmazsınız.
Aşağıda, uygulamamızın dar bir bölümünden (içe aktardığımız belirli bir içerik kaynağıyla ilgili olanlar) günlüğe kaydedilecek tüm olayları işleyen böyle bir günlük kaydı sınıfına bir örnek verilmiştir.
Bunun genellikle en iyi uygulama olduğunu söylemeyeceğim, çünkü ne sıklıkta ve nasıl oturum açacağım konusunda fikrimi değiştiriyorum - ve bir sorunu teşhis etmek için her gün bir günlük kullanmam gerektiğinde, kaçınılmaz olarak iyileştirmeler yapmanın yollarını buluyorum kaydettiğim bilgiler.
Bununla birlikte, ilgili bilgilerin kaydedilmesinin (özellikle Ctrl-F / aranabilir bir şekilde bulun) en önemli kısım olduğunu söyleyeceğim.
İkinci en önemli bölüm, günlük kodunu ana mantığınızdan uzaklaştırmaktır - çirkin ve uzun bir yöntem yapabilir ve çok hızlı bir şekilde kıvrılır .
public class MctLogger :
IEventHandler<StoryImported>,
IEventHandler<StoryScanned>,
IEventHandler<SourceDirectoryMissing>,
IEventHandler<SourceDirectoryAccessError>,
IEventHandler<CannotCreateScannedStoryDirectory>,
IEventHandler<CannotReadStoryDocument>,
IEventHandler<StorySkippedPastCutoff>,
IEventHandler<StorySkippedDuplicateUniqueId>,
IEventHandler<StorySkippedByFilter>
{
public void Observe(StoryImported e)
{
var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.StoryImported");
log.Info("Story Unique ID: {Story.UniqueId}, Content ID: {ContentId}, Title: {Story.Headline}".SmartFormat(e));
}
public void Observe(StoryScanned e)
{
var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.StoryScanned");
log.Info("Story Unique ID: {Story.UniqueId}, File: {FilePath}, Title: {Story.Headline}".SmartFormat(e));
}
public void Observe(SourceDirectoryMissing e)
{
var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.SourceDirectoryMissing");
log.Error("Directory: " + e.Directory);
}
public void Observe(SourceDirectoryAccessError e)
{
var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.SourceDirectoryAccessError");
log.Error(e.Exception, "Exception: " + e.Exception.Message);
}
public void Observe(CannotCreateScannedStoryDirectory e)
{
var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.CannotCreateScannedStoryDirectory");
log.Error(e.Exception, "Directory: {Directory}, Exception: {Exception.Message}".SmartFormat(e));
}
public void Observe(CannotReadStoryDocument e)
{
var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.CannotReadStoryDocument");
if (e.Exception == null) {
log.Warn("File: {FilePath}".SmartFormat(e));
}
else {
log.Warn(e.Exception, "File: {FilePath}, Exception: {Exception.Message}".SmartFormat(e));
}
}
public void Observe(StorySkippedPastCutoff e)
{
var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.StorySkippedPastCutoff");
log.Warn("Story Unique ID: {Story.UniqueId}, File: {FilePath}, Title: {Story.Headline}".SmartFormat(e));
}
public void Observe(StorySkippedDuplicateUniqueId e)
{
var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.StorySkippedDuplicateUniqueId");
log.Warn("Story Unique ID: {Story.UniqueId}, File: {FilePath}, Title: {Story.Headline}".SmartFormat(e));
}
public void Observe(StorySkippedByFilter e)
{
var log = Slf.LoggerService.GetLogger("RoboChef.Content.Mct.StorySkippedByFilter");
log.Warn("Story Unique ID: {Story.UniqueId}, Reason: {Reason}, File: {FilePath}, Title: {Story.Headline}".SmartFormat(e));
}
}