Веб-сервис Monitor для диагностики и трассировки¶
Monitor - веб-сервис для сбора статистики и трассировки с сервисов web с последующей передачей собранных данных потребителям, таким как prometheus и jaeger. Для передачи статистики используется протокол prometheus, в то время как для передачи трассировки используется протокол OTLP. Данный сервис может быть развёрнут как в операционной системе Windows, так и Linux.
Important
Monitor не является обязательным компонентом системы и необходим только для агрегации данных с их последующей передачей. Устанавливайте его только в том случае, если вы хотите отслеживать состояние системы с помощью счётчиков производительности или же выполнять трассировку запросов для выявления проблем производительности.
Important
Monitor предоставляет доступ к счётчикам производительности по протоколам http/https всем, у кого есть доступ по адресу /metrics. Крайне рекомендуется ограничивать доступ к методам сервиса Monitor, оставляя его только для определённых потребителей.
Установка Monitor в Windows¶
Выполните предварительные настройки и создание учётной записи, если эти действия не были выполнены ранее.
Important
Сервисы web и monitor используют счётчики производительности Windows для получения информации о работе сервера, например дисковой очереди. Для их корректной работы рекомендуется добавить созданную учётную запись в группу Performance Monitor Users.
При настройке компонентов также включите компонент Инициализация приложений в группе Службы IIS → Службы интернета → Компоненты разработки приложений.

Модуль инициализации приложений позволяет IIS упреждающе выполнять задачи инициализации, такие как выполнение первоначального HTTP-запроса к приложению или вызов пользовательской логики для выполнения действий, необходимых для “разогрева” приложения.
В Диспетчер служб IIS создайте новый пул приложений monitor и укажите версию среды CRL .NET равную Без управляемого кода.

В качестве учётной записи укажите “tessa”. Для настройки учётной записи необходимо выбрать созданный в предыдущем пункте пул приложений и нажать Дополнительные параметры…:

В открывшемся окне в поле Удостоверение нажать на кнопку с изображением трех точек:

Выбрать Особая учетная запись, нажав на кнопку Установить… откроется окно, где необходимо указать учетную запись (в формате имя домена\имя учетной записи и пароль):

Параметр Режим запуска должен быть равен значению Всегда запущен / AlwaysRunning.

Данный режим запуска указывает IIS немедленно запустить рабочий процесс для приложения, не дожидаясь первоначального запроса к нему.
Для параметра Тайм-аут простоя (в минутах) укажите значение 0.

Тайм-аут простоя равный 0 означает, что время ожидания приложения никогда не истекает. IIS не уничтожит приложение, даже если оно не получало ни одного HTTP-запроса в течение неопределенного времени.
Убедитесь, что веб-сайт Default Web Site запущен (щелкаем правой кнопкой на сайте, далее Управление веб-сайтом → Запустить).

Создайте директорию C:\inetpub\wwwroot\tessa\monitor, если она не была создана ранее. Скопируйте в неё содержимое папки Services\monitor, которая находится в папке с основной сборкой TESSA.
Далее в диспетчере IIS вы увидите Default Web Site и вложенную в него папку tessa\monitor. Папку необходимо преобразовать в приложение через контекстное меню.

В открывшемся окне для параметра Пул приложений укажите значение monitor.

С помощью того же контекстного меню на приложении monitor выберите пункт Управление приложением → Дополнительные параметры.

В открывшемся окне для параметра Предварительная установка включена установите значение True.

Перезапустите пул приложений monitor.
Установка Monitor в Linux¶
Important
Сервисы web и monitor используют программу iostat для получения информации о работе сервера, например дисковой очереди. Для их корректной работы рекомендуется установить её.
Настройка службы monitor для systemd¶
Создайте конфигурационный файл веб-сервиса и откройте его на редактирование, используя команду в терминале:
sudo nano /etc/systemd/system/monitor.service
Скопируйте следующий текст:
[Unit]
Description=Syntellect TESSA Monitor
[Service]
WorkingDirectory=/home/tessa/tessa/monitor
ExecStart=/home/tessa/tessa/monitor/Tessa.Monitor 5200
Restart=always
RestartSec=10
SyslogIdentifier=monitor
User=tessa
UMask=002
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
[Install]
WantedBy=multi-user.target
Закройте редактор с сохранением изменений.
Tip
Строка WorkingDirectory содержит путь до папки с веб-сервисом. Строка ExecStart должна содержать тот же путь вместе с именем исполняемого файла Tessa.Monitor.
Настройте автозапуск веб-сервиса и запустите его, выполнив команду в терминале:
sudo systemctl enable monitor && sudo systemctl start monitor
Tip
Здесь monitor соответствует имени сервиса monitor.service без расширения .service.
Проверьте, что сервис успешно запущен, выполнив команду:
sudo systemctl status monitor
Если всё корректно, то рядом с именем сервиса будет выведен зелёный кружок.
Если режим просмотра статуса не закрылся сам, закройте его нажатием кнопки Q.
Tip
Если позже вы измените файл сервиса .service, то сначала выполните команду sudo systemctl daemon-reload и затем перезапустите изменённый сервис sudo systemctl restart monitor.
Tip
Посмотреть сообщения журнала по всем запущенным службам можно, выполнив команду: sudo journalctl -xe.
Настройка службы monitor для systemv¶
sudo nano /etc/init.d/monitor
Скопируйте следующий текст:
#!/bin/sh
### BEGIN INIT INFO
# Provides: monitor
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Stop/start monitor
### END INIT INFO
PATH=/sbin:/usr/sbin:/bin:/usr/bin
if [ -L $0 ]; then
SCRIPTNAME=`/bin/readlink -f $0`
else
SCRIPTNAME=$0
fi
NAME="monitor"
DAEMONUSER="tessa"
DAEMONDIR="/home/$DAEMONUSER/tessa/monitor"
DAEMON="$DAEMONDIR/monitor"
DAEMON_ARGS="5200"
LOGDIR="/home/$DAEMONUSER/tessa/logs/"
LOGFILE="$LOGDIR/monitor.log"
PIDFILE="/var/run/monitor.pid"
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
. /lib/init/vars.sh
. /lib/lsb/init-functions
do_start()
{
log_daemon_msg "Starging system $NAME daemon"
su - $DAEMONUSER -c "mkdir -p '$LOGDIR'"
su - $DAEMONUSER -c "rm -f '$LOGFILE'"
start-stop-daemon --start --name "$NAME" --user $DAEMONUSER \
--background --make-pidfile --pidfile "$PIDFILE" \
--stdout "$LOGFILE" --stderr "$LOGFILE" \
--chdir "$DAEMONDIR" \
--exec "$DAEMON" -- $DAEMON_ARGS
RETVAL="$?"
log_end_msg $?
return "$RETVAL"
}
do_stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
log_daemon_msg "Stopping system $NAME daemon"
start-stop-daemon --stop --quiet --oknodo --retry=5 --pidfile "$PIDFILE"
RETVAL="$?"
log_daemon_msg $?
rm -f $PIDFILE
return "$RETVAL"
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting " "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping " "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
restart)
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
status)
status_of_proc -p "$PIDFILE" "$DAEMON" "$NAME" && exit 0 || exit $?
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart|status}" >&2
exit 3
;;
esac
exit $RETVAL
Закройте редактор с сохранением изменений.
Important
Переменные скрипта DAEMONUSER, DAEMONDIR, LOGDIR зависят от установки monitor. В случае необходимости запуска от другого пользователя укажите его имя в DAEMONUSER. В случае установки monitor в директорию, отличную от /home/$DAEMONUSER/tessa/, измените переменные DAEMONDIR, LOGDIR таким образом, чтобы они соответствовали директории установки monitor.
Important
Ознакомьтесь с документацией start-stop-daemon для вашей операционной системы. В некоторых версиях вместо двух аргументов --stdout и --stderr используется один --output. В этом случае скорректируйте соответствующую часть функции do_start (--stdout "$LOGFILE" --stderr "$LOGFILE" замените на --output "$LOGFILE").
Задайте права на исполнение данного сервиса.
sudo chmod 755 /etc/init.d/monitor
Добавьте сервис в автозапуск.
- Наиболее надёжный способ:
sudo ln -s /etc/init.d/monitor /etc/rc0.d/S01monitor
- Если доступна команда
chkconfig:
sudo chkconfig --add /etc/init.d/monitor
- Если доступна команда
update-rc.d:sudo update-rc.d monitor defaults
- Если доступна команда
rc-update:
sudo rc-update add monitor default
Запустите сервис, выполнив команду:
sudo service monitor start
Проверьте, что сервис успешно запущен, выполнив команду:
sudo service monitor status
Описание работы веб-сервиса Monitor¶
При запуске, сервис monitor начинает слушать порт 5100 на входящие подключения от сервисов web. После установления подключения, monitor каждую секунд отправляет запрос на актуализацию счётчиков производительности каждому подключенному сервису web. В то же время он постоянно принимает данные трассировки, которые пересылаются согласно настройкам app.json с использованием протокола OTLP. Счётчики производительности же отдаётся при обращении по адресу /metrics с использованием протокола prometheus.
Important
Передача данных между сервисами web и monitor не защищена шифрованием. Крайне рекомендуется устанавливать сервис monitor на одном сервере с сервисами web (в случае, если используется несколько серверов, то устанавливайте по одному сервису monitor на каждый сервер) для повышения производительности и безопасности.
Конфигурационные параметры app.json¶
-
Параметр:
"TracingHost": "localhost"
Адрес, используемый для передачи трассировки. В качестве допустимых адресов возможно указать
localhost, IP-адрес или DNS-имя серверов. По умолчаниюlocalhost. -
Параметр:
"TracingPort": 4317
Порт, используемый для передачи трассировки. По умолчанию указан порт 4317, используемый для протокола
gRPC. -
Параметр:
"TracingProtocol": "Grpc"
Протокол, используемый для передачи трассировки. Поддерживаются значения
gRPCиHttpProtobuf(HTTPс использованиемprotobuf). По умолчаниюGrpc. -
Параметр:
"EnableUnrestrictedAccess": false
Определяет, должен ли сервис
monitorпринимать входящие подключения со всех сетевых интерфейсов. По умолчанию отключён. Не рекомендуется включать кроме случаев, когда сервисmonitorи сервисыwebрасположены на разных серверах.
Трассировка серверов приложений¶
Для трассировки запросов к серверам приложений используется API .NET ActivitySource. Данные трассировки передаются в monitor, который передаёт их по протоколу OTLP через gRPC/HTTP потребителям. Так, можно передавать данные напрямую (например, в Jaeger), или же через специальные процессоры (OpenTelemetry Collector), которые позволяют отфильтровать трассировку или преобразовать её в другой формат для потребителя.
Список имён доступных источников трассировок:
| Имя | Группа | Описание |
|---|---|---|
Tessa.Web.OpenTelemetry.SqlClient |
Queries |
Трассировка всех SQL запросов, проходящих через провайдер для СУБД Microsoft SQL Server |
Npgsql |
Queries |
Трассировка всех SQL запросов, проходящих через провайдер для СУБД PostgreSQL |
CardRepository |
Cards |
Трассировка всех операций с карточками и универсальных запросов к сервису карточек |
CardNewComponent |
Cards |
Трассировка всех операций создания карточек |
CardGetComponent |
Cards |
Трассировка всех операций получения карточек |
CardStoreComponent |
Cards |
Трассировка всех операций сохранения карточек |
CardStreamServerRepository |
Cards |
Трассировка всех операций с файлами в карточках |
CardDeleteComponent |
Cards |
Трассировка всех операций удаления карточек |
ActivityExtensionTraceListener |
Extensions |
Трассировка всех операций, производимых в серверных расширениях работы с карточками |
ViewQueryExecutor |
Views |
Трассировка выполнения SQL запросов представлений.Сюда не входит трассировка по выполнению программных представлений и перехватчиков любых представлений |
WorkflowEngine |
Processes |
Трассировка обработки сигнала процесса WorkflowEngine |
GetContentByLink |
ContentByLink |
Трассировка выполнения запросов на получение контента по ссылке |
TracingMiddleware |
Web |
Трассировка обработки запросов сервером приложений |
Также существуют специальные группы * и ALL, включающие в себя все доступные источники трассировки.
Note
Предпочтительнее использовать группу, если не требуется детально разделять источник возникновения события. Например, включите трассировку представлений с указанием группы Views вместо имени ViewQueryExecutor.
Note
Для написания своей трассировки обратитесь к документации .NET или же к “Руководству разработчика” к разделу Добавление трассировки обработки запросов и счётчиков производительности на сервере.
По умолчанию трассировка запросов в TESSA отключена. Для включения трассировки обратитесь к документации по Командам управления компонентами.
Диагностика серверов приложений¶
Для диагностики состояния серверов приложений используется API .NET Meter. Данные этих счётчиков передаются в monitor, который отдаёт их по протоколу prometheus при обращении по адресу /metrics. Далее, по данным этих счётчиков можно настраивать предупреждения в prometheus (например, при превышении пороговых значений потребления памяти) или же строить графики в grafana.
TESSA собирает данные со счётчиков .NET Runtime и AspNetCore, SqlClient, Npgsql. Также, TESSA собирает данные со своих счётчиков, таких как:
| Название | Описание | Тэги |
|---|---|---|
total-get-requests |
Количество запросов на получение карточки (учитываются как внутренние, так и внешние запросы) | CardTypeID - идентификатор типа запрашиваемой карточки или Guid.Empty если он неизвестен |
current-get-requests |
Количество запросов на получение карточки в данный момент (учитываются как внутренние, так и внешние запросы) | Отсутствуют |
total-store-requests |
Количество запросов на сохранение карточки (учитываются как внутренние, так и внешние запросы) | CardTypeID - идентификатор типа сохраняемой карточки или Guid.Empty если он неизвестен |
current-store-requests |
Количество запросов на сохранение карточки в данный момент (учитываются как внутренние, так и внешние запросы) | Отсутствуют |
total-new-requests |
Количество запросов на получение объекта новой карточки (учитываются как внутренние, так и внешние запросы) | CardTypeID - идентификатор типа карточки или Guid.Empty если он неизвестен |
current-new-requests |
Количество запросов на получение объекта новой карточки в данный момент (учитываются как внутренние, так и внешние запросы) | Отсутствуют |
total-delete-requests |
Количество запросов на удаление карточки (учитываются как внутренние, так и внешние запросы) | CardTypeID - идентификатор типа удаляемой карточки или Guid.Empty если он неизвестен |
current-delete-requests |
Количество запросов на удаление карточки в данный момент (учитываются как внутренние, так и внешние запросы) | Отсутствуют |
total-card-requests |
Количество универсальных запросов (учитываются как внутренние, так и внешние запросы) | RequestType - идентификатор типа запроса или Guid.Empty если он неизвестен |
current-card-requests |
Количество универсальных запросов в данный момент (учитываются как внутренние, так и внешние запросы) | Отсутствуют |
total-view-requests |
Количество запросов на получение данных из представлений (учитываются как внутренние, так и внешние запросы) | ViewAlias - название представления |
current-view-requests |
Количество запросов на получение данных из представлений в данный момент (учитываются как внутренние, так и внешние запросы) | Отсутствуют |
total-content-by-link-requests |
Количество запросов на получение контента по ссылке | ContentType - тип запрашиваемого контента |
total-content-by-link-requests-duration |
Суммарное время выполнения запросов на получение контента по ссылке в миллисекундах | ContentType - тип запрашиваемого контента |
current-content-by-link-requests |
Количество запросов на получение контента по ссылке в данный момент | Отсутствуют |
current-sequential-background-queue-tasks |
Количество заданий для последовательного выполнения в очереди фоновых задач в данный момент | Отсутствуют |
current-parallel-background-queue-tasks |
Количество заданий для параллельного выполнения в очереди фоновых задач в данный момент | Отсутствуют |
Note
Для написания своих счётчиков обратитесь к документации .NET или же к “Руководству разработчика” к разделу Добавление трассировки обработки запросов и счётчиков производительности на сервере.