При работе с приложениями, созданными с использованием ASP.NET Core 6, вам часто может потребоваться использовать трассировку и ведение журнала для мониторинга производительности вашего приложения и диагностики ошибок. Вы также можете использовать трассировку в производственной среде, чтобы измерить производительность вашего приложения во время выполнения.
В этой статье обсуждается, как мы можем использовать трассировку в ASP.NET Core 6. Мы рассмотрим, как использовать прослушиватели трассировки для сбора сообщений трассировки и направления вывода трассировки в журнал событий с помощью ILogger.
Для работы с примерами кода, представленными в этой статье, в вашей системе должна быть установлена Visual Studio 2022. Если у вас еще нет копии, вы можете скачать Visual Studio 2022 здесь.
Создайте проект веб-API ASP.NET Core в Visual Studio 2022.
Прежде всего давайте создадим проект ASP.NET Core в Visual Studio 2022. Выполнение этих шагов позволит создать новый проект веб-API ASP.NET Core 6 в Visual Studio 2022:
- Запустите интегрированную среду разработки Visual Studio 2022.
- Нажмите «Создать новый проект».
- В окне «Создать новый проект» выберите «ASP.NET Core Web API» из списка отображаемых шаблонов.
- Нажмите “Далее.
- В окне «Настроить новый проект» укажите имя и местоположение нового проекта.
- При желании установите флажок «Поместить решение и проект в один каталог», в зависимости от ваших предпочтений.
- Нажмите “Далее.
- В показанном далее окне «Дополнительная информация» убедитесь, что установлен флажок «Использовать контроллеры…», поскольку в этом примере мы не будем использовать минимальные API. В поле «Тип аутентификации» оставьте значение «Нет» (по умолчанию).
- Убедитесь, что флажки «Включить Docker», «Настроить HTTPS» и «Включить поддержку Open API» сняты, поскольку мы не будем здесь использовать ни одну из этих функций.
- Нажмите Создать.
Мы будем использовать этот проект веб-API ASP.NET Core 6 для работы с прослушивателями трассировки в последующих разделах этой статьи.
Что такое отслеживание?
По сравнению с журналированием событий, которое отслеживает основные события, трассировка позволяет получить гораздо более полное представление о работающем приложении и его компонентах. Журналы содержат структурированные или неструктурированные данные с отметками времени, которые отображают записи событий, происходящих в вашем приложении. Трассировка обеспечивает гораздо большую прозрачность отдельного запроса и способа его обработки.
Пространство имен System.Diagnostics содержит классы Trace и Debug. Класс Trace используется в производственных средах, а класс Debug используется во время разработки.
Отслеживание обычно включает в себя следующие три этапа:
- Инструментарий: мы пишем необходимый код для сбора соответствующей информации.
- Трассировка: мы записываем сообщения трассировки в указанную цель, т. е. в журнал событий, текстовый файл, таблицу базы данных и т. д.
- Анализ: мы анализируем информацию, собранную из трассировок, чтобы определить узкие места в приложении.
Что такое прослушиватели трассировки? Зачем они нужны?
Прослушиватели трассировки собирают сообщения трассировки, сохраняют их и направляют в соответствующий целевой объект, например в текстовый файл. .NET предоставляет несколько прослушивателей трассировки, включая следующие:
- ConsoleTraceListener — отправляет сообщения трассировки в окно консоли.
- DefaultTraceListener — отправляет сообщения трассировки на стандартный вывод отладки.
- DelimitedListTraceListener — отправляет выходные данные трассировки в формате с разделителями в поток, средство записи потока или средство записи текста.
- EventLogTraceListener — отправляет сообщения трассировки в журналы событий.
- TextWriterTraceListener — отправляет сообщения трассировки в текстовый файл.
- XmlWriterTraceListener — преобразует сообщения трассировки в XML.
Классы System.Diagnostics.Debug и System.Diagnostics.Trace могут отправлять сообщения прослушивателям трассировки, которые, в свою очередь, направляют сообщения в соответствующий целевой объект.
Создайте прослушиватель трассировки, используя файл конфигурации в ASP.NET Core 6.
Вы можете создать прослушиватель трассировки либо с помощью файла конфигурации, либо путем написания собственного кода. Приведенный ниже фрагмент кода иллюстрирует, как создать прослушиватель трассировки с использованием файла конфигурации приложения.
<configuration>
<system.diagnostics>
<trace autoflush="false" indentsize="4">
<listeners>
<add name="MyFirstListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="TraceOutput.txt" />
<remove name="Default" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
Все прослушиватели, добавленные в коллекцию Listeners, получат выходные данные трассировки. Однако вы можете использовать прослушиватель без добавив его в коллекцию Listeners. В этом случае вы отправляете выходные данные с помощью метода Write или WriteLine в прослушивателе.
Следующий код иллюстрирует прослушиватель, который не добавлен в коллекцию Listeners, но по-прежнему способен отправлять сообщения трассировки в окно вывода, файл или любой предварительно настроенный вывод.
TextWriterTraceListener myFirstListener = new
TextWriterTraceListener("Output.txt", "myFirstListener");
myFirstListener.WriteLine("This is a test message.");
myFirstListener.Flush();
Создайте собственный прослушиватель трассировки в ASP.NET Core 6.
Прослушиватели трассировки, поставляемые с .NET 6 по умолчанию, в большинстве случаев удовлетворят вашим требованиям. Однако если вы хотите выводить сообщения трассировки в другое место назначения, вы можете реализовать собственный прослушиватель трассировки.
Чтобы создать собственный прослушиватель трассировки, вам следует создать класс, расширяющий абстрактный класс TraceListener. В классе TraceListener есть несколько виртуальных и абстрактных методов. Вам следует как минимум реализовать методы Write и WriteLine. Как минимум, ваш пользовательский прослушиватель трассировки должен выглядеть так:
public class CustomTraceListener : TraceListener
{
public CustomTraceListener(ILoggerFactory loggerFactory)
{
}
public override void Write(string? message, string? category)
{
}
public override void Write(string? message)
{
}
public override void WriteLine(string? message)
{
}
}
Итак, ваш пользовательский класс прослушивателя трассировки должен иметь конструктор аргументов и методы Write и WriteLine.
Вам также понадобится экземпляр ILogger, представляющий средство ведения журнала, фабрика средств ведения журнала для создания средства ведения журнала и StringBuilder для хранения сообщений трассировки перед их отправкой в целевой объект журнала.
private readonly ILoggerFactory _loggerFactory;
private readonly ILogger _iLogger;
private readonly StringBuilder _stringBuilder = new();
Вы можете воспользоваться внедрением зависимостей, чтобы внедрить экземпляр ILoggerFactory в конструктор, а затем использовать этот экземпляр для создания экземпляра ILogger.
public CustomTraceListener(ILoggerFactory loggerFactory)
{
_loggerFactory = loggerFactory;
_iLogger = loggerFactory.CreateLogger(nameof(CustomTraceListener));
}
Вот минимальная реализация методов Write и WriteLine:
public override void Write(string? message, string? category)
{
_stringBuilder.Append(message + "-" + category);
}
public override void Write(string? message)
{
_stringBuilder.Append(message);
}
public override void WriteLine(string? message)
{
_stringBuilder.AppendLine(message);
_iLogger.LogInformation(_stringBuilder.ToString());
_stringBuilder.Clear();
}
Полный пример пользовательского прослушивателя трассировки в ASP.NET Core 6
Ниже приведен полный исходный код нашей минимальной реализации специального прослушивателя трассировки.
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Text;
namespace TraceListenerDemo
{
public class CustomTraceListener : TraceListener
{
private readonly ILoggerFactory _loggerFactory;
private readonly ILogger _iLogger;
private readonly StringBuilder _stringBuilder = new();
public CustomTraceListener(ILoggerFactory loggerFactory)
{
_loggerFactory = loggerFactory;
_iLogger =
loggerFactory.CreateLogger(nameof(CustomTraceListener));
}
public override void Write(string? message, string? category)
{
_stringBuilder.Append(message + "-" + category);
}
public override void Write(string? message)
{
_stringBuilder.Append(message);
}
public override void WriteLine(string? message)
{
_stringBuilder.AppendLine(message);
_iLogger.LogInformation(_stringBuilder.ToString());
_stringBuilder.Clear();
}
}
}
Зарегистрируйте пользовательский прослушиватель трассировки в файле Program.cs.
Чтобы использовать пользовательский прослушиватель трассировки, необходимо зарегистрировать его в коллекции Listeners, используя следующий код.
var loggerFactory = app.Services.GetRequiredService<ILoggerFactory>();
Trace.Listeners.Add(new LoggerTraceListener(loggerFactory));
Поскольку наш пользовательский прослушиватель трассировки был добавлен в коллекцию прослушивателей, он будет захватывать все сообщения трассировки, генерируемые средой выполнения, и отправлять выходные данные в наш регистратор. Он также будет отправлять любые сообщения трассировки, которые мы отправляем явно в приложении (как мы делали ранее в примере myFirstListener).
Таким образом, любой прослушиватель, добавленный в коллекцию Listeners, может захватывать трассировки, созданные средой выполнения, а также любые сообщения трассировки, явно отправленные в приложении. Однако если прослушиватель трассировки не добавлен в коллекцию, он может отправлять только сообщения трассировки, отправленные явно в приложении. Он не будет захватывать сообщения трассировки, созданные средой выполнения.
При работе с настраиваемыми прослушивателями трассировки необходимо не забывать закрывать или очищать прослушиватель трассировки, чтобы гарантировать очистку выходного буфера. Вы можете воспользоваться классом StringBuilderCache для оптимизации кода (в классе CustomTraceListener), использующего StringBuilder.