Журналювання та трасування в програмах .NET
Коли ви продовжуєте розробляти програму, вона стає складнішою, вам потрібно буде застосувати додаткову діагностику налагодження до програми.
Трасування – це спосіб відстежувати виконання програми під час його роботи. Ви можете додати інструментарій трасування та налагодження до програми .NET під час її розробки. Ви можете використовувати цей інструментарій під час розробки програми та після її розгортання.
Ця проста техніка напрочуд потужна. Його можна використовувати в ситуаціях, коли потрібно більше, ніж налагоджувач.
- Проблеми, які виникають протягом довгих періодів часу, може бути важко налагодити за допомогою традиційного налагоджувача. Журнали дозволяють детальний огляд після мортему, який охоплює тривалі періоди часу. На відміну від цього, налагоджувачі обмежені аналізом у реальному часі.
- Багатомовні програми та розподілені програми часто важко налагодити. Вкладення налагоджувача має тенденцію змінювати поведінку. За потреби можна проаналізувати докладні журнали, щоб зрозуміти складні системи.
- Проблеми в розподілених програмах можуть виникнути внаслідок складної взаємодії між багатьма компонентами. Можливо, не доцільно підключати налагоджувач до кожної частини системи.
- Багато служб не слід застопорити. Вкладення налагоджувача часто призводить до помилок часу очікування.
- Проблеми не завжди передбачаються. Журналювання та трасування призначено для низьких витрат, тому програми завжди можуть записуватися на випадок виникнення проблеми.
Записування інформації у вікна виводу
До цього моменту ми використовуємо консоль для відображення інформації для користувача програми. Є й інші типи програм, створені з .NET, які мають інтерфейси користувача, наприклад мобільні, веб-програми та класичні програми, і немає видимої консолі. У цих програмах System.Console реєструє повідомлення "за лаштунками". Ці повідомлення можуть відображатися у вікні виводу у Visual Studio або Visual Studio Code. Вони також можуть бути вихідні в системному журналі, наприклад logcatAndroid. Тому слід враховувати, коли ви використовуєте System.Console.WriteLine у програмі, яка не є консоллю.
Тут можна використовувати System.Diagnostics.Debug та System.Diagnostics.Trace на додачу до System.Console. Як Debug, так і Trace є частиною System.Diagnostics і буде записувати лише в журнали, коли додається відповідний слухач.
Вибір інтерфейсу API стилю друку – це саме ви. Основні відмінності:
-
System.Console
- Завжди вмикати та завжди записувати на консоль.
- Корисна інформація, яку клієнт може бачити у випуску.
- Оскільки це найпростіший підхід, він часто використовується для тимчасового налагодження. Цей код налагодження часто ніколи не перевіряється в елементі керування джерелом.
-
System.Diagnostics.Trace
- Увімкнуто, лише якщо визначено
TRACE. - Записує до приєднаних слухачів, за замовчуванням – DefaultTraceListener.
- Використовуйте цей API під час створення журналів, які буде ввімкнуто в більшості збірок.
- Увімкнуто, лише якщо визначено
-
System.Diagnostics.Debug
- Увімкнуто, лише якщо визначено
DEBUG(у режимі налагодження). - Записує до вкладеного налагоджувача.
- Використовуйте цей API під час створення журналів, які буде ввімкнуто лише в збірках налагодження.
- Увімкнуто, лише якщо визначено
Console.WriteLine("This message is readable by the end user.");
Trace.WriteLine("This is a trace message when tracing the app.");
Debug.WriteLine("This is a debug message just for developers.");
Створюючи стратегію трасування та налагодження, подумайте, як виглядатиме результат. Кілька операторів записування, заповнених непов'язаними відомостями, створюють журнал, який важко прочитати. З іншого боку, за допомогою функції WriteLine для розміщення пов'язаних інструкцій в окремих рядках може бути складно розрізняти відомості, які належать разом. Загалом, використовуйте кілька операторів записування, коли потрібно об'єднати відомості з кількох джерел, щоб створити одне інформативне повідомлення. Використовуйте інструкцію WriteLine, коли потрібно створити одне повне повідомлення.
Debug.Write("Debug - ");
Debug.WriteLine("This is a full line.");
Debug.WriteLine("This is another full line.");
Цей вивід отримано з попереднього журналювання за допомогою Debug:
Debug - This is a full line.
This is another full line.
Визначення констант TRACE і DEBUG
За замовчуванням, коли програму запущено в розділі налагодження, визначається DEBUG константа. Ви можете керувати цим елементом, додавши запис DefineConstants у файл проекту в групі властивостей. Нижче наведено приклад увімкнення TRACE як для конфігурацій Debug, так і для Release на додачу до DEBUG для конфігурацій Debug.
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>
Якщо ви використовуєте Trace, коли не підключено до налагоджувача, потрібно настроїти прослуховувач трасування, наприклад dotnet-trace.
Умовне трасування
Окрім простих методів Write та WriteLine, можна також додати умови за допомогою WriteIf та WriteLineIf. Наприклад, наведена нижче логіка перевіряє, чи дорівнює кількість нулю, а потім записує налагоджуваюче повідомлення:
if(count == 0)
{
Debug.WriteLine("The count is 0 and this may cause an exception.");
}
Це можна переписати в одному рядку коду:
Debug.WriteLineIf(count == 0, "The count is 0 and this may cause an exception.");
Ці умови також можна використовувати з Trace та позначками, визначеними в програмі.
bool errorFlag = false;
System.Diagnostics.Trace.WriteIf(errorFlag, "Error in AppendData procedure.");
System.Diagnostics.Debug.WriteIf(errorFlag, "Transaction abandoned.");
System.Diagnostics.Trace.Write("Invalid value for data request");
Переконайтеся, що існують певні умови
Твердження або Assert оператор перевіряє умову, указану як аргумент для Assert оператора. Якщо умова повертає значення true, жодних дій не відбувається. Якщо умова обчислюється false, твердження не вдається. Якщо ви використовуєте збірку налагодження, програма переходить у режим розриву.
Метод Assert можна використовувати з Debug або Trace, які містяться в просторі імен System.Diagnostics.
Debug методи класу не входять до версії випуску програми, тому вони не збільшують розмір і не зменшують швидкість випуску коду.
Використовуйте метод System.Diagnostics.Debug.Assert вільно, щоб перевірити умови, які мають містити значення true, якщо код правильний. Припустімо, наприклад, ви написали функцію розподілу цілих числових даних. За правилами математики дільник ніколи не може бути нульовим. Цю умову можна перевірити за допомогою твердження:
int IntegerDivide(int dividend, int divisor)
{
Debug.Assert(divisor != 0, $"{nameof(divisor)} is 0 and will cause an exception.");
return dividend / divisor;
}
Коли ви запускаєте цей код під налагоджувачем, обчислюється твердження твердження. Однак порівняння не виконується у версії випуску, тому додаткових витрат немає.
Примітка
Якщо використовується System.Diagnostics.Debug.Assert, переконайтеся, що будь-який код у Assert не змінює результати програми, якщо функцію "Твердження" видалено. В іншому разі ви можете випадково ввести помилку, яка відображається лише у версії програми. Будьте особливо уважні щодо тверджень, які містять виклики функцій або процедур.
Використання Debug та Trace із простору імен System.Diagnostics – це чудовий спосіб надати додатковий контекст під час запуску та налагодження програми.