Переваги структурованої реєстрації та основної лісозаготівлі


110

Ми створюємо нову програму, і я хотів би включити структурований журнал. Моя ідеальна настройка буде щось на кшталт Serilogнашого C # коду та Bunyanдля нашого JS. Вони могли б вписатись fluentdі потім могли б вийти на будь-яку кількість речей, я думав спочатку elasticsearch + kibana. У нас вже є база даних MySQL, тому в короткий термін я більше зацікавлений у налаштуванні Serilog + Bunyan і розробниках для її використання, і ми можемо увійти в MySQL, поки ми забираємо трохи більше часу, приводячи вільне та інше.

Однак один з наших більш досвідчених кодерів вважає за краще просто зробити щось на кшталт: log.debug("Disk quota {0} exceeded by user {1}", quota, user);використання, log4netа потім просто запуск вибраних операторів проти MySQL, наприклад:SELECT text FROM logs WHERE text LIKE "Disk quota";

Зважаючи на це, який підхід кращий та / або які речі нам потрібно враховувати при виборі типу системи лісозаготівлі?


Я погоджуюся з внесеними правками. Я не стільки намагаюся довести щось комусь, скільки намагаюся зрозуміти переваги та відмінність в структурованому порівнянні з базовим веденням журналу. На мій погляд, структурованість дає нам набагато більшу гнучкість, особливо в джерелах журналів, і як ми потім здатні відображати їх дані. У моєму розумінні я не можу пояснити, чому базовий журнал та пошук MySQL краще / гірше, ніж структурований журнал.
DTI-Matt

2
@ Структурований журнал DTI-Matt serilog - це просто основний журнал, лише він форматує об’єкти, які ви друкуєте до нього - те, що ви можете зробити самостійно, перевантаживши ToString дуже легко. Більш важливим аспектом є конфігурація та управління файлами журналів, не один спосіб форматування рядка над іншим, інший - це продуктивність. Якщо розробник хоче використовувати log4net (що є гарною лівою реєстрації), то ваш вибір серілогів (який виглядає круто) - одне з таких «рішень у пошуку проблеми».
gbjbaanb

@ DTI-Matt Якщо дивитися на серілог, він дуже схожий на log4net. log4net обробляє створення структурованих журналів на конфігурації. Не потрібно шукати повідомлення в журналі, оскільки ви можете налаштувати додаткову інформацію та записати в таблицю. Також налаштувати log4net для fluentd tipstuff.org/2014/05 / ...
RubberChickenLeader

Слідкуйте, що тут є деякі дурні, які не розуміють ідеї концептуальних питань. запитання про напрямок додатків баз даних при спробі отримати обробку їхніх можливостей ETL v. код отримає серйозні зворотні відгуки. Я припускаю, що ваше запитання також буде на рубаючому блоці.
користувач3916597

2
@gbjbaanb Serilog працює так само, як log4net при наданні подій у тексті, але якщо ви використовуєте структурований формат для зберігання журналів, він пов'язує названі властивості з аргументами, які передаються через (тобто для підтримки пошуку / фільтрації без регулярного вираження тощо). ) HTH!
Nicholas Blumhardt

Відповіді:


140

Є два фундаментальні досягнення структуризованого підходу, які неможливо імітувати за допомогою текстових журналів без додаткових зусиль (іноді надзвичайних рівнів).

Типи подій

Коли ви пишете дві події з log4net, як-от:

log.Debug("Disk quota {0} exceeded by user {1}", 100, "DTI-Matt");
log.Debug("Disk quota {0} exceeded by user {1}", 150, "nblumhardt");

Вони дадуть подібний текст:

Disk quota 100 exceeded by user DTI-Matt
Disk quota 150 exceeded by user nblumhardt

Але, що стосується машинної обробки, це лише два рядки різного тексту.

Ви можете знайти всі події "Дискова квота перевищена", але спрощений випадок пошуку подій like 'Disk quota%'впаде, як тільки відбудеться інша подія, схожа на:

Disk quota 100 set for user DTI-Matt

Текстовий журнал викидає інформацію, яку ми спочатку маємо про джерело події, і це потрібно реконструювати, читаючи журнали, як правило, з більш детальними виразами відповідності.

На противагу цьому, коли ви пишете наступні два події Serilog :

log.Debug("Disk quota {Quota} exceeded by user {Username}", 100, "DTI-Matt");
log.Debug("Disk quota {Quota} exceeded by user {Username}", 150, "nblumhardt");

Вони створюють аналогічний вихід тексту до версії log4net, але поза кадром "Disk quota {Quota} exceeded by user {Username}" шаблон повідомлення передається обома подіями.

За допомогою відповідної раковини ви зможете пізніше писати запити where MessageTemplate = 'Disk quota {Quota} exceeded by user {Username}'і отримувати саме ті події, де квота на диск перевищена.

Не завжди зручно зберігати весь шаблон повідомлення з кожною подією журналу, тому деякі занурює хеш шаблону повідомлення в числове EventTypeзначення (наприклад 0x1234abcd), або, ви можете додати збагачувач до трубопроводу журналу, щоб зробити це самостійно .

Це більш тонка, ніж наступна різниця нижче, але надзвичайно потужна при роботі з великими обсягами журналів.

Структуровані дані

Знову ж таки, враховуючи дві події щодо використання місця на диску, це може бути досить просто, використовуючи текстові журнали для запиту конкретного користувача like 'Disk quota' and like 'DTI-Matt'.

Але діагностика виробництва не завжди є такою простою. Уявіть, що потрібно знайти події, де квота на диск перевищила 125 Мб?

З Serilog це можливо в більшості раковин, використовуючи варіант:

Quota < 125

Створення такого роду запит з регулярного виразу є можливим, але це стає нудними швидко і , як правило , закінчується час крайній захід.

Тепер додайте до цього типу події:

Quota < 125 and EventType = 0x1234abcd

Ви починаєте бачити тут, як ці можливості прямо поєднуються, щоб виробнича налагодження з журналами відчувало себе першокласною розробкою.

Ще одна перевага, можливо, не така проста для запобігання випередженням, але після того, як налагодження виробництва буде знято з краху хекерів, регулярно розробляючи журнали, вони більше уважно ставляться до уваги при їх написанні. Кращі журнали -> якісніші програми -> більше щастя навколо.


4
я люблю цю відповідь. дуже добре написана, і я чомусь не можу пояснити, тримає мене на краю сидіння.
jokab

16

Коли ви збираєте журнали для обробки, будь то для розбору в деякій базі даних та / або пошуку згодом оброблених журналів, використовуючи структурований журнал, якась обробка робить простішою / ефективнішою. Аналізатор може скористатися відомою структурою ( наприклад, JSON, XML, ASN.1, будь-яка інша) та використовувати державні машини для розбору, на відміну від регулярних виразів (які можуть бути обчислювально дорогими (відносно) для компіляції та виконання). Розбір тексту у вільній формі, такий як той, запропонований вашим колегою, як правило, покладається на регулярні вирази та покладається на те, що текст не змінюється . Це може зробити синтаксичний розбір тексту у вільній формі досить крихким ( тобто синтаксичний аналіз щільно пов'язаний з точним текстом у коді).

Розглянемо також випадок пошуку / пошуку, наприклад :

SELECT text FROM logs WHERE text LIKE "Disk quota";

LIKEумови вимагають порівняння з кожним textзначенням рядка; знову ж таки, це порівняно обчислювально дорого, особливо коли використовуються символи підстановки:

SELECT text FROM logs WHERE text LIKE "Disk %";

При структурованому веденні журналів повідомлення журналу, пов’язані з помилками на диску, може виглядати так у JSON:

{ "level": "DEBUG", "user": "username", "error_type": "disk", "text": "Disk quota ... exceeded by user ..." }

Поля такого типу структури можуть легко відображатись, наприклад, назви стовпців таблиці SQL, що означає, що пошук може бути більш конкретним / детальним:

SELECT user, text FROM logs WHERE error_type = "disk";

Ви можете розміщувати індекси на стовпцях, значення яких ви очікуєте на пошук / пошук часто, поки ви не використовуєте LIKEпропозиції для цих значень стовпців . Чим більше ви можете розділити своє журнальне повідомлення на конкретні категорії, тим більш цілеспрямовано ви зможете зробити свій пошук. Наприклад, крім error_typeполя / стовпця у наведеному вище прикладі, ви можете зробити ще "error_category": "disk", "error_type": "quota"й деяким.

Чим більше структура у вас в журналі повідомлень, тим більше ваш розборі / пошук системи (такі як fluentd, elasticsearch, kibana) можуть скористатися цієї структури, а також виконувати свої завдання з більшою швидкістю і меншим кількістю CPU / пам'яті.

Сподіваюся, це допомагає!


1
+1 Хочемо додати, що мова йде не лише про швидкість та ефективність. Актуальність результатів пошуку буде набагато вищою при використанні структурованого ведення журналів і, таким чином, "структурованих запитів". Без цього пошук будь-яких слів, які зустрічаються в різних контекстах, дасть вам безліч невідповідних звернень.
Мар'ян Венема

1
+1 також від мене, я вважаю, що це нігті. Нижче додано дещо іншу формулювання, щоб розширити і випадок типів подій.
Ніколас Блюмхардт

8

Ви не знайдете великої користі від структурованого журналу, коли ваш додаток створює кілька сотень повідомлень журналу на день. Ви, безумовно, будете, коли у вас буде кілька сотень повідомлень журналу в секунду, які надходять із багатьох різних розгорнутих додатків.

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

Я бачив налаштування "базового ведення журналів і пошуку" за допомогою SQL select .. likeі регулярних експедицій, висунутих до його меж, де він розпадається - є помилкові позитиви, упущення, жахливий код фільтра з помилками knwon, які важко підтримувати і ніхто не хоче торкатися, нові повідомлення журналу, які не відповідають припущенням фільтра, небажання торкатися операторів журналу в коді, щоб вони не порушували звіти тощо.

Таким чином, з'являється кілька програмних пакетів, щоб краще вирішити цю проблему. Є Serilog, я чую, що команда NLog на це дивиться , і ми писали StructuredLogging.Jsonдля Nlog , я також бачу, що нові абстракції ядерного журналу ASP.Net "дають можливість постачальникам послуг з реєстрації протоколів реалізувати ... структурований журнал".

Приклад із StructuredLogging. Ви входите в реєстратор NLog таким чином:

logger.ExtendedError("Order send failed", new { OrderId = 1234, RestaurantId = 4567 } );

Ці структуровані дані надходять до кібани. Значення 1234зберігається в OrderIdполі запису журналу. Потім можна здійснити пошук за допомогою синтаксису запиту kibana, наприклад, для всіх записів журналу, де @LogType:nlog AND Level:Error AND OrderId:1234.

Messageі OrderIdтепер це лише поля, за якими можна шукати точні чи неточні збіги, як вам потрібно, або агрегувати для підрахунків. Це потужний і гнучкий.

З найкращих практик StructuredLogging :

Повідомлення, що реєструються, повинні бути однаковими щоразу. Це повинен бути постійний рядок, а не рядок, відформатований для вмісту значень даних, таких як ідентифікатори або кількості. Тоді його легко знайти.

Повідомлення, що реєструється, повинно бути чітким, тобто не таким, як повідомлення, яке створюється незв'язаним оператором журналу. Тоді його пошук також не відповідає спорідненим речам.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.