На вході в ASP.NET Applications M SK1Part 1...probably)
Введение
Logging is OF COURSE a critical part of applications however I often see it misunderstood / misused in ASP.NET applicationsM SK2 Це частково пост і частково manifest on how to effectively log in ASP
Це не є цілковитим інструкцією для журналування. МСК0, там, МСК1, ті, що є назовні, МSK2, а МСК3 - це більше про те, як обрати ефективну стратегію журналування для ASP, ., NET, і МSK5
В головному журналі має бути USEFUL; неважливо, чи це ' журналування, коли ви МSK2 розробляєте, чи журналування в процесі виробництва, воно має бути корисно для вас M SK3 вашому команді
Проблема
Надто часто лісозаготівлю сприймають як "'", що робиться тільки тоді, коли є винятки. МSK1 . МSK2 . Я думаю, це неправильно розуміє, чим має бути лісозаготовка.
ЛУКИ не лише для винятків
Загалом, вам треба бути в змозі запустити значну частину вашої програми локальноM SK1 у цьому контексті log.LogInformation це ваш друг.
Рішення
Успіх в заході
Протягом 30 років я ' писав код Я МSK2 бачив кілька прикладів хорошої лісозаготівлі і ще більше прикладів поганої лісзаготівли
Принципи хорошої лісозаготівлі:
- Logging in Development має давати достатню інформацію про те, як працює ваша програма, щоб зрозуміти, що відбувається, коли
- Logging in Production дасть вам супершвидкий і легкий механізм, щоб зрозуміти, як ваша програма провалюється.
- Збагато вирубування в процесі виробництва є негативним фактором; це може сповільнити вашу роботу і зробити його складнішим для пошуку важливих речейM SK1
Пам 'ятайте: ; записування постійно знизує ефективність вашої додатки ; ви маєте записувати те, що вам потрібно для діагностації проблеми, але більше не в процесі виробництва МSK2 там, де ефективність є критичною
Типи входу в ASP.NET
Серілог проти Microsoft
В ASP you already have a build in logging system; Microsoft.Extensions.Logging. Це хороша система запису даних ,, але вона МSK2 не настільки гнучка, як Serilog M SK3 Serilog - гнучкіша система записування даних, яка дозволяє записувати дані в декількох сховищах MSC4 вихідні дані ) і розширювати ваші записи додатковою інформацією
Запис BootStrap
Це запис, який відбувається, коли ваша програма запускається. МСК0. Це - перша річ, яка відбувається. МSK2 і МСК3 - перша, яку ви маєте бачити, коли запускаєте свою програму. .. В АSP...NET, особливо, коли ви використовуєте її конфігурацію.
Наприклад, у Serilog ви можете зробити це:
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.File("logs/boot-*.txt", rollingInterval: RollingInterval.Day, retainedFileCountLimit: 7)
.CreateBootstrapLogger();
NOTA: Це обмежено, тому що у вас не є доступ до конфігурації на даний момент, тож, наприклад, для використання AppInsights вам, #if RELEASE блокувати, щоб встановити відповідний ключ .
Це дає вам дані про будь-які проблеми з запуском в вашій програмі; він пише як на консоль, так і на файл . ЦеM SK2 також важливо для того, щоб гарантувати, що ви не зберігаєте всі журнальні файли МSK4 ви бачите тут ми МСК5 зберігаємо тільки М СК6 щоденні журнали M СК7
Ви також хочете загорнути метод запуску ( в цій програмі Я використовую новий Program.cs метод) в спробіM SK1 ловити і записувати будь-які винятки, які там трапляються
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();
}
Запис .CloseAndFlush() важливий, бо він гарантує, що всі журнали будуть надруковані на дискі
Тут я також розпізнаю, чи програма працює в режимі міграції, і якщо так, я записую це і виходжу з неї.
Log.Fatal - найсерйозніший рівень журналу; це ' він використовується, коли ваша програма збирається скінчитися
Не всі винятки є смертельними - ви повинні використовувати Log.Error для тих (, якщо вони не мають на увазі APP ( а не запит МSK2, не можуть продовжувати рухатись далі за цим пунктом
Рівень журналу
У ASP.NET M SK1 і .NET По-іншому, в ) you have a number of log levels
Log.Fatal- Це найсерйозніший рівень журналу ; це МSK2 він використовують, коли ваша програма збирається скінчитисяLog.Error- Воно використовується, коли трапляється винятка, що означає, що APP не прохання МSK2 не може продовжувати рухатись повз цей моментLog.Warning- Це використовується, коли трапляється щось таке, що ' не є помилкою, але є чимось, про що вам слід знати МSK2 наприклад, погіршена служба не зовсім правильно але не помилка).Log.Information- Це використовується для загальної інформації про те, що відбувається в вашій програміLog.Debug- Це використовується для того, щоб повідомити, що ' є корисним лише тоді, коли ви МSK2 розв 'язуєте проблему в вашій програмі
Для виробництва I'd зазвичай визначає Log.Fatal, Log.Error і Log.Warning лише.
Запис часу запуску
На противагу запуску запису це запис, який відбувається, коли ваша програма працює. Це запис, що говорить вам, що відбувається в вашій програмі в будь-який момент
Наприклад, щоб використовувати їх в Серілогі, ви робите це:'d
"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"
}
},
Збагачує
Як ви бачите, я - великий прихильник Serilogу. МSK2, МSK3 - чудова база записів, яка дуже гнучка. МСК4 - гнучкість. MСК5 - одна з речей, які мені подобаються - це можливість заповнювати ваші журнали додатковою інформацією. М СК6 - це може бути дуже корисно для діагностування проблем у вашій програмі. У попередньому прикладі ви бачите, як I'm заповнює мої журнали ідеєю потоку , ім 'я потока МSK2 ідеєю процесу і ім' я процесу M SK3 Це може бути дуже корисним для діагностування проблем у вашій програмі
Я також налаштував запис, щоб перейти до кількох 'sinksM SK1 (outputs); в цьому випадку яМSK4м надсилаю його до консольіMSC5 до файлу і до Seq ♫(сервису запису ♫ ).
Множество раковин дуже зручно, якщо один fails, в цьому випадку моя улюблена служба запису - Seq, тож я відправляю її туди спочаткуM SK2 Потім, якщо це fails, я відправлю її до консолі та до файлуMSC3
Я також встановив властивість ApplicationName у журналах; це може бути корисно, якщо у вас є багато прикладів, які записуються на одну і ту ж службу M SK1 для розповсюджень ви часто будете ; разом з ідеалом корреляції, щоб зв 'язати журнали разом для одного запиту).
Наприклад, якщо у вас є фронтальний інтерфейс JS і .NET, ви можете встановити ID кореляції на фронтальному інтерфейсі і передати його назад . Це дає вам змогу побачити всі журнали для одного запиту в одному місці МSK2 Або, якщо ви використовуєте HttpClient на вашому зворотньому інтерфейсу, то можете передати ID корелації в заголовках до іншого сервісу M SK3
Там є чудова інформація про те, як це можна зробити. МСК1 https :// josef . codes / appen - correlation - id - to - all - log - entries - asp - net - core
Structured Logging
Структуроване записування - це спосіб запису, що робить пошук та фільтрування ваших записів легшими. В Серілогі ви можете зробити це, використовуючи Log.Information("This is a log message with {Property1} and {Property2}", property1, property2); синтаксис. Це робить пошук журналів з певною властивістю легшим
Контекстове Logging
Використовуючи Serilog, ви також можете використовувати LogContext.PushProperty додавати в журнали властивості, які стосуються лише певного діапазону. Це може бути дуже корисним для діагностики проблем у вашій програмі
Установлення Серілог
Серілог надзвичайно гнучкий, тому що він дозволяє налаштувати його як в коді, так і за допомогою config. Наприклад, щоб використати нагорну конфігурацію ви'd робите це
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 you can use Exception Filters to catch exceptions and log them Хоча це не замінює записування на рівні методу. МСК1, вам слід все ще записувати на рівні методики, щоб ви могли бачити, що відбувається в вашій програмі. МSK3. Виняток показує лише те, що трапляється після того, як ціла база запитів розгорнута, і часто дуже незрозуміло з 'ясувати, що відбулося.
Це змінилося в ASP.NET Core 8 і тамM SK2 є TON, який ви можете зробити з цими нові характеристики.
Знову ж таки, apply the same principles; you should log at the method level so you can see what 's happening in your application in detailM SK2 the Exception filters / status handlers just show what happens once the whole request stack has been unwound and can often be very confusing to work out whatMST4s happenedMst5
DON'T LOG Все в порядку
Logging should be appropriate to the environment; в Developer you log everything so you can see what is happening at each point in your application, but in Test you need less logging (maybe log Information hereM SK2 and in Production you need even less | МСК3 | Warning and above | ).
Це ' спокусує записувати все в процесі виробництва, але це МSK1 погана ідея МSK2 Ви маєте записувати усе, що потрібно для діагностування проблеми, але не більше . У cloud-провайдерах ви можете легко отримати плату за кількість даних, які ви надсилаєте на службу запису, тож ви повинні бути обережними щодо того, що ви записуєтесь та скільки часу ви зберігаєте ці записи для M(Application Insights зберігає журнали на МСК5 дні по замовчуваннюМСК6 це часто занадто довго і коштує вам, доки дані запису зберігаються МК7
Для дуже активної програми, яку ви щойно запустили, вам не потрібно довготривалих записів цих даних. МСК3, ви матимете хорошу ідею про те, що відбувається в програмі з останніми днями записів.
Запроси запису
Одного разу поширеним питанням, яке я бачу в виробництві, є запис невдачливих запитів; тоді як ці можуть бути цікавими M SK1 ніхто не хоче МSK2 МSK3 \ 401) це може бути величезна кількість даних і може бути дуже дорогою для зберігання. Ви повинні тільки записувати речі ви плануєте виправити, для МSK1 це може бути важливим, тому що він може вказувати на зламаний зв 'язок у вашій програмі
В той же час, як я вже згадував, вони краще обробляються в коді, який насправді відбувається у ( в випадку з МSK1, можливо, вони також мають бути зареєстровані як Warning або Error у коді, який насправді генерує 401.
Для створення Request Logging в Serilog ви можете зробити це:
app.UseSerilogRequestLogging();
Це зареєструє всі вимоги до вашої додатки; це ' чудовий спосіб побачити, що відбувається в вашій додатку на високому рівніM SK3 але знову ж таки, ви маєте бути обережними щодо того, що ви зареєстровуєте і скільки часу ви зберігаєте ці журнали для
Для Application Insights ви все ще можете зареєструватися на рівні інформації, бо це дасть вам чудову функцію User Journey; це чудовий спосіб побачити, як użytkownicy використовують вашу програму і може бути дуже корисним для діагностування проблем ; однак знову ж таки, ці швидко збільшують витрати, тому ви повинні бути обережними щодо того, що ви зареєструєте, та про те, скільки часу ви зберігаєте ці журнали дляM SK2
На завершення
Таким чином, це - швидка перевірка того, як зайти в ASP, ., NET, МSK3. Багато з цього - реакція на безцінні журнали, які я бачу у багатьох виробничих програмах. Під час розробки ви хочете побачити як працює додаток; у процесі виробництва, який ви хочете побачити як програма не працює. Записування надто часто є непотрібним, дорогою частиною розробки програмного забезпеченняМSK1 Як і все в програмному розвитку, записування має зосередитися на держателеM SK2 чи то на вас / інших розробниках, працюючи над програмою у вашому IDE / локально або швидко та ефективно вирішуючи проблеми в процесі виробництва МSK5