NOTE: Apart from
(and even then it's questionable, I'm Scottish). These are machine translated in languages I don't read. If they're terrible please contact me.
You can see how this translation was done in this article.
Sunday, 27 October 2024
//Less than a minute
Лісозаготівля є невід'ємною частиною програм, але я часто бачу, що вона неправильно зрозуміла / неправильно використана у програмах ASP.NET. Це пост і частково виявлений спосіб ефективної реєстрації у програмах ASP. NET.
Це не повний посібник для ведення лісозаготівлі; там є LOTS; це більше стосується ефективної стратегії ведення лісозаготівель для ваших програм ASP.NET.
Основним веденням лісозаготівлі має бути USEROWE; чи буде він веденням журналу під час вашого розвитку, чи веденням журналу, він буде корисним для вас або вашої команди / ваших користувачів.
Надто часто лісозаготівля вважається "це тільки тоді, коли є якісь винятки. Я думаю, це не так, як має бути лісозаготівля.
БЛИЗЬКІСТЬ НЕ Є ТІЛЬКИ ДЛЯ ВИЯВЛЕННЯ
Загалом кажучи, ви можете запустити значну частину вашої програми локально; у цьому контексті log.LogInformation
твій друг.
Протягом 30 років я писав код, я бачив кілька прикладів хороших лісозаготівель і майже більше прикладів поганої лісозаготівлі.
Принципи хорошої лісозаготівлі:
Пам' ятайте; журналювання ALWAYS тягне вниз швидкодію вашої програми; вам слід записувати все, що потрібно для визначення проблеми, але більше не у виробінні /, де швидкодія є критичною (наприклад, не пропускайте тест швидкодії, якщо ви використовуєте повний журнал зневаджування).
У ASP. NET вже побудовано систему ведення журналу; Microsoft.Extensions.Logging
. Це гарна система лісозаготівлі, але вона не така гнучка, як серілог. Серілог - це гнучкіша система ведення журналу, яка надає вам змогу входити до декількох тонурів (вигульків) і збагачувати ваші журнали додатковими відомостями.
Це журналювання, яке відбувається після запуску вашої програми. Це перше, що станеться, і це перше, що ви повинні побачити, коли запустите свою заявку. У ASP.NET особливо, коли ви використовуєте налаштування, це важливо, ви розумієте, що відбувається, коли ваша програма запускається. Це надзвичайно поширене джерело проблем в програмах ASP.NET.
Наприклад, у Serilog ви можете зробити це:
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.File("logs/boot-*.txt", rollingInterval: RollingInterval.Day, retainedFileCountLimit: 7)
.CreateBootstrapLogger();
ЗАУВАЖЕННЯ: цей параметр обмежений, оскільки ви не маєте доступу до налаштувань, отже, наприклад, для використання AppInsights вам, ймовірно, знадобиться #if RELEASE
блок для встановлення відповідного ключа.
Це надає вам дані щодо всіх проблем, пов' язаних з запуском у вашій програмі; вона пише як у консоль, так і до файла. Важливо також переконатися, що ви не зберігаєте ВСІ файли журналів; ви можете побачити тут, що ми зберігаємо лише 7 днів вартості журналів.
Ви також бажаєте загорнути ваш метод запуску (у цій програмі я використовую новий Program.cs
метод) за допомогою try/ knaet і записуйте всі винятки, які там трапляються.
try
{
..all your startup code
}
catch (Exception ex)
{
if(args.Contains("migrate"))
{
Log.Information("Migration complete");
return;
}
Log.Fatal(ex, "Application terminated unexpectedly");
}
finally
{
Log.CloseAndFlush();
}
Журнал. CloseADFlush} важливий, оскільки забезпечує запис всіх журналів на диск (ваша програма зазнає краху, отже, у іншому випадку вона завершить роботу перед тим, як зробить це).
За допомогою цього пункту я також можу визначити, чи запущено програму у режимі міграції, і, якщо так, фіксувати цей режим і виходити з нього.
Log.Fatal
є найсуворішим рівнем журналу; його буде використано під час аварійного завершення роботи програми.
Не всі винятки смертельні - ви повинні використовувати Log.Error
для тих (якщо вони не означають, що APP (а не запит) не може продовжуватися поза цією точкою).
У ASP. NET (і. NET більш загально) є декілька рівнів журналу:
Log.Fatal
- Це найсуворіший рівень журналу. Він використовується під час аварійного завершення роботи програми.Log.Error
- Цей параметр використовується, якщо трапляється виняток, що означає, що APP (не запит) не може продовжуватися поза цією точкою.Log.Warning
- Це використовується, коли щось трапляється, це не помилка, але щось, про що вам слід знати (наприклад, зіпсована служба / щось) не зовсім правий але не помилка).Log.Information
- Це використовується для загальної інформації про те, що відбувається у вашій заяві.Log.Debug
- Це використовується для інформації, яка корисна лише для усування вад у вашій програмі (ВСЮ ВСЕ в розробці, але її слід вимкнути у виробництві).Для виробництва я б зазвичай встановив, що лісозаготівля - це Log.Fatal
, Log.Error
і Log.Warning
Только.
На відміну від запуску входу до журналу, це журнал, який відбувається під час запуску вашої програми. Це журналювання, який повідомляє вам про те, що відбувається у вашій програмі у будь-який час.
Наприклад, щоб скористатися цими у серілогах, ви можете зробити ось що:
"Serilog": {
"Enrich": ["FromLogContext", "WithThreadId", "WithThreadName", "WithProcessId", "WithProcessName", "FromLogContext"],
"MinimumLevel": "Warning",
"WriteTo": [
{
"Name": "Seq",
"Args":
{
"serverUrl": "http://seq:5341",
"apiKey": ""
}
},
{
"Name": "Console"
},
{
"Name": "File",
"Args": {
"path": "logs/applog-.txt",
"rollingInterval": "Day"
}
}
],
"Properties": {
"ApplicationName": "mostlylucid"
}
},
Як бачите, я дуже великий прихильник серілога; це чудова лісозаготівельна бібліотека, дуже гнучка. Мені подобається здатність збагачувати ваші журнали додатковою інформацією. Це може бути дуже корисним у діагностуванні проблем у вашій програмі. У наведеному вище прикладі ви можете бачити, що я збагачую свої журнали ідентифікатором нитки, ім'ям гілки, ідентифікатором процесу і назвою процесу. Це може бути дуже корисним у діагностуванні проблем у вашій програмі.
Я також встановлю для ведення журналу декілька "инків" (вигуків); у цьому випадку я відсилаю їх до консолі, до файла і до Сека (служби лісозаготівель).
Множина раковини буде корисною у випадку невдачі, у цьому випадку моя улюблена послуга лісозаготівлі - Сек, тому я відіслав її туди першим. Тоді, якщо це не вдасться, я відішлю його до консолі і до файла.
Крім того, ви можете вказати у журналі властивість applicationName. Ця властивість може бути корисною, якщо у вас є декілька програм, які входять до тієї самої служби (яка для поширених програм, які ви часто виконуєте, разом з ідентифікатором кореляції, який зв' яже ці журнали для окремого запиту).
Наприклад, якщо у вас є графічна оболонка JS і сервер. NET, ви можете встановити ідентифікатор кореляції у передній частині і передати його серверу. За допомогою цього пункту ви можете переглянути всі журнали одного запиту у одному місці. АБО, якщо ви використовуєте HtpClient у вашому сервері, ви можете передати ідентифікатор співвідношення у заголовках до іншої служби.
Існує чудова інформація про те, як ви могли б зробити це: https: // josef. codes/append- correation- id- all-log- entries- in- asp- net- core /, але я повідомлю про це у наступних повідомленнях.
Структурований журналювання - це спосіб ведення журналу, який полегшує пошук і фільтрування ваших журналів. У серилогах ви можете зробити це за допомогою Log.Information("This is a log message with {Property1} and {Property2}", property1, property2);
синтаксис. Це полегшує пошук журналів з певною властивістю.
Використання серілогів можна також використовувати LogContext.PushProperty
щоб додати властивості до ваших журналів, які відповідають лише певній області видимості. Це може бути дуже корисним у діагностуванні проблем у вашій програмі.
Серілог дуже гнучкий, оскільки надає вам змогу налаштувати його у коді, а також за допомогою налаштувань. Наприклад, щоб скористатися параметрами, наведеними вище, ви можете зробити це:
builder.Host.UseSerilog((context, services, configuration) =>
{
configuration
.MinimumLevel.Warning()
.Enrich.FromLogContext()
.Enrich.WithThreadId()
.Enrich.WithThreadName()
.Enrich.WithProcessId()
.Enrich.WithProcessName()
.WriteTo.Seq("http://seq:5341", apiKey: "")
.WriteTo.Console()
.WriteTo.File("logs/applog-.txt", rollingInterval: RollingInterval.Day)
.Enrich.WithProperty("ApplicationName", "mostlylucid");
});
Це те саме, що і налаштування, які було наведено вище, але у коді. Це корисно, якщо ви бажаєте налаштувати ваші записи журналу у коді, вам залежить від того, як ви це робите.
У ASP. NET ви можете скористатися фільтрами Винятки для того, щоб у них можна було знайти винятки і зареєструвати їх. Це чудовий спосіб переконатися, що ви записуєте всі винятки у вашій програмі. ЯК ЖЕ це не є замінником рівня ведення журналу методів; вам все ще слід записуватися на рівні методу так, щоб ви могли бачити, що відбувається у вашій програмі з подробицями; фільтр виключення просто показує, що відбувається після того, як весь стос запиту буде вимкнено і часто може бути дуже заплутаним, щоб розібратися у тому, що сталося.
Це змінилося в ASPNET Core 8 і є ТОН, ви можете зробити з цим нові можливості.
Вада знову застосування тих самих принципів; вам слід записуватися на рівні методу так, щоб ви могли бачити, що відбувається у вашій програмі з подробицями; фільтри виключення / визначення стану просто показують, що відбувається після того, як весь стос запитів буде вимкнено, і часто це може дуже спантеличувати вас, щоб розібратися у тому, що сталося.
Журналювання має бути відповідним для середовища. У розділі Розвиток ви записуєте все, щоб бачити події, які відбуваються у кожному з точок вашої програми, але у Test вам потрібно менше журналу (можливо, журнал Інформація тут), а у процесі створення вам потрібно менше (Вартість і вище).
Це спокуса записати все в виробництві, але це погана ідея. Вам слід записати все необхідне, щоб поставити діагноз, але не більше. У провайдерах хмар ви можете легко отримати заряд за об' єм даних, які ви надсилаєте до служби ведення журналу, отже вам слід бути обережними з тим, скільки часу ви зберігатимете ці журнали (типово, журнал " Проникливість " зберігає журнали на 90 днів; часто це значення TOO ДОВГО, воно коштуватиме вам протягом того часу, доки зберігатимуться дані журналу).
Для дуже "активної" програми вам просто не знадобиться довгострокова лісозаготівля цих даних; ви маєте уявлення про те, що відбувається з програмою за останні декілька днів лісозаготівлі.
Коли я бачу поширене питання в виробництві - ведення лісозаготівельних запитів про невдачу, а ці можуть бути цікавими (нетілес хоче 404 / 401), вони можуть бути величезною кількістю даних, що може бути дуже дорогим для зберігання. Вам слід записувати лише записи ви маєте намір виправити, для 404 може бути, що це є важливим, але воно може вказувати на поламане посилання у вашій програмі; для 401 це може бути важливим, оскільки воно може вказувати на пошкоджену систему розпізнавання.
ЯК БИ я не згадував вище, вони краще оброблені в коді, в якому вони насправді відбуваються (у випадку 401), може бути, що вони також повинні бути зареєстровані як Warning
або Error
в коді, який насправді створює 401.
Щоб налаштувати запит на ведення журналу у системному журналі, ви можете зробити це:
app.UseSerilogRequestLogging();
За допомогою цього пункту можна зареєструвати всі запити до вашої програми; це чудовий спосіб спостерігати за тим, що відбувається у вашій програмі на високому рівні. Але знову ж таки, вам слід бути обережними з тим, які дані ви ведете до журналу і скільки часу ви зберігатимете ці журнали.
Для " Проникливість у суть програми " вам, можливо, захочеться увійти до системи з використанням " Інформаційного рівня," оскільки це надасть вам доступ до низьких можливостей подорожі користувача. Це чудовий спосіб бачити, як користувачі використовують вашу програму, і може бути дуже корисним у проблемах з діагностуванням; але знову ж таки, ці проблеми швидко стискають витрати, отже вам слід бути обережними з тим, що ви ведете до журналу, і з часом, протягом якого ви зберігаєте ці журнали.
Ось і все, швидко пройти через те, як увійти до програм ASP.NET. Більшість з них - це реакція на надмірні, непотрібні журнали, які я бачу у багатьох промислових програмах. У розробці ви бажаєте бачити спосіб роботи програми; у створенні, яке ви хочете бачити спосіб, у який програма зазнає невдачі. Журналювання надто часто є марною, дорогою частиною розвитку програми. Так само, як і все у програмному розробці, журналювання має бути фокусовано на USER; чи ви / інші розробники програми під час роботи над програмою у вашому IDE / local, чи сортування проблем у виробництві швидко і ефективно.