Які існують шаблони та анти-шаблони реєстрації програм? [зачинено]


66

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

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

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

Натомість, для того, щоб оцінити, наскільки погано ми робимось на фронті, я хотів би знати:

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

Бічна примітка: ми використовуємо log4j.

Відповіді:


55

Кілька моментів, які моя практика виявилася корисною:

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

  • Зробіть так, щоб журнали були легко розібрані grepоком і за оком. Дотримуйтесь кількох загальних полів на початку кожного рядка. Визначте час, суворість та підсистему в кожному рядку. Чітко сформулюйте повідомлення. Зробіть так, щоб кожне повідомлення журналу було легко наближати до його рядка вихідного коду.

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

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


10
Мені подобається ця відповідь, але я хочу додати, що важливо зареєструватися, який вибір був зроблений у момент прийняття рішень. Я бачив багато систем, де було зареєстровано багато сміття, але ключові рішення не реєструвались. Тож 95% лісозаготівлі в основному марно. Також для систем типу запитів / відповідей важливіше вміти входити в систему за запитом, ніж по підсистемі.
Кевін

4
+1. Мені подобається ваша думка про те, щоб поставити себе у взуття для вирішення проблем. Здається, що записи журналів повинні містити набагато більше якісних повідомлень, ніж те, що ми робимо ...
c_maker

1
Важливо зауважити, що журнал помилок повинен бути записаний у відповідний журнал подій, а також у журнали програм.
Стівен Еверс

2
@SnOrfus: Існує кілька способів зберігання журналів, але суть полягає в тому, що повідомлення журналу повинні бути доступними до останньої секунди, коли система зазнала аварії - як чорна скринька літака. Якщо ви використовуєте будь-який тип буферизації, надайте можливість обійти його / промити кожне повідомлення.
rwong

1
@Rig: з іншого боку, багато домашніх лісорубів не здійснили жодної буферизації (і прискіпливо промивають кожне повідомлення), що призводить до дуже низької продуктивності. Ось чому це повинно бути необов’язковим.
rwong

28

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

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

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

off
errors only
basic
detailed
everything

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

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

#define DEBUG_ERROR          1
#define DEBUG_BASIC          2
#define DEBUG_DETAIL         4
#define DEBUG_MSG_BASIC      8
#define DEBUG_MSG_POLL       16
#define DEBUG_MSG_STATUS     32
#define DEBUG_METRICS        64
#define DEBUG_EXCEPTION      128
#define DEBUG_STATE_CHANGE   256
#define DEBUG_DB_READ        512
#define DEBUG_DB_WRITE       1024
#define DEBUG_SQL_TEXT       2048
#define DEBUG_MSG_CONTENTS   4096

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

Програмне забезпечення зазвичай постачається з ERROR, BASIC, STATE_CHANGE та EXCEPTION, але це можна змінити в полі через діалогове вікно налагодження (або налаштування реєстру / ini / cfg, де ці речі зберігаються).

О та одне - моя система налагодження генерує один файл на день. Ваші вимоги можуть бути різними. Але переконайтеся, що ваш код налагодження починає кожен файл із датою, версією коду, який ви працюєте, і, якщо можливо, деяким маркером для ідентифікатора клієнта, місцезнаходження системи чи будь-якого іншого. Ви можете отримати міш-меш файлів журналів, що надходять з поля, і вам потрібен деякий запис про те, що звідки і з якої версії системи вони працювали, що є насправді в самих даних, і ви не можете довіряти клієнту / польовий інженер, щоб сказати, яку версію вони мають - вони можуть просто сказати вам, яку версію вони думають, що у них є. Гірше, вони можуть повідомити про версію exe, що знаходиться на диску, але стара версія все ще працює, оскільки забули перезавантажити після заміни. Попросіть ваш код сам сказати.

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


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

27

Мій улюблений загальнодоступний ресурс для керівництва журналом - найкращі практики Apache JCL .

Кращі практики для JCL представлені у двох категоріях: General та Enterprise. Загальні принципи досить чіткі. Корпоративна практика трохи більше задіяна, і не завжди так зрозуміло, чому вони важливі.

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

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

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

Найвідоміший анти-шаблон є, ймовірно, "ковтанням винятків" - просто шукайте його в Інтернеті.

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

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

PS. Щодо анти-зразків, то інші, які приходять на думку, - це "затоплення" та безглузді повідомлення.

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

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

    step #1
    step #2
    step #3
    

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


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

@Spoike хороший момент! зберігання в змінній - це справді один із моїх улюблених особистих трюків щодо боротьби з повені
гнат

1
Я виводжу всі різні лічильники до реєстратора як ASCII-таблицю в журналі після закінчення циклу, щоб їх можна було легко порівняти. Ідея таблиці надихнула ту, яку генерує SpringWatch.prettyPrint () Spring . Крім цього, зробити текст журналу читабельним і релевантним все ще є «мистецтвом», про що говорилося у відповіді.
Спайк

@Spoike: (і @gnat) Це цікаво. Отже, ви в основному додаєте фактичний код до бізнес-логіки лише з метою реєстрації? Я ніколи не чув про це і не робив цього раніше і не знав, як би виправдати це своїм колегам. Я боюся, що якщо ми почнемо це робити, то деякі наші розробники будуть захаращувати вихідний код настільки, що ділова логіка стає перекрученою і важкою для читання. Просто записування заяви вже робить джерело більш неприємним.
c_maker

2
@c_maker Ваша думка щодо змішування журналів із діловою логікою виглядає варто окремим питанням. Особисто я поки що не маю твердої думки з цих питань. Теоретично можна уявити деякі покращення розділення за допомогою AOP та iirc. Для цього підходу є навіть практичні додатки. На практиці, однак, я дотримуюся "змішаного" підходу, і до цього часу у мене не було великих проблем. Забруднення вихідного коду - це реальна небезпека, але, знову ж таки, мені вдалося змусити його співіснувати з кодом реєстрації досить мірно. Це, звичайно, вимагає певних зусиль.
гнат

11

Увімкніть виняток лише один раз!

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


5

Ось антидіаграма: Створення двох десятків "загальнозмінних" полів у таблиці бази даних, щоб відстежувати все можливе, а потім мати 88 (і рахувати) різні значення перерахунків для різних типів журналів.


+1 - Я це бачив. "Таблиці помилок", які містять стовпці, як string1, string2, string3, string4, string5, де стискання всіх стовпців призведе до коду помилки, на який не посилається жодна документація. Результатом є ведення журналу, який є одночасно заплутаним та марним; також відомий як "сторона-підприємство-додаток-з-користувальницьким розвитком-налагодження-пекло".
Морган Херлокер

У моєму випадку це "ручна система прокатки без будь-якого уявлення про те, що насправді веде лісозаготівля"
Уейн Моліна

4

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

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


2

Пара приміток з операційної сторони будинку тут:

1) Переконайтеся, що журнали можуть бути налаштовані локально, бажано з інструментом, не важчим за текстовий редактор. Більшу частину часу ми не хочемо вести облік рівня TRACE, але ми любимо його вмикати.

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


1

З власного досвіду роботи з веб-додатками:

(І зважаючи на зберігання дуже дешево зараз)

  • Запишіть якомога більше доступної інформації (на той момент).
  • Я завжди включаю DateTime.Now у свої рядки журналу.
  • Я завжди (якщо це можливо) фіксую тривалість часу якоїсь конкретної "дії".
  • Будьте узгоджені зі своїми журналами. Оскільки я завжди використовую такий зразок:

    • "[Інформація X] [Інформація Y] [Інформація Z] [тощо]"

1

Крім стеження, записуйте поточний стан програми та вхід.

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

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


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