Передовий досвід ведення журналу [закрито]


323

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

Каркаси

Які рамки ви використовуєте?

  • log4net
  • System.Diagnostics.Trace
  • System.Diagnostics.TraceSource
  • Блок застосунку журналів
  • Інший?

Якщо ви використовуєте трасування, чи використовуєте ви Trace.Correlation.StartLogicalOperation?

Ви пишете цей код вручну або для цього використовуєте якусь форму аспектно-орієнтованого програмування? Хочете поділитися фрагментом коду?

Чи надаєте ви будь-яку форму деталізації щодо слідів джерел? Наприклад, WPF TraceSources дозволяє налаштувати їх на різних рівнях:

  • System.Windows - налаштування для всіх WPF
  • System.Windows.Animation - переосмислення спеціально для анімації.

Слухачі

Які виходи журналу ви використовуєте?

  • Текстові файли
  • XML-файли
  • Журнал подій
  • Інший?

Якщо ви використовуєте файли, ви використовуєте журнали прокатки чи лише один файл? Як зробити журнали доступними для споживання людьми?

Перегляд

Які інструменти ви використовуєте для перегляду журналів?

  • Блокнот
  • Хвіст
  • Переглядач подій
  • Менеджер операцій із системного центру / Управління операціями Microsoft
  • Переглядач трас служб WCF
  • Інший?

Якщо ви будуєте рішення ASP.NET, чи використовуєте ви також моніторинг здоров'я ASP.NET? Чи включаєте виведення слідів у події моніторингу здоров'я? Що з Trace.axd?

А як же користувацькі лічильники ефективності?


3
Було б корисно, якщо люди, які закривають подібні запитання з 300 оновлень, можуть запропонувати або формат вікі, або публікацію на programmers.stackexchange, або ще Quora, якщо такий тип питань не вітається. Очевидно, що питання є насправді дуже конструктивним, воно просто не відповідає критеріям, який хоче StackOverflow. programmers.stackexchange.com/questions/57064/… має 24 відгуки. Можливо, StackOverflow чогось не вистачає?
Niall Connaughton

Якщо це питання порушує формат запитань, відповідь, то НЕОБХІДНО помиляється з форматом запитання, а не з цим питанням. Іноді рішення про те, чи варто запитання закрити, має бути функцією наданих відповідей, деякі відкриті запитання запрошують дискусії, а інші запрошують користувачів надати цінний контент, наприклад, цей!
Маттіас Вольф

1
Це питання - особливо головна відповідь - ймовірно, стало б чудовим підґрунтям для публікації в блозі, якщо хтось захотів би використати його як таке ... Як об'єктивне питання, воно не дуже відповідає - воно явно структурується як солом'яне опитування - але нижче є хороша інформація, звідси і замок.
Shog9

Відповіді:


232

Оновлення: Про розширення до System.Diagnostics, що надають деякі з пропущених слухачів, які вам можуть захотіти, див. Essential.Diagnostics на CodePlex ( http://essentialdiagnostics.codeplex.com/ )


Каркаси

З: Які рамки ви використовуєте?

A: System.Diagnostics.TraceSource, вбудований в .NET 2.0.

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

Є деякі області, в яких додаткова функціональність корисна, а іноді функціональність існує, але вона не є добре задокументована, однак це не означає, що всю рамку ведення журналу (яка призначена для розширення) слід викинути і повністю замінити, як деякі популярні альтернативи (NLog, log4net, Common.Logging і навіть EntLib Logging).

Замість того, щоб змінити спосіб додавання заяв реєстрації до програми та повторного винайдення колеса, ви просто розширили систему System.Diagnostics на декілька потрібних вам місць.

Мені здається, що інші рамки, навіть EntLib, просто страждають від синдрому Not Invented Here, і я думаю, що вони витратили час на переосмислення основ, які вже добре працюють в System.Diagnostics (наприклад, як ви пишете журнальні заяви), а не заповнення кількох існуючих прогалин. Словом, не використовуйте їх - вони не потрібні.

Особливості, які ви, можливо, не знали:

  • Використання перевантажень TraceEvent, які приймають рядок формату та аргументи, може сприяти продуктивності, оскільки параметри зберігаються як окремі посилання до досягнення успіху Filter.ShouldTrace (). Це означає, що жодних дорогих викликів ToString () на значення параметрів, поки система не підтвердиться, повідомлення фактично не буде зареєстровано.
  • Trace.CorrelationManager дозволяє співвіднести оператори журналу про одну і ту ж логічну операцію (див. Нижче).
  • VisualBasic.Logging.FileLogTraceListener хороший для запису в журнал файлів та підтримує обертання файлів. Хоча у просторі імен VisualBasic він може бути так само легко використаний у проекті C # (або іншої мови), просто включивши DLL.
  • Якщо ви використовуєте EventLogTraceListener, якщо ви викликаєте TraceEvent з декількома аргументами та з порожнім або нульовим рядком формату, то аргументи передаються безпосередньо в EventLog.WriteEntry (), якщо ви використовуєте локалізовані ресурси повідомлень.
  • Засіб Service Trace Viewer (від WCF) корисний для перегляду графіків корельованих файлів журналів активності (навіть якщо ви не використовуєте WCF). Це дійсно може допомогти налагодити складні проблеми, коли задіяно декілька потоків / активів.
  • Уникайте накладних витрат, очищаючи всіх слухачів (або видаляючи за замовчуванням); інакше за замовчуванням все передасть у систему слідів (і понесе всі накладні витрати ToString ()).

Сфери, які ви хочете подивитися на розширення (якщо потрібно):

  • Слухач слідів бази даних
  • Слухач кольорових консольних слідів
  • Слухачі трасування MSMQ / Email / WMI (за потреби)
  • Встановіть FileSystemWatcher для виклику Trace.Refresh для динамічних змін конфігурації

Інші рекомендації:

Використовуйте структуровані ідентифікатори подій та зберігайте довідковий список (наприклад, документуйте їх у перерахунку).

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

Ідентифікатор подій повинен відповідати деякій структурі (подібно до Теорії кодів відповідей, що використовується в електронній пошті та HTTP), яка дозволяє обробляти їх за категоріями, не знаючи конкретних кодів.

наприклад, перша цифра може деталізувати загальний клас: 1xxx можна використовувати для операцій "Пуск", 2xxx для нормальної поведінки, 3xxx для відстеження активності, 4xxx для попереджень, 5xxx для помилок, 8xxx для операцій "Стоп", 9xxx для фатальних помилок, тощо.

Друга цифра може деталізувати область, наприклад, 21xx для інформації про базу даних (41xx для попередження бази даних, 51xx для помилок бази даних), 22xx для режиму обчислення (42xx для попередження обчислення тощо), 23xx для іншого модуля тощо.

Присвоєні структуровані ідентифікатори подій також дозволяють використовувати їх у фільтрах.

Питання: Якщо ви використовуєте калькування, чи використовуєте ви Trace.Correlation.StartLogicalOperation?

A: Trace.CorrelationManager дуже корисний для співвіднесення виписок журналу в будь-якому середовищі з багатопотоковою обстановкою (що в наші дні майже все).

Вам потрібно принаймні встановити ActivityId один раз для кожної логічної операції, щоб співвідносити.

Start / Stop та LogicalOperationStack можуть бути використані для простого контексту на основі стека. Для більш складних контекстів (наприклад, асинхронних операцій) використання TraceTransfer до нового ActivityId (перед його зміною) дозволяє корелювати.

Засіб Service Trace Viewer може бути корисним для перегляду графіків активності (навіть якщо ви не використовуєте WCF).

Питання: Чи пишете ви цей код вручну чи використовуєте певну форму орієнтованого на нього аспекту? Хочете поділитися фрагментом коду?

Відповідь: Ви можете створити клас області, наприклад, LogicalOperationScope, який (a) встановлює контекст під час створення та (b) скидає контекст під час видалення.

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

  using( LogicalOperationScope operation = new LogicalOperationScope("Operation") )
  {
    // .. do work here
  }

При створенні області може спочатку встановити ActivityId, якщо потрібно, зателефонуйте до StartLogicalOperation та введіть повідомлення TraceEventType.Start. У розпорядженні Dispose може записати повідомлення Stop, а потім викликати StopLogicalOperation.

Питання: Чи надаєте ви будь-яку форму деталізації щодо джерел слідів? Наприклад, WPF TraceSources дозволяють налаштувати їх на різних рівнях.

A: Так, декілька джерел слідів корисні / важливі в міру збільшення системи.

Хоча ви, мабуть, хочете послідовно реєструвати всі попередження та вище, або всю інформацію та інформацію вище, для будь-якої системи розумного розміру обсяг відстеження активності (пуск, зупинка тощо) та багатословного ведення журналів просто стає занадто великим.

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

Таким чином, ви можете виявити значні проблеми із звичайного ведення журналу (всі попередження, помилки тощо), а потім "збільшити масштаб" на потрібних розділах і встановити їх на рівні відстеження активності або навіть на рівні налагодження.

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

Якщо вам потрібен ще більш тонкий налаштований контроль, додайте індивідуальні булові перемикачі, щоб увімкнути / вимкнути специфічне відстеження великої гучності, наприклад, скидання нераціональних повідомлень. (Або може бути використане окреме джерело слідів, подібне до WCF / WPF).

Ви також можете розглянути окремі джерела трасування для відстеження активності проти загального (іншого) ведення журналів, оскільки це може полегшити налаштування фільтрів саме так, як ви їх хочете.

Зауважте, що повідомлення все ще можна співвіднести через ActivityId, навіть якщо використовуються різні джерела, тому використовуйте стільки, скільки потрібно.


Слухачі

З: Які виходи журналу ви використовуєте?

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

Я, як правило, класифікую результати на три групи:

(1) Події - Журнал подій Windows (та файли трасування)

Наприклад, якщо писати сервер / послугу, то найкращою практикою для Windows є використання журналу подій Windows (у вас немає інтерфейсу, для якого потрібно звітувати).

У цьому випадку всі події "Фатальна помилка", "Помилки", "Попередження" та "Інформація про рівень обслуговування" повинні переходити до Журналу подій Windows. Рівень інформації повинен бути зарезервований для таких типів подій високого рівня, тих, які ви хочете пройти в журналі подій, наприклад, "Служба розпочата", "Сервіс припинено", "Підключено до Xyz", а може бути навіть "Розклад розпочато" , "Користувач увімкнено" тощо.

У деяких випадках ви можете зробити запис у журнал подій вбудованою частиною вашої програми, а не через систему слідів (тобто записувати записи журналу подій безпосередньо). Це означає, що його не можна випадково вимкнути. (Зверніть увагу, ви все ще хочете відзначити ту саму подію у своїй системі слідів, щоб ви могли співвіднестись).

На відміну від цього, програма GUI Windows зазвичай повідомляє про це користувачеві (хоча вони також можуть увійти до Журналу подій Windows).

Події можуть також мати відповідні лічильники ефективності (наприклад, кількість помилок / сек), і може бути важливо координувати будь-яке пряме записування до Журналу подій, лічильники ефективності, запис у систему трасування та звітування перед користувачем, щоб вони відбувалися на одночасно.

тобто якщо користувач бачить повідомлення про помилку в певний час, ви повинні мати можливість знайти те саме повідомлення про помилку в Журналі подій Windows, а потім ту саму подію з тією ж міткою часу в журналі слідів (разом з іншими деталями відстеження).

(2) Діяльність - Файли журналу додатків або таблиця баз даних (та файли трасування)

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

Тут є корисним відстеження активності (старт, зупинка тощо) (у правильній детальності).

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

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

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

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

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

(3) Trabubu Trace - текстовий файл, а може бути, XML або база даних.

Це інформація на рівні докладної та нижчої (наприклад, спеціальні булеві перемикачі для вмикання / вимикання неочищених скидів даних). Це забезпечує вміст або детальну інформацію про те, що система робить на рівні суб-діяльності.

Це рівень, який ви хочете мати можливість вмикати / вимикати для окремих розділів вашої програми (отже, для кількох джерел). Ви не хочете, щоб цей матеріал захаращувався Журналом подій Windows. Іноді використовується база даних, але швидше за все це прокатні файли журналів, які очищаються через певний час.

Велика різниця між цією інформацією та файлом журналу додатків полягає в тому, що вона неструктурована. У той час як у Журналі додатків можуть бути поля "Для", "Від", "Сума" тощо, сліди налагодження вербальної версії можуть бути будь-якими програмами, наприклад "перевірка значень X = {значення}, Y = помилка" або випадкові коментарі / маркери, наприклад " Зробив це, спробував ще раз ".

Однією з важливих практик є переконання, що речі, які ви вводите у файли журналу додатків або Журнал подій Windows, також потрапляють у систему трасування з тими ж деталями (наприклад, часова мітка). Це дозволяє потім співвіднести різні журнали під час дослідження.

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

Питання: Якщо ви використовуєте файли, чи використовуєте ви прокатні журнали чи лише один файл? Як зробити журнали доступними для споживання людьми?

Відповідь: Для файлів, як правило, потрібно прокрутити файли журналів з точки зору керованості (для System.Diagnostics просто використовуйте VisualBasic.Logging.FileLogTraceListener).

Доступність знову залежить від системи. Якщо ви говорите лише про файли, то для сервера / сервісу, до потрібних файлів можна просто отримати доступ, коли це необхідно. (Журнал подій Windows або журнали додатків бази даних матимуть власні механізми доступу).

Якщо у вас немає простого доступу до файлової системи, відстежувати налагодження до бази даних може бути простіше. [тобто реалізувати базу даних TraceListener].

Одне цікаве рішення, яке я бачив для програми GUI для Windows, - це те, що він записував дуже детальну інформацію про відстеження до "реєстратора польотів" під час запуску, а потім, коли ви закрили її, якщо у неї не було проблем, то просто видалили файл.

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

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


Перегляд

Питання: Які інструменти ви використовуєте для перегляду журналів?

Відповідь: Якщо у вас кілька журналів з різних причин, ви будете використовувати кілька глядачів.

Блокнот / vi / Блокнот ++ або будь-який інший редактор тексту є основою для простого текстового журналу.

Якщо у вас є складні операції, наприклад, діяльність з передачами, то, очевидно, ви б скористалися спеціалізованим інструментом, таким як Viewer Trace Service. (Якщо вам це не потрібно, то текстовий редактор простіше).

Оскільки я звичайно реєструю інформацію про високий рівень до Журналу подій Windows, то це забезпечує швидкий спосіб структурованого огляду (шукайте досить значки про помилки / попередження). Починати полювання потрібно лише через текстові файли, якщо їх у журналі не вистачає, хоча принаймні журнал дає вихідну точку. (У цей момент переконайтеся, що переконайтеся, що ваші журнали мають узгоджені вбудовані елементи).

Як правило, Журнал подій Windows також робить ці значні події доступними для таких інструментів моніторингу, як MOM або OpenView.

Інші -

Якщо ви входите в базу даних, можна легко відфільтрувати і сортувати інформацію (наприклад, збільшити масштаб певного ідентифікатора діяльності. (За допомогою текстових файлів ви можете використовувати Grep / PowerShell або подібне для фільтрації за потрібним частинним GUID))

MS Excel (або інша програма електронних таблиць). Це може бути корисно для аналізу структурованої або напівструктурованої інформації, якщо ви можете імпортувати її правильними роздільниками, щоб різні значення йшли в різні стовпці.

Під час запуску послуги в налагодженні / тесті я зазвичай розміщую її в консольній програмі для простоти, я вважаю корисним кольоровий реєстратор консолі (наприклад, червоний для помилок, жовтий для попереджень тощо). Вам потрібно впровадити користувальницький слухач слідів.

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

Мене справді дратує, що декілька фреймворків (log4net, EntLib тощо) витратили час, щоб переосмислити колесо і знову реалізували основні журнали, фільтрування та вхід до текстових файлів, Журналу подій Windows та XML-файлів, кожен із яких є власним. різний спосіб (виписки журналу у кожного різні); кожен з них реалізував власну версію, наприклад, реєстратора баз даних, коли більшість із них вже існувала, і все, що було потрібно, було ще пару слухачів слідів для System.Diagnostics. Говоріть про велику трату дублюючих зусиль.

Питання: Якщо ви будуєте рішення ASP.NET, чи використовуєте ви також моніторинг здоров'я ASP.NET? Чи включаєте виведення слідів у події моніторингу здоров'я? Що з Trace.axd?

Ці речі можна вмикати / вимикати за потреби. Я вважаю Trace.axd досить корисним для налагодження того, як сервер реагує на певні речі, але він, як правило, не корисний у сильно використовуваному середовищі або для довгострокового відстеження.

Питання: А як же користувацькі лічильники ефективності?

Для професійного додатку, особливо сервера / сервісу, я очікую, що він буде повністю забезпечений інструментами як з лічильниками монітора продуктивності, так і з входом у Журнал подій Windows. Це стандартні інструменти в Windows, і їх слід використовувати.

Вам потрібно переконатися, що ви включаєте інсталяторів для лічильників ефективності та журналів подій, які ви використовуєте; їх слід створити під час встановлення (при установці як адміністратор). Коли ваша програма працює нормально, вона не повинна мати права адміністратора (і тому не зможе створювати відсутні журнали).

Це хороший привід практикувати розробку як неадміністратор (мати окремий обліковий запис адміністратора, коли вам потрібно встановити служби тощо). Якщо ви записуєтеся до Журналу подій, .NET автоматично створить відсутній журнал при першому його написанні; якщо ви розвинетесь як не-адміністратор, ви спіймаєте це рано та уникнете неприємного сюрпризу, коли клієнт встановить вашу систему, а потім не зможе її використовувати, оскільки він не працює як адміністратор.


FYI: У мене виникла проблема, при якій мікрософт-слід до файлу випадає. Якщо у вас є декілька процесів (або потоків) запису до одного файлу, і вони стикаються, ви отримуєте помилку блокування доступу до файлової системи у файлі журналу.
Джей

1
Інфраструктура System.Diagnostics є безпечною для потоків; поведінка за замовчуванням полягає в тому, що рамка блокується, проте ви можете змінити TraceListener.IsThreadSafe, якщо надасте власне блокування. Див msdn.microsoft.com/en-us/library / ... . Для декількох процесів ви зазвичай записуєте в окремі файли, але зауважте, що Service Trace Viewer може завантажувати декілька файлів слідів (наприклад, з декількох машин) та співвідносити їх через ActivityId.
Хитрий Грифон

1
Може, ви можете запропонувати, як використовувати TraceEvent () для реєстрації винятків?
Дмитро Сосунов

1
Хіба це не один з основних недоліків того, System.Diagnostics.Traceщо він оздоблений, [Conditional("TRACE")]що робить його непридатним у виробничих середовищах, де ви рідко маєте код, зібраний з TRACEпрапором?
Асбьорн Ульсберг

2
@asbjornu Конфігурація збірки випусків у Visual Studio має TRACE (для DEBUG вимкнено для збірок версій); якщо будівництво з командного рядка ви, однак, потрібно ввімкнути.
Хитрий Грифон

40

Я маю приєднатися до хору, що рекомендує log4net, в моєму випадку - з точки зору гнучкості платформи (настільний .Net / Compact Framework, 32/64-бітний).

Однак, загортання його в приватний API є головним анти-шаблоном . log4net.ILoggerє .Net аналогом API обгортки журналу Commons , тому з'єднання для вас уже зведено до мінімуму, а оскільки це також бібліотека Apache, це зазвичай навіть не викликає занепокоєння, оскільки ви не відмовляєтесь від будь-якого контролю. повинен.

Більшість бібліотек для обгортки будинків, яких я бачив, також здійснюють одну чи кілька літаній несправностей:

  1. Використовуючи глобальний одиночний реєстратор (або еквівалентно статичну точку входу), яка втрачає чітку роздільну здатність рекомендованого шаблону реєстратора для класу, не вимагаючи іншого посилення селективності.
  2. Якщо не виставити необов'язковий Exceptionаргумент , це призведе до кількох проблем:
    • Це ускладнює підтримку політики реєстрації винятків, тому нічого не робиться послідовно з винятками.
    • Навіть при послідовній політиці форматування виключення у рядку передчасно втрачає дані. Я написав спеціальний ILayoutдекоратор, який виконує детальну деталізацію за винятком для визначення ланцюга подій.
  3. Якщо не виставити властивостейIsLevelEnabled , це відкидає можливість пропускати код форматування, коли області або рівні журналу вимкнено.

1
Мені було доручено переробити (жахливий) внутрішній обгортку навколо log4j в щось дещо менш жахливе (це все ще досить погано, але це результат обурення вимогам, які мені дали в log4j). Я намагався усунути глобальну статичну точку входу, але був збитий. Я дійсно не розумію. У нашому налаштуванні log4j настільки сильно розширений і скручений, що він насправді просто використовується як диспетчер подій; ми використовуємо його лише тому, що хтось запитав "як ми можемо використовувати log4j для цього?" Або використовуйте log4 незалежно від прямого запису, або просто напишіть власну структуру. Середня дорога болюча.
Адам Яскевич

25
Я не погоджуюсь з вашою рекомендацією не обертати log4net. Обгортання його тонким API-моделлю постачальника дозволяє користувачам бібліотек вашого класу підключати їх улюблені рамки реєстрації. YMMV, звичайно, але описувати його як "основний анти-шаблон" є трохи догматичним. Також той факт, що існують бібліотеки обгортки з "літанією несправностей", не є гарним аргументом проти добре написаної обгортки.
Джо

1
Називати щось анти-візерунком не означає, що це завжди на 100% погана ідея - просто те, що це створює схильність малювати себе в кут, якщо ви не обережні. Крім того, ILog / LogManager - сама добре написана міні-бібліотека для обгортки на зображенні загальнодоступного журналу, що входить у збірку log4net, але немає причин її неможливо витягнути і перетворити на належний журнал обміну для CLR.
Джефрі Хантін

18

Я не часто розвиваюсь на asp.net, однак, коли мова заходить про реєстратори, я думаю, що багато кращих практик є універсальними. Ось кілька моїх випадкових думок щодо ведення лісозаготівлі, про які я дізнався за ці роки:

Каркаси

  • Використовуйте рамку абстракції логгера - наприклад, slf4j (або згорніть свій власний), щоб ви відокремили реалізацію реєстратора від свого API. Я бачив, що низка фреймворків лісорубів приходить і йде, і вам краще зможете прийняти новий без особливих клопотів.
  • Спробуйте знайти рамку, яка підтримує різні формати виводу.
  • Спробуйте знайти основу, яка підтримує плагіни / спеціальні фільтри.
  • Використовуйте рамку, яку можна налаштувати за допомогою зовнішніх файлів, щоб ваші клієнти / споживачі могли легко налаштувати вихід журналу, щоб його легко читали програми комерційного управління журналом.
  • Не забудьте переходити за борт на користувальницьких рівнях реєстрації, інакше ви не зможете перейти на різні рамки ведення журналу.

Вихід з реєстратора

  • Постарайтеся уникати журналів стилів XML / RSS для ведення журналів, які можуть зіткнутися з катастрофічними поломками. Це важливо, тому що якщо вимикач живлення вимкнено без того, щоб ваш реєстратор написав </xxx>тег закриття , ваш журнал порушений.
  • Теми журналу. В іншому випадку відстежити потік вашої програми може бути дуже важко.
  • Якщо вам доведеться інтернаціоналізувати свої журнали, можливо, ви хочете мати вхід для розробників лише англійською мовою (або вашою мовою на вибір).
  • Іноді можливість встановлення операторів журналу в SQL-запити може бути рятувальником в ситуаціях налагодження. Як от:
    - Клас виклику: com.foocorp.foopackage.FooClass: 9021
    ВИБІР * ВІД foo;
  • Ви хочете записувати на рівні класу. Зазвичай ти не хочеш статичних екземплярів реєстраторів - не варто мікрооптимізації.
  • Позначення та категоризація зареєстрованих винятків іноді корисна, оскільки не всі винятки створюються однаковими. Отже, знаючи підмножину важливих винятків, час роботи корисний, якщо у вас є монітор журналу, який повинен надсилати сповіщення про критичні стани.
  • Копіюючі фільтри дозволять зберегти зір та жорсткий диск. Ви дійсно хочете, щоб той самий запис журналу повторювався 10 ^ 10000000 разів? Не було б краще просто отримати повідомлення типу: This is my logging statement - Repeated 100 times

Також дивіться це моє питання .


5
фільтри дублювання - відмінна ідея
Пол Стовелл

Я раніше погоджувався з проблемою зламаного тегу, але більшість хороших письменників XML так і не використовують повний XML (тобто жоден кореневий елемент), щоб вони могли увійти без завантаження XML DOM. в нечастому випадку виникає проблема з частково записаним записом, ви можете виправити це вручну
Пол Стовелл

Я роками іду назад і назад на реєстрацію XML. Тепер мені це здається надмірним. Якщо мені знадобився RSS-канал про статус програми, я думаю, що це краще реалізувати за допомогою утиліти для моніторингу журналу.
Ілля

Я погоджуюся на RSS. Я більше розмірковую про засоби візуалізації, які дозволяють краще зрозуміти запис. з текстовими файлами, як правило, ви хочете зберегти запис в одному рядку; але іноді потрібно включити сліди стека або серіалізовані об'єкти. ось тут стане в нагоді журнал XML (як використовується WCF)
Пол Стовелл,

+1 для згадування інструментації SQL-запитів. Це дійсно дуже корисно для співвідношення слідів бази даних та слідів додатків. Я роблю це вручну в своєму DAL, але мені цікаво, яка підтримка інструментів для цієї техніки?
Костянтин

17

Я не кваліфікований, щоб коментувати вхід у систему .Net, оскільки мій хліб і масло - це Java, але ми перенеслися в наші лісозаготівлі протягом останніх 8 років, ви можете виявити корисну аналогію вашому питанню.

Ми почали з реєстратора Singleton, який використовувався кожним потоком в JVM, і встановив рівень журналу для всього процесу. Це призвело до величезних журналів, якщо нам довелося налагодити навіть дуже специфічну частину системи, тому урок номер один - це сегментувати ваш журнал.

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

Ми використовуємо бібліотеку обміну журналами Apache, обернуту навколо Log4J.

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

* Редагувати *

Прочитавши публікацію Джефрі Хантіна нижче, я зрозумів, що я мав зазначити, чим насправді стала наша внутрішня обгортка. Зараз він по суті є фабрикою і застосовується строго для отримання робочого реєстратора, використовуючи правильний файл властивостей (який із застарілих причин не переміщений у положення за замовчуванням). Оскільки ви можете вказати файл конфігурації журналу в командному рядку зараз, я підозрюю, що він стане ще більш сухим, і якщо ви запускаєте нову програму, я б точно погодився з його твердженням, що вам навіть не варто заважати обгортати реєстратор.


дякую за відповідь. ви створюєте дочірні реєстратори вручну в коді (тобто, чи вони жорстко закодовані) або через якусь автоматичну / неявну річ?
Пол Стовелл

Ні ... якщо ми додамо конфігурацію журналу до файлів logging.properties для пакету або класу, вони будуть реєструватися відповідно до цієї конфігурації, але будь-який пакет або клас, не спеціально налаштований, будуть реєструватися на рівнях за замовчуванням.
Стів Моєр

9

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

Ми вибрали його з наступних причин:

  • Проста конфігурація / конфігурація в різних середовищах
  • Хороша кількість заздалегідь побудованих закусочок
  • Один із CMS, який ми використовуємо, вже мав його вбудований
  • Приємна кількість рівнів журналів та конфігурації навколо них

Я мушу зазначити, що це говорить з точки зору розвитку ASP.NET

Я бачу деякі достоїнства у використанні Trace, який знаходиться в .NET рамках, але я не повністю продається на ньому, головним чином тому, що компоненти, з якими я працюю, насправді не роблять жодних дзвінків Trace. Єдине, чим я часто користуюся, - цеSystem.Net.Mail те, що я можу сказати.

Таким чином, у нас є бібліотека, яка обгортає log4net, і в рамках нашого коду нам просто потрібні такі речі:

Logger.Instance.Warn("Something to warn about");
Logger.Instance.Fatal("Something went bad!", new Exception());

try {
  var i = int.Parse("Hello World");
} catch(FormatException, ex) {
  Logger.Instance.Error(ex);
}

У межах методів ми перевіряємо, чи включений рівень журналу, тому у вас немає зайвих дзвінків до API log4net (тому якщо налагодження не ввімкнено, заяви про налагодження ігноруються), але коли я отримую деякий час Я буду оновити його, щоб викрити ці, щоб ви могли зробити перевірки самостійно. Це запобіжить проведенню оцінок, коли вони не повинні, наприклад:

Logger.Instance.Debug(string.Format("Something to debug at {0}", DateTime.Now);

Це стане:

if(Logger.DebugEnabled) Logger.Instance.Debug(string.Format("Something to debug at {0}", DateTime.Now);

(Заощаджуйте трохи часу на виконання)

За замовчуванням ми реєструємось у двох місцях:

  1. Файлова система веб-сайту (у розширенні, що не використовується)
  2. Надсилання електронної пошти для помилок та фатальних результатів

Файли виконуються як прокатка кожного дня або 10 Мб (IIRC). Ми не використовуємо EventLog, оскільки це може зажадати більш високої безпеки, ніж ми часто хочемо дати сайту.

Я вважаю, що Блокнот працює чудово для читання журналів.


Рамки ведення журналів - один з небагатьох випадків, коли синглтон не є зловживанням.
mmcdole

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

7
Я б точно вирвав сингла. Ви, звичайно, можете мати один екземпляр, який передається навколо (бажано, в контейнері IOC / DI). Я б також спробував перейти вхід у перехоплювач ....
yfeldblum

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

8

Які рамки ви використовуєте?

Ми використовуємо суміш блоку додатків для реєстрації та спеціальний помічник журналу, який працює навколо бітів .Net Framework. LAB налаштований для виведення досить обширних файлів журналів, включаючи окремі загальні файли трасування для введення / виходу методу обслуговування та конкретні файли помилок для несподіваних проблем. Конфігурація включає в себе дату / час, потік, pId і т.д. для допомоги з налагодження, а також повну інформацію про винятки та стек (у випадку несподіваного винятку).

Користувальницький помічник ведення журналів використовує систему Trace.Correlation і особливо зручний у контексті входу в систему WF. Наприклад, у нас є державна машина, яка викликає ряд послідовних робочих процесів. Під час кожної з цих операцій виклику ми реєструємо початок (використовуючи StartLogicalOperation), а потім наприкінці зупиняємо логічну операцію з гереричним обробником подій повернення.

Це вже кілька разів виявилося корисним при спробі налагодження помилок у складних бізнес-послідовностях, оскільки це дозволяє нам швидше визначати такі речі, як рішень філій If / Else тощо, виходячи з послідовності виконання діяльності.

Які виходи журналу ви використовуєте?

Ми використовуємо текстові та XML-файли. Текстові файли конфігуруються через блок додатків, але ми також отримали XML-виходи з нашого сервісу WF. Це дозволяє нам фіксувати події виконання (наполегливість тощо), а також загальні винятки для бізнесу. Текстові файли - це журнали, які прокручуються за днем ​​та розміром (я вважаю, що загальний розмір 1 МБ - це точка перекидання).

Які інструменти ви використовуєте для перегляду журналів?

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

Журнали надсилаються в єдиний каталог, який потім розбивається на підкаталоги на основі служби джерела. Кореневий каталог відкривається через веб-сайт, на якому доступ контролюється групою користувачів підтримки. Це дозволяє нам ознайомитись із журналами виробництва без необхідності подавати запити та проходити тривалі процеси бюрократії для отримання виробничих даних.


6

Як автори інструменту ми, звичайно, використовуємо SmartInspect для ведення журналів та відстеження програм .NET. Зазвичай ми використовуємо названий протокол труби для живого ведення журналу та (зашифровані) бінарні файли журналів для журналів кінцевих користувачів. Ми використовуємо консоль SmartInspect як інструмент перегляду та моніторингу.

Насправді існує досить багато фреймворків та інструментів для створення .NET. Огляд та порівняння різних інструментів на DotNetLogging.com .


5

У відповідях є безліч чудових рекомендацій.

Загальна найкраща практика - це врахувати, хто буде читати журнал. У моєму випадку це буде адміністратор на сайті клієнта. Тому я реєструю повідомлення, які надають їм те, на що вони можуть діяти. Наприклад, "Неможливо ініціалізувати додаток. Зазвичай це спричинено ......"


1

Ми використовуємо log4net у своїх веб-додатках.

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

Це також дозволяє орієнтуватися на конкретні класи або атрибути, щоб увійти в систему. Це дуже зручно, коли ви маєте уявлення, де відбувається помилка. Класичний приклад - NHibernate, де ви хочете бачити лише SQL, що йде до бази даних.

Редагувати:

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


Чи можете ви надати більш детальну інформацію про те, як ви його використовуєте? Ви входите у файл чи журнал подій? Це прокручений файл журналу? Що ви робите, щоб захистити його чи створити резервну копію? Мене цікавить використання в реальному житті.
Пол Стовелл

1

Що стосується аспектно-орієнтованого ведення журналу, то мені рекомендували PostSharp з іншого питання SO -

Агентно-орієнтоване ведення журналу за допомогою Unity \ T4 \ що-небудь ще

Посилання, надане у відповіді, варто відвідати, якщо ви оцінюєте рамки журналу.

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