Структурний логування на прикладі Serilog і Seq

Seq
Структурний логування робить один невеликий крок вперед у порівнянні зі звичайними записами.

Ідея
Звичайні лог-записи складаються з рядків і для пошуку запису серед масиву тексту нам доводиться використовувати регулярні вирази
_logger.Warning("Запис в лог файл. Пост на хабре ID"+postId); 


Структурний логування зберігає записи у вигляді об'єктів (структур). Наприклад, з допомогою JSON
_logger.Warning("Запис в лог файл. Пост на хабре {ID}", postId); 

Буде збережено два записи:
  1. Шаблон для кінцевого виводу рядка «Запис в лог файл. Пост на хабре {ID}»
  2. Об'єкт, який будемо підставляти в шаблон: {«ID»:1, type:Number}
Головна перевага даного підходу полягає в тому, що тепер можна зберігати об'єкт ID integer у вигляді окремого параметра, наприклад в NoSql БД. І здійснювати зручний і швидкий пошук з використанням типізованих операцій порівняння замість написання регулярних виразів.

Serilog
Однією з зручних бібліотек .NET, які підтримують структурний логування є Serilog.
Бібліотека підтримує всі основні функції логування, які є у log4net, Nlog, та інших відомих бібліотек:
  • Кілька загальноприйнятих типів запису:
    Verbose — саме низкоуровнивое і детальне логування (наприклад, прийшли аргументи метод)
    Debug — дані для налагодження коду, на один рівень вище Verbose (наприклад, який метод запускали, і результат виконання)
    Warning — попередження для бізнес-процесу, не повинно містити Debug дані (наприклад, запустили розрахунок зарплат)
    Error — помилка у програмі, яка не очікували
    Fatal — виняткова помилка зупиняє бізнес процеси додатки (наприклад, перенаправили користувача PayPal і оплата покупця не дорівнює очікуваній сумі).
  • Різні типи зберігання, званих у Serilog стоком: текстовий файл, реляційні БД, NoSql БД, Windows Events, http/s запити, і т. д.
  • Зручна конфігурація через код, так і через .config файли


Отже, після установки Serilog Nuget пакету, налаштовуємо конфігурацію. Зробимо це в коді замість .config файлу.
var logger = new LoggerConfiguration()
.MinimumLevel.Verbose() // ставимо мінімальний рівень в Verbose для тесту, за замовчуванням стоїть Information 
.WriteTo.ColoredConsole() // виводимо дані на консоль
.WriteTo.RollingFile(@"C:\Logs\Log-{Date}.txt") // а також пишемо лог файл, розбиваючи його по даті
// є можливість писати Verbose рівень в текстовий файл, а наприклад, Помилка у Windows Event Logs
.CreateLogger();


Тепер можна передавати об'єкт logger через Dipendency Injection, або відразу його використовувати.
Припустимо ми створюємо програму для діагностики автомобіля і нам необхідна інформація про виробника, серії та дату впуску. І звичайно, щоб все зберігалося у структурному вигляді.


logger.Debug("Request for vehicles {Manufature}, {Series}, {ProductionYear}", "BMW", "F02", new DateTime(2015, 1,1));
// search returns 10 vehicles
logger.Verbose("Found {FoundVehiclesCount}", 10);


Оскільки ми використовували висновок в консоль і файл, то і результат буде у вигляді звичної рядка.


Однією з зручних особливостей є добавка часто використовуваних властивостей. Для web додатка це може бути сесія користувача, відвідуваний URL, дані браузера. У більш загальному випадку можна додати версію програми. Зробити це можна за допомогою властивості Enrich і вже вбудованих класів, або написати свій.

var logger = new LoggerConfiguration()
.Enrich.With<HttpRequestIdEnricher>()
.Enrich.With<HttpRequestUrlEnricher>()
.Enrich.With<HttpRequestUserAgentEnricher>()
.Enrich.With<UserNameEnricher>();
.Enrich.WithProperty("ApplicationVersion", config.ApplicationVersion)
.CreateLogger();


Для зручного виведення на консоль або текстовий файл складних об'єктів краще підказати шаблоном Serilog про те, що використовуємо саме складний об'єкт, а не примітивний тип, додавши символ @. Інакше буде виводиться typeof(MyClass).ToSting().

logger.Debug("We are using anonymous object instead of simple string/integer {@Car}", new {Manufacture="Toyota", Production = new DateTime(2015, 1,1)});


Seq
Додаток Seq приходить на допомогу для зручного зберігання та пошуку структурних логів.
Працює Seq у вигляді сервісу windows, який приймає REST-запити, а всередині зберігає дані в NoSql БД.

Після установки Seq необхідно також додати в додаток Serilog.Sinks.Seq Nuget пакет. А далі подружити наш Serilog з Seq.

var logger = new LoggerConfiguration()
.MinimumLevel.Verbose()
.WriteTo.Seq("http://localhost:5341")
.CreateLogger();


Тепер можна зручно робити пошук по наших полях, включаючи порівняння чисел та дат


Параметри пошуку можна зберігати й використовувати в інших частинах програми. Додаємо Environment в Dashboard

А можна додати real-time Dashboard відображення помилок, які прийшли саме від програми «MyApp», версії 1.2.1» і відбулися в методі «Repository.GetUserByIdAndPassword()».

Бізнес вимоги
Як і будь-яку нову, модну, що світиться програму треба перевіряти, задаючи питання:
«Яку користь несе ця програма для бізнесу?», «Яке завдання вона вирішує, за яку ціну?».
Часто ставлення логування цілі зводяться до
  • Зменшити трудовитрати по пошуку помилок у програмі.
  • Мати можливість відновити історію дій користувача. Наприклад, для з'ясування чи дійсно товар оплачений.
  • Бути в курсі помилок, так як вони ведуть до втрат користувачів і прибутку.
Якщо перші два пункти вирішуються детальними записами і зручним пошуком, інформування про помилки часто пропускають. Я це називаю «спокоєм в невіданні». Відкриємо журналів подій Windows і виявиться, що майже на кожному сервері є програми, які сипляться з критичними помилками.

За допомогою розширень Seq можна інформувати про події, що відбуваються. Приміром, відразу посилати повідомлення програмісту/адміністратору, якщо сталась критична помилка. І відправляти список всіх помилок, що сталися за день або тиждень. Налаштувати розширення можна в розділі Seq -> Settings -> Apps


Мінуси структурного логування
До мінуса структурного логування можна віднести необхідність у визначенні параметрів, за якими буде проводитися пошук. Вони ж потім будуть використовуватися для створення NoSql індексів. Якщо забули визначити параметр, то пошук зводиться до старого сканування рядків через регулярні вирази.
Гігантський крок у цьому напрямку робить додаток Splunk. Ідея полягає в зборі строкових даних, абсолютно будь-яких і в будь-якому форматі (логи програми, події про роботу ОС, тощо). А далі приголомшливе розбиття рядка в залежності від запитів і динамічне побудова результату через Map/Reduce. Splunk є великою інфраструктурою для збору та аналізу даних, і виходить за тему логування та даній статті.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.