Возможно, многим знакома библиотека ELMAH (Error Logging Modules and Handlers), которая позволяет организовать простое журналирование ошибок для любого сайта, созданного с помощью .NET Framework.
Этот простой и проверенный временем инструмент выручал меня во многим проектах.
Несколько лет назад, создавая свой новый проект под .NET Core я с досадой обнаружил, что ELMAH не работает под .NET Core.
Но это же opensource проект! Несколько выходных в работе над форком, и вот готова первая версия ELMAH работающая под .NET Core.
С тех пор много воды утекло, и признаюсь, я несколько забросил свой pet-проект. Однако, сейчас выдалась небольшая передышка между проектами, мне удалось внести существенные улучшения и хочу познакомить уважаемых «хабравчан» с новой версией ElmahCore.
Итак, ElmahCore – это opensource проект, библиотека для регистрации ошибок на сайтах, созданных с помощью технологий .NET Core.
При возникновении необработанного исключения в вашем приложении, библиотека автоматически регистрирует всю имеющуюся информацию об этом факте, включая следующие данные:
- Тип и информация об исключении, стек вызова
- Информация об HTTP запросе: данные шапки запроса (header), параметры запроса, cookies, данные о подключении пользователя
- Информация о текущем пользователе
- Информация о текущей сессии на сервере
- Переменные среды сервера
В новой версии я добавил регистрацию всех сообщений, созданных через Microsoft.Extensions.Logging (ILogger) в привязке к контексту HTTP запроса.
Вся эта информация может быть сохранена:
- в памяти сервера
- в XML файлах в папке на сервере
- в СУБД, сейчас поддерживаются MSSQL, MySQL, PostgreSQL
Подключение данной библиотеки максимально простое:
- Добавить в проект nuget-пакет elmahcore.
- Добавить следующие строчки в Startup.cs:
services.AddElmah(); // в метод ConfigureServices
app.UseElmah(); // в начале метода Configure
Для доступа к журналу ошибок библиотека предоставляет программный и пользовательский интерфейс.
Интерфейс пользователя, по умолчанию, доступен по пути ~/elmah.
В новой версии я существенно переработал UI, реализовав его на VUE.js
Важным улучшением новой версии является возможность предварительного просмотра места в коде, где произошла ошибка. Для этого необходимо предоставить библиотеке доступ к исходникам:
services.AddElmah(options =>
{
options.SourcePaths = new []
{
@"D:\tmp\ElmahCore.DemoCore3",
@"D:\tmp\ElmahCore.Mvc",
@"D:\tmp\ElmahCore"
};
});
На закладке «Log» отображается журнал сообщений Microsoft.Extensions.Logging в контексте HTTP запроса в котором была зарегистрирована ошибка.
Понятно, что такая ценная информация не для публичных глаз!
Чтобы защитить доступ к журналу, необходимо добавить проверку прав доступа:
services.AddElmah(options =>
{
options.OnPermissionCheck = context => context.User.Identity.IsAuthenticated;
});
При этом вызов UseElmah, должен быть позже UseAuthentication и UseAuthorization
app.UseAuthentication();
app.UseAuthorization();
app.UseElmah();
Можно организовать фильтрацию регистрируемых ошибок с помощь фильтров, реализованных в коде (реализующих интерфейс IErrorFilter) или в xml-файле конфигурации (https://elmah.github.io/a/error-filtering/examples/).
services.AddElmah<XmlFileErrorLog>(options =>
{
options.FiltersConfig = "elmah.xml";
options.Filters.Add(new MyFilter());
})
Кроме регистрации журнала ошибок библиотека позволяет организовать рассылку уведомлений (через реализацию IErrorNotifier), например на электронную почту.
services.AddElmah<XmlFileErrorLog>(options =>
{
options.Notifiers.Add(new ErrorMailNotifier("Email",emailOptions));
});
Надеюсь, что эта бесплатная библиотека будет полезна в ваших проектах.
Подробнее с библиотекой можно познакомиться здесь.
Mikluho
Да, прикольная библиотека! Пользовался ею ранее. И, наверно воспользуюсь вашей версией в ближайшем будущем.
Мне в старой версии не хватало пары фич:
1. Там есть только ошибки, хотя для анализа часто важно знать последовательность действий пользователя. Т.е. нужна связка подробной информации об ошибке с последовательностью вызов от конкретного пользователя.
2. Часто, при довольно сложной бизнес-логике приложения, важно понимать, каким путём прошла обработка пользовательского запроса и, желательно так, чтобы отслеживался вызов всех методов, да ещё и с параметрами.
Как итог, у нас на прошлой работе было так:
— NLog пишет обычный лог, который можно отфильтровать по логину пользователя
— в Elmah пишется куча всего про ошибку
— Interceptor, встроенный в DI-контейнер, умеет записывать цепочку вызовов и писать в отдельный лог в виде, похожем на код (полное имя метода + ключевые параметры + отступы). Этот лог пишется при ошибке или при активации расширенной трассировки для конкретного пользователя.
Эта связка очень помогала разбираться со сложными кейсами, когда ошибка возникает из-за нестыковок в данных, пришедших от внешних систем.
И ещё, про доступность логов на веб-сайте. Когда я увидел, что эти логи как-то слишком доступны, мы перенастроили все пром-сервера так, чтобы лог elmah был доступен на отдельном сайте с доступностью только из внутренней сети и авторизацией через доменные группы.
naychenko Автор
В новой версии все что журналируется через ILogger будет доступно на вкладке «Log» у каждой ошибки. Там будут только записи, которые относятся к HTTP сессии в которой произошла ошибка.
Про Interceptor — интересна идея, попробую добавить в следующей версии
Mikluho
Про лог текущего HTTP-запроса я увидел. Это уже лучше, чем было ранее.
С Interceptor есть одна, но большая сложность — его надо отдельно встраивать в DI-контейнер (мы, помимо самого перехватчика, размечали методы атрибутами, через которые определялось и логгирование, и запись в лог значений параметров). И, наверно, это не дело библиотеки. Cтоит оставить эту функцию разработчикам приложений.
А вот в библиотеке пригодится возможность регистрировать другие поставщики логов, данные с которых забираются при записи ошибки.
KaiOvas
А можно, пожалуйста, больше технических деталей про DI+Interceptor +разметку аттрибутами? Может быть небольшую статью напишите? С удовольствием почитал бы.
Mikluho
Может и напишу. Надо только старый код привести в порядок…
Shvedov
Distributed Tracing с .Net Core 3.0 доступен в базе.
Mikluho
Distributed Tracing — это про другое (про связь логов нескольких взаимодействующих приложений).
Мы делали подробный лог внутренних вызовов в приложении.
Shvedov
А я то подумал микросервисы современные…