Мониторинг .NET приложений с помощью Proto Observability
На этой странице:
- Установка .NET трейсера
- Активация трейсера для .NET Framework приложений
- Активация трейсера для .NET Core приложений
- Подробнее про настройку переменных окружения
- Если приложение работает в Kubernetes
- Диагностика неполадок
- Метрики .NET
- Примеры Dockefile
- Корреляция трейсов и логов
- Поддерживаемые технологии
Установка .NET трейсера
После установки и настройки Агента ProtoOBP следующим шагом будет добавление библиотеки трассировки непосредственно в приложение для его инструментации.
Вы можете установить .NET Tracer на всю машину, чтобы все службы на машине были инструментированы, или установить его для каждого приложения отдельно, чтобы разработчики могли управлять инструментацией через зависимости приложения. Чтобы просмотреть инструкции по установке на всю машину, перейдите на вкладку Windows или Linux. Чтобы просмотреть инструкции по установке для каждого приложения, перейдите на вкладку NuGet.
Для установки .NET трейсера на всю машину в Windows:
- 
Скачайте MSI установщик для подходящий архитектуры (x64 или x86), замените <YOUR_TOKEN>на значение вашего токена из лицензионного сертификата:- C помощью curl на MacOS или Linux:
curl --header "PRIVATE-TOKEN:<YOUR_TOKEN>" \ "https://git.proto.group/api/v4/projects/125/packages/generic/protoobp-dotnet-apm/2.56.0/protoobp-dotnet-apm-2.56.0-x64.msi" \ --output protoobp-dotnet-apm-2.56.0-x64.msi
- или с помощью PowerShell на Windows:
$webClient = New-Object System.Net.WebClient $webClient.Headers.Add("PRIVATE-TOKEN", "<YOUR_TOKEN>") $webClient.DownloadFile( "https://git.proto.group/api/v4/projects/125/packages/generic/protoobp-dotnet-apm/2.56.0/protoobp-dotnet-apm-2.56.0-x64.msi", "protoobp-dotnet-apm-2.56.0-x64.msi" )
 
- C помощью curl на MacOS или Linux:
- 
Запустите MSI пакет с привилегиями Администратора в интерактивном режиме, или из PowerShell: Start-Process -Wait msiexec -ArgumentList '/qn /i protoobp-dotnet-apm-2.56.0-x64.msi'
Для установки .NET трейсера на всю машину в Linux:
- 
Скачайте соответствующий пакет для вашей ОС и архитектуры, замените <YOUR_TOKEN>на значение вашего токена из лицензионного сертификата:- 
Debian или Ubuntu curl --header "PRIVATE-TOKEN:<YOUR_TOKEN>" \ "https://git.proto.group/api/v4/projects/125/packages/generic/protoobp-dotnet-apm/2.56.0/protoobp-dotnet-apm_2.56.0_amd64.deb" \ --output protoobp-dotnet-apm_2.56.0_amd64.deb
- 
CentOS или Fedora curl --header "PRIVATE-TOKEN:<YOUR_TOKEN>" \ "https://git.proto.group/api/v4/projects/125/packages/generic/protoobp-dotnet-apm/2.56.0/protoobp-dotnet-apm-2.56.0-1.x86_64.rpm" \ --output protoobp-dotnet-apm-2.56.0-1.x86_64.rpm
- 
Alpine или другие musl-based дистрибутивы curl --header "PRIVATE-TOKEN:<YOUR_TOKEN>" \ "https://git.proto.group/api/v4/projects/125/packages/generic/protoobp-dotnet-apm/2.56.0/protoobp-dotnet-apm-2.56.0-musl.tar.gz" \ --output protoobp-dotnet-apm-2.56.0-musl.tar.gz
- 
Прочие дистрибутивы sudo tar -C /opt/protoobp -xzf protoobp-dotnet-apm-2.56.0.tar.gz && /opt/protoobp/createLogPath.sh
 
- 
- 
Запустите команды для установки трейсера и создания директории /var/log/protoobp/dotnetс необходимыми разрешениями:- 
Debian или Ubuntu sudo dpkg -i ./protoobp-dotnet-apm_2.56.0_amd64.deb && /opt/protoobp/createLogPath.sh
- 
CentOS или Fedora sudo rpm -Uvh protoobp-dotnet-apm-2.56.0-1.x86_64.rpm && /opt/protoobp/createLogPath.sh
- 
Alpine или другие musl-based дистрибутивы sudo tar -C /opt/protoobp -xzf protoobp-dotnet-apm-2.56.0-musl.tar.gz && sh /opt/protoobp/createLogPath.sh
- 
Прочие дистрибутивы sudo tar -C /opt/protoobp -xzf protoobp-dotnet-apm-2.56.0.tar.gz && /opt/protoobp/createLogPath.sh
- 
Контейнеры без shell Для установки .NET трейсера в ограниченные образы Docker, в которых нет оболочки shell и других (например distroless), используйте следующие команды в Dockerfile: - Используйте ADDдля добавления файлов в образ контейнера
- Используйте COPY --chown=$APP_UIDс пустой директорией в качестве источника для создания директории логов
 Пример Dockerfile: ADD protoobp-dotnet-apm-2.56.0.tar.gz /opt/protoobp/ COPY --chown=$APP_UID --from=<OTHER_STAGE> /empty/ /var/log/prototoobp/dotnet/
- Используйте 
 
- 
Важно
Этот вариант установки не предназначен для приложений, работающих в IIS. Для приложений, работающих в IIS, следуйте процессу установки трейсера для всей машины Windows.
Необходимо добавить Protoobp.Trace.Bundle NuGet пакет в ваше приложение. Также потребуется NuGet пакет Protoobp.Trace – убедитесь, что оба пакета доступны либо через NuGet репозиторий, либо в виде локальных файлов.
Варианты добавления NuGet пакетов:
- 
Настройте проксирование ProtoOBP NuGet репозитрия на своем локальном репозитории. Адрес репозитория: https://git.proto.group/api/v4/projects/125/packages/nuget/index.jsonДанные аутентификации берутся из вашего лицензионного сертификата. Выполните добавление пакета: nuget install Protoobp.Trace.Bundle
- 
Использование NuGet репозитория ProtoOBP. nuget source Add -Name "ProtoOBP" -Source "https://git.proto.group/api/v4/projects/125/packages/nuget/index.json" -UserName <your_username> -Password <your_token> nuget install Protoobp.Trace.Bundle -Source "ProtoOBP"Значения <your_username>и<your_token>берутся из лицензионного сертификата.
- 
Добавление NuGet пакетов в виде файлов. - 
Скачайте файлы двух NuGet пакетов: Protoobp.Trace.Bundle.2.56.0.nupkg: curl --header "PRIVATE-TOKEN: <your_token>" "https://git.proto.group/api/v4/projects/125/packages/generic/protoobp-dotnet-apm/v2.56.0/protoobp.trace.bundle.2.56.0.nupkg" --output protoobp.trace.bundle.2.56.0.nupkgProtoobp.Trace.2.56.0.nupkg: curl --header "PRIVATE-TOKEN: <your_token>" "https://git.proto.group/api/v4/projects/125/packages/generic/protoobp-dotnet-apm/v2.56.0/protoobp.trace.2.56.0.nupkg" --output protoobp.trace.2.56.0.nupkgЗамените <your_token>на значение вашего токена из лицензионного сертификата.
- 
Добавьте в директорию packagesв каталоге с приложением два файла NuGet, скачанные ранее:- Protoobp.Trace.2.56.0.nupkg
- Protoobp.Trace.Bundle.2.56.0.nupkg
 
- 
Измените nuget.confи добавьте строку с новым источником (директорияpackages):<?xml version="1.0" encoding="utf-8"?> <configuration> <packageSources> <add key="nuget" value="https://api.nuget.org/v3/index.json" /> <add key="Local Packages" value="packages" /> </packageSources> </configuration>
- 
Измените .csprojвашего приложения, добавив информацию о зависимости:<ItemGroup> <PackageReference Include="Protoobp.Trace.Bundle" Version="2.56.0" /> </ItemGroup>
 
- 
Активация трейсера для .NET Framework приложений
Чтобы включить .NET трейсер для вашего сервиса, установите необходимые переменные окружения и перезапустите приложение.
- 
MSI установщик .NET трейсера добавляет все необходимые переменные окружения. Дополнительно переменные окружения настраивать не нужно. Обратите внимание: Вам следует установит параметр .NET CLR versionдля application pool в IIS в значениеNo Managed Codeкак рекомендовано Microsoft.
- 
Для автоматической инструментации приложений, размещенных в IIS, полностью остановите и запустите IIS, выполнив следующие команды от имени Администратора: net stop /y was net start w3svc # Также запустите все другие службы, которые были остановлены в момент остановки WAS.Важно: Всегда используйте команды выше для полной остановки и перезапуска IIS для активации трейсера. Не используйте графическую консоль IIS Manager или iisreset.exe.
- 
Чтобы автоматическая инструментация с помощью .NET трейсера подключилась к вашему приложению, необходимы следующие переменные окружения: COR_ENABLE_PROFILING=1
- 
Для автономных приложений и служб Windows перезапустите приложение вручную. 
Активация трейсера для .NET Core приложений
Чтобы включить .NET трейсер для вашего сервиса, установите необходимые переменные окружения и перезапустите приложение.
Internet Information Services (IIS)
- 
MSI установщик .NET трейсера добавляет все необходимые переменные окружения. Дополнительно переменные окружения настраивать не нужно. Обратите внимание: Вам следует установит параметр .NET CLR versionдля application pool в IIS в значениеNo Managed Codeкак рекомендовано Microsoft.
- 
Для автоматической инструментации приложений, размещенных в IIS, полностью остановите и запустите IIS, выполнив следующие команды от имени Администратора: net stop /y was net start w3svc # Также запустите все другие службы, которые были остановлены в момент остановки WAS.Важно: Всегда используйте команды выше для полной остановки и перезапуска IIS для активации трейсера. Не используйте графическую консоль IIS Manager или iisreset.exe.
Сервисы не в IIS
- 
Чтобы автоматическая инструментация с помощью .NET трейсера подключилась к вашему приложению, необходимы следующие переменные окружения: CORECLR_ENABLE_PROFILING=1
- 
Для автономных приложений и служб Windows перезапустите приложение вручную. 
После установки трейсера с помощью deb, rpm или tar.gz пакета, необходимо задать приложению переменные окружения:
- 
Установите следующие необходимые переменные окружения, чтобы трейсер автоматически подключился к вашему приложению: CORECLR_ENABLE_PROFILING=1 CORECLR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8} CORECLR_PROFILER_PATH=/opt/protoobp/Protoobp.Trace.ClrProfiler.Native.so POBP_DOTNET_TRACER_HOME=/opt/protoopb POBP_INSTRUMENTATION_TELEMETRY_ENABLED=0
- 
Перезапустите приложение. 
При использовании NuGet необходимо установить переменные окружения, указав в них корректный путь к файлу модуля в структуре приложения, а также самостоятельно создать директорию для логов трейсера.
Переменные окружения следующие:
Для .NET Core:
CORECLR_ENABLE_PROFILING=1
CORECLR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8}
CORECLR_PROFILER_PATH=<зависит от системы, смотри ниже>
POBP_DOTNET_TRACER_HOME=<APP_DIRECTORY>/protoobp
POBP_INSTRUMENTATION_TELEMETRY_ENABLED=0
Для .NET Framework:
COR_ENABLE_PROFILING=1
COR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8}
COR_PROFILER_PATH=<зависит от системы, смотри ниже>
POBP_DOTNET_TRACER_HOME=<APP_DIRECTORY>/protoobp
POBP_INSTRUMENTATION_TELEMETRY_ENABLED=0
<APP_DIRECTORY> – это путь к файлам вашего приложения, содержащий файлы .dll приложения. Значения переменных CORECLR_PROFILER_PATH/COR_PROFILER_PATH зависят от системы, в которой запускается приложение:
| ОС и архитектура | Путь к модулю трейсера | 
|---|---|
| Alpine Linux x64 | <APP_DIRECTORY>/protoobp/linux-musl-x64/Protoobp.Trace.ClrProfiler.Native.so | 
| Linux x64 | <APP_DIRECTORY>/protoobp/linux-x64/Protoobp.Trace.ClrProfiler.Native.so | 
| Windows x64 | <APP_DIRECTORY>\protoobp\win-x64\Protoobp.Trace.ClrProfiler.Native.dll | 
| Windows x86 | <APP_DIRECTORY>\protoobp\win-x86\Protoobp.Trace.ClrProfiler.Native.dll | 
Для образов Docker, работающих под Linux, настройте образ на выполнение скрипта createLogPath.sh:
RUN /<APP_DIRECTORY>/protoobp/createLogPath.sh
Подробнее про настройку переменных окружения
Windows сервисы
- 
С помощью редактора реестра: В Редакторе Реестра, создайте multi-string значение с именем Environmentв ключеHKLM\System\CurrentControlSet\Services\<SERVICE NAME>и установите значения:- 
Для .NET Framework COR_ENABLE_PROFILING=1
- 
Для .NET Core CORECLR_ENABLE_PROFILING=1
 
- 
- 
С помощью PowerShell: - 
Для .NET Framework Set-ItemProperty HKLM:SYSTEM\CurrentControlSet\Services\<SERVICE NAME> -Name Environment -Value 'COR_ENABLE_PROFILING=1'
- 
Для .NET Core Set-ItemProperty HKLM:SYSTEM\CurrentControlSet\Services\<SERVICE NAME> -Name Environment -Value 'CORECLR_ENABLE_PROFILING=1'
 
- 
Где <SERVICE NAME> – имя сервиса, к которому производится подключение.
Internet Information Services (IIS)
После установки MSI не требуется никаких дополнительных настроек для автоматической инструментации приложений в IIS. Чтобы задать дополнительные переменные окружения, которые наследуются всеми сайтами IIS, выполните следующие действия:
Откройте редактор реестра, найдите многострочное значение Environment в ключе HKLM\System\CurrentControlSet\Services\WAS и добавьте переменные среды, по одной в строку. Например, чтобы добавить сбор runtime метрик, добавьте следующие строки в данные значения:
POBP_RUNTIME_METRICS_ENABLED=true
Выпоните следующие команды для перезапуска IIS:
net stop /y was
net start w3svc
# Также запустите все другие службы, которые были остановлены в момент остановки WAS.
Консольные приложения
Чтобы автоматически инструментировать консольное приложение, установите переменные окружения из пакетного файла перед запуском приложения:
- 
Для .NET Core SET CORECLR_ENABLE_PROFILING=1 SET POBP_INSTRUMENTATION_TELEMETRY_ENABLED=0
- 
Для .NET Framework SET COR_ENABLE_PROFILING=1 SET POBP_INSTRUMENTATION_TELEMETRY_ENABLED=0
Для установки дополнительных переменные окружения конфигурации трейсера:
SET POBP_RUNTIME_METRICS_ENABLED=true
rem Запустите приложение
dotnet.exe example.dll
Bash скрипт
Чтобы установить необходимые переменные окружения с помошью bash скрипта перед запуском приложения:
# Установка переменных окружения
export CORECLR_ENABLE_PROFILING=1
export CORECLR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8}
export CORECLR_PROFILER_PATH=/opt/protoobp/Protoobp.Trace.ClrProfiler.Native.so
export POBP_DOTNET_TRACER_HOME=/opt/protoobp
# Установка дополнительных переменных окружения
export POBP_RUNTIME_METRICS_ENABLED=true
export POBP_INSTRUMENTATION_TELEMETRY_ENABLED=0
# Запуск приложения
dotnet example.dll
Обратите внимание:
Если вы используете Alpine Linux, установите значение переменной окружения CORECLR_PROFILER_PATH в значение для musl-based дистрибутивов: /opt/protoobp/linux-musl-x64/Protoobp.Trace.ClrProfiler.Native.so.
Linux Docker контейнеры
Чтобы установить необходимые переменные окружения в контейнере Linux Docker, выполните следующие действия (Dockerfile):
# Установка переменных окружения
ENV CORECLR_ENABLE_PROFILING=1
ENV CORECLR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8}
ENV CORECLR_PROFILER_PATH=/opt/protoobp/Protoobp.Trace.ClrProfiler.Native.so
ENV POBP_DOTNET_TRACER_HOME=/opt/protoobp
# Установка дополнительных переменных окружения
ENV POBP_RUNTIME_METRICS_ENABLED=true
ENV POBP_INSTRUMENTATION_TELEMETRY_ENABLED=0
# Запуск приложения
CMD ["dotnet", "example.dll"]
systemctl (для конкретного сервиса)
При использовании systemctl для запуска приложений .NET в качестве службы вы можете добавить необходимые переменные окружения, которые будут загружаться для конкретной службы.
Создайте файл environment.env, содержащий:
# обязательные переменные окружения
CORECLR_ENABLE_PROFILING=1
CORECLR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8}
CORECLR_PROFILER_PATH=/opt/protoobp/Protoobp.Trace.ClrProfiler.Native.so
POBP_DOTNET_TRACER_HOME=/opt/protoobp
# дополнительные переменные окружения
POBP_RUNTIME_METRICS_ENABLED=true
POBP_INSTRUMENTATION_TELEMETRY_ENABLED=0
В конфигурационном файле службы укажите этот файл как EnvironmentFile в блоке службы:
[Service]
EnvironmentFile=/path/to/environment.env
ExecStart=<command used to start the application>
Перезапустите службу .NET, чтобы настройки переменной окружения применились.
Если приложение работает в Kubernetes
- 
Убедитесь, что у вас успешно установлен и настроен ProtoOBP Агент для Kubernetes. 
- 
Убедитесь, что у вас установлен dotnet трейсер. 
Дополнительно необходимо передать поду переменную окружения POBP_AGENT_HOST со значением IP адреса воркер-ноды, а также переменные окружения для связи трейсов с инфраструктурой (имя k8s кластера нужно задать вручную).
apiVersion: apps/v1
kind: Deployment
#(...)
    spec:
      containers:
      - name: "<CONTAINER_NAME>"
        image: "<CONTAINER_IMAGE>/<TAG>"
        env:
          - name: POBP_SERVICE
            value: "<YOUR_SERVICE_NAME>"			
          - name: POBP_INSTRUMENTATION_TELEMETRY_ENABLED
            value: "0"
          - name: POBP_RUNTIME_METRICS_ENABLED
            value: "true"          
          - name: POBP_AGENT_HOST
            valueFrom:
              fieldRef:
                fieldPath: status.hostIP
          - name: NODE_NAME
            valueFrom:
              fieldRef:
                fieldPath: spec.nodeName
          - name: POD_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: POBP_TAGS
            value: "pod_name:$(POD_NAME),node:$(NODE_NAME),kube_namespace:$(POD_NAMESPACE),kube_cluster_name:<your_cluster_name>"            
            
Диагностика неполадок
Если после подключения трейсера данные в интерфейсе ProtoOBP не отображаются:
- Проверьте, что установлены все необходимые переменные окружения для работы трейсера.
- Проверьте, что переменные окружения указаны с учетом типа ОС (например, для alpineпуть должен включать-musl).
- Дайте нагрузку на приложение (вызовы к приложению).
- Проверьте логи запуска вашего приложения (stdout или файл), в них при успешном подключении трейсера должны быть записи от трейсера.
- Проверьте, что на машине/поде с приложением создалась директория /var/log/protoobp/dotnetи в ней есть логи.
- Проверьте логи трейсера в директории /var/log/protoobp/dotnetна предмет ошибок подключения к Агенту:- dotnet-tracer-managed-{processName}-{timestamp}.logсодержит логи конфигурации
- dotnet-tracer-native-{processName}-{processID}.logсодержит логи диагностики (могут отсутствовать)
 
- Проверьте, что от контейнера/пода с приложением есть сетевой доступ до Агента по порту 8126/tcpи8125/udp(в случае Kubernetes – поNodeIP).
- Добавьте переменные окружения к приложению для вывода отладочной инфинформации:
POBP_TRACE_DEBUG=true POBP_TRACE_STARTUP_LOGS=true
- Заново дайте назрузку на приложение и проверьте данные в интерфейсе ProtoOBP.
Пример лога конфигурации:
2024-08-15 12:26:39.572 +03:00 [INF] PROTOOBP TRACER CONFIGURATION -
{"date":"2024-08-15T12:26:39.5615724+02:00","os_name":"Windows",
"os_version":"Microsoft Windows NT 6.2.9200.0","version":"1.17.1.0",
"platform":"x64","lang":".NET Framework","lang_version":"4.8+",
"env":null,"enabled":true,"service":"git-credential-manager",
"agent_url":"http://localhost:8126","debug":false,
"analytics_enabled":false,"sample_rate":null,"sampling_rules":null,
"tags":[],"log_injection_enabled":false,
"runtime_metrics_enabled":false,"disabled_integrations":[]}
- На строне агента:
- проверьте логи агента на предмет ошибок подключения к бэкенду.
 
- На стороне бэкенда:
- проверьте что в логах контейнера proto-nginxнет ошибок, если есть - перезапустите контейнер.
- проверьте что в логах контейнера proto-trace-processorнет ошибок (например, что закончился срок действия лицензии), если есть ошибки – перезапустите контейнер.
 
- проверьте что в логах контейнера 
Метрики .NET
Для каждого инстанса трейсер ProtoOBP собирает и отображает runtime метрики .NET. Посмотреть их можно выбрав Сервисы > дашборд .NET Сервиса, далее выбрать вкладку Инстансы > инстанс сервиса с вызовами > вкладка .NET.
Сбор метрик .NET отключен по умолчанию. Он может быть включен с помощью переменной окружения:
POBP_RUNTIME_METRICS_ENABLED=true
По умолчанию, метрики из приложений отсылаются Агенту на порт 8125.
Если Агент работает в контейнере:
- убедитесь, что переменная POBP_DOGSTATSD_NON_LOCAL_TRAFFICустановлена в значениеtrue, и что порт8125открыт на агенте;
- дополнительно для Kubernetes порт DogstatsD должен быть host port.
Список dotnet runtime метрик, собираемых ProtoOBP
| Метрика | Тип | Описание | 
|---|---|---|
| runtime_dotnet_cpu_system | gauge | Количество миллисекунд, выполняемых в ядре. | 
| runtime_dotnet_cpu_user | gauge | Количество миллисекунд, выполняемых вне ядра. | 
| runtime_dotnet_cpu_percent | gauge | Процент от общего CPU, используемого приложением. | 
| runtime_dotnet_mem_committed | gauge | Использование памяти. | 
| runtime_dotnet_threads_count | gauge | Количество потоков. | 
| runtime_dotnet_threads_workers_count | gauge | Количество worker’ов в threadpool (только для .NET Core 3.1+). | 
| runtime_dotnet_threads_contention_time | gauge | Суммарное время, затраченное потоками на ожидание блокировки (только для .NET Core 3.1+). | 
| runtime_dotnet_threads_contention_count | count | Количество раз, когда поток останавливался для ожидания блокировки. | 
| runtime_dotnet_exceptions.count | count | Количество исключений первого шанса. | 
| runtime_dotnet_gc_size_gen0 | gauge | Размер кучи 0-го поколения. | 
| runtime_dotnet_gc_size_gen1 | gauge | Размер кучи 1-го поколения. | 
| runtime_dotnet_gc_size_gen2 | gauge | Размер кучи 2-го поколения. | 
| runtime_dotnet_gc_size_loh | gauge | Размер кучи больших объектов. | 
| runtime_dotnet_gc_memory_load | gauge | Процент от общего объема памяти, используемой процессом. GC меняет свое поведение, когда это значение становится больше 85. (Только для .NET Core 3.1+). | 
| runtime_dotnet_gc_pause_time | gauge | Количество времени, в течение которого GC приостанавливал потоки приложения (только для .NET Core 3.1+). | 
| runtime_dotnet_gc_cunt_gen0 | count | Количество сборов мусора 0-го поколения. | 
| runtime_dotnet_gc_cunt_gen1 | count | Количество сборов мусора 1-го поколения. | 
| runtime_dotnet_gc_cunt_gen2 | count | Количество сборов мусора 2-го поколения. | 
| runtime_dotnet_aspnetcore_requests_total | gauge | Общее количество HTTP-запросов, полученных сервером (только для .NET Core 3.1+). | 
| runtime_dotnet_aspnetcore_requests_failed | gauge | Количество неудачных HTTP-запросов, полученных сервером (только для .NET Core 3.1+). | 
| runtime_dotnet_aspnetcore_requests_current | gauge | Общее количество HTTP-запросов, которые были запущены, но еще не остановлены (только для .NET Core 3.1+). | 
| runtime_dotnet_aspnetcore_requests_queue_length | gauge | Текущая длина очереди HTTP-запросов сервера (только для .NET 5+). | 
| runtime_dotnet_aspnetcore_connections_total | gauge | Общее количество HTTP-соединений, установленных с сервером (только для .NET 5+). | 
| runtime_dotnet_aspnetcore_connections_current | gauge | Текущее количество активных HTTP-соединений с сервером (только для .NET 5+). | 
| runtime_dotnet_aspnetcore_connections_queue_length | gauge | Текущая длина очереди HTTP-соединений сервера (только для .NET 5+). | 
Примеры Dockefile
Alpine Linux – установка TAR.GZ пакета и переменных окружения
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /app
COPY *.csproj ./
RUN dotnet restore
COPY . ./
RUN dotnet publish -c Release -f netcoreapp3.1 -o out
FROM mcr.microsoft.com/dotnet/core/runtime:3.1-alpine3.10
WORKDIR /app
COPY --from=build /app/out .
# Добавление curl 
RUN apk --no-cache update && apk add curl
# Подключение Protoobp
RUN mkdir -p /var/log/protoobp
RUN mkdir -p /opt/protoobp
RUN curl --header "PRIVATE-TOKEN:<YOUR_TOKEN>>" "https://git.proto.group/api/v4/projects/125/packages/generic/protoobp-dotnet-apm/2.56.0/protoobp-dotnet-apm-2.56.0-musl.tar.gz" \
  |  tar xzf - -C /opt/protoobp
ENV CORECLR_ENABLE_PROFILING=1
ENV CORECLR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8}
ENV CORECLR_PROFILER_PATH=/opt/protoobp/Protoobp.Trace.ClrProfiler.Native.so
ENV POBP_DOTNET_TRACER_HOME=/opt/protoobp
ENV POBP_INSTRUMENTATION_TELEMETRY_ENABLED=0
CMD ["dotnet", "ConsoleApp.dll"]
Debian Linux – установка DEB пакета и переменных окружения
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /app
COPY *.csproj ./
RUN dotnet restore
COPY . ./
RUN dotnet publish -c Release -f netcoreapp3.1 -o out
FROM mcr.microsoft.com/dotnet/core/runtime:3.1
WORKDIR /app
COPY --from=build /app/out .
# Подключение Protoobp
RUN mkdir -p /var/log/protoobp
RUN mkdir -p /opt/protoobp
RUN curl -v --header "PRIVATE-TOKEN:<your_token>" "https://git.proto.group/api/v4/projects/125/packages/generic/protoobp-dotnet-apm/2.56.0/protoobp-dotnet-apm_2.56.0_amd64.deb" -o "protoobp-dotnet-apm_2.56.0_amd64.deb"
RUN dpkg -i ./protoobp-dotnet-apm_2.56.0_amd64.deb
ENV CORECLR_ENABLE_PROFILING=1
ENV CORECLR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8}
ENV CORECLR_PROFILER_PATH=/opt/protoobp/Protoobp.Trace.ClrProfiler.Native.so
ENV POBP_DOTNET_TRACER_HOME=/opt/protoobp
ENV POBP_INSTRUMENTATION_TELEMETRY_ENABLED=0
CMD ["dotnet", "ConsoleApp.dll"]
Alpine Linux – установка NuGet пакета локально и переменных окружения
FROM mcr.microsoft.com/dotnet/runtime:5.0-alpine AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
# В nuget.config должна быть включена установка локально
COPY ["nuget.config", "./"]
# Файлы с двумя NuGet пакетам лежат в папке packages
COPY ["packages", "packages"]
COPY ["HttpListenerExample.csproj", "./"]
RUN dotnet restore "HttpListenerExample.csproj"
COPY . .
WORKDIR "/src"
RUN dotnet build "HttpListenerExample.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "HttpListenerExample.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
# Включение Protoobp трейсера для автоматической инструментации
# Приложение копируется в /app, поэтому файлы Protoobp будут в папке /app/protoobp
ENV CORECLR_ENABLE_PROFILING=1
ENV CORECLR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8}
ENV CORECLR_PROFILER_PATH=/app/protoobp/linux-musl-x64/Protoobp.Trace.ClrProfiler.Native.so
ENV POBP_DOTNET_TRACER_HOME=/app/protoobp
ENV POBP_INSTRUMENTATION_TELEMETRY_ENABLED=0
# Запуск скрипта createLogPath для создания директории с логами трейсера
RUN sh /app/protoob/createLogPath.sh
ENTRYPOINT ["dotnet", "HttpListenerExample.dll"]
Debian Linux – установка NuGet пакета локально и переменных окружения
FROM mcr.microsoft.com/dotnet/runtime:5.0 AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
# В nuget.config должна быть включена установка локально
COPY ["nuget.config", "./"]
# Файлы с двумя NuGet пакетам лежат в папке packages
COPY ["packages", "packages"]
COPY ["HttpListenerExample.csproj", "./"]
RUN dotnet restore "HttpListenerExample.csproj"
COPY . .
WORKDIR "/src"
RUN dotnet build "HttpListenerExample.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "HttpListenerExample.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
# Включение Protoobp трейсера для автоматической инструментации
# Приложение копируется в /app, поэтому файлы Protoobp будут в папке /app/protoobp
ENV CORECLR_ENABLE_PROFILING=1
ENV CORECLR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8}
ENV CORECLR_PROFILER_PATH=/app/protoobp/linux-x64/Protoobp.Trace.ClrProfiler.Native.so
ENV POBP_DOTNET_TRACER_HOME=/app/protoobp
ENV POBP_INSTRUMENTATION_TELEMETRY_ENABLED=0
# Запуск скрипта createLogPath для создания директории с логами трейсера
RUN /app/protoobp/createLogPath.sh
ENTRYPOINT ["dotnet", "HttpListenerExample.dll"]
Корреляция трейсов и логов
Для корреляции трейсов и логов необходимо:
- настроить логгер для записи служебных параметров в лог (service, traceId и др)
- настроить передачу лога в бэкенд Proto OBP
- с помощью агента Proto OBP или
- c помощью внешнего шиппера логов
 
NLog
NLog.config:
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <targets>
        <!-- For JsonLayout, you can set includeMdlc=true to automatically extract all of the Protoobp properties (see: https://github.com/NLog/NLog/wiki/JsonLayout) -->
        <!--
            Additions to layout: none
        -->
        <target name="jsonFile-includeMdlc-true" xsi:type="File" fileName="log-NLog46-jsonFile-includeMdlc-true.log">
            <layout xsi:type="JsonLayout" includeMdlc="true"> <!-- includeMdlc property available in NLog 4.4.10+ -->
                <attribute name="time" layout="${longdate}" />
                <attribute name="level" layout="${level:upperCase=true}"/>
                <attribute name="message" layout="${message}" />
                <attribute name="exception" layout="${exception:format=ToString}" />
            </layout>
        </target>
        <!-- For JsonLayout, if includeMdlc=false or if not set, you must extract the Protoobp properties individually by adding <attribute> nodes (see: https://github.com/NLog/NLog/wiki/JsonLayout) -->
        <!--
            Additions to layout:
            - <attribute name="pobp.env" layout="${mdlc:item=pobp.env}"/>
            - <attribute name="pobp.service" layout="${mdlc:item=pobp.service}"/>
            - <attribute name="pobp.version" layout="${mdlc:item=pobp.version}"/>
            - <attribute name="pobp.trace_id" layout="${mdlc:item=pobp.trace_id}"/>
            - <attribute name="pobp.span_id" layout="${mdlc:item=pobp.span_id}"/>
        -->
        <target name="jsonFile-includeMdlc-false" xsi:type="File" fileName="log-NLog46-jsonFile-includeMdlc-false.log">
            <layout xsi:type="JsonLayout">
                <attribute name="time" layout="${longdate}" />
                <attribute name="level" layout="${level:upperCase=true}"/>
                <attribute name="message" layout="${message}" />
                <attribute name="exception" layout="${exception:format=ToString}" />
                <!-- Manual changes: start -->
                <attribute name="pobp.env" layout="${mdlc:item=pobp.env}"/>
                <attribute name="pobp.service" layout="${mdlc:item=pobp.service}"/>
                <attribute name="pobp.version" layout="${mdlc:item=pobp.version}"/>
                <attribute name="pobp.trace_id" layout="${mdlc:item=pobp.trace_id}"/>
                <attribute name="pobp.span_id" layout="${mdlc:item=pobp.span_id}"/>
                <!-- Manual changes: end -->
            </layout>
        </target>
        <!-- For a custom layout, you must extract the Protoobp properties individually by using the ${mdlc:item=String} syntax (see: https://github.com/NLog/NLog/wiki/MDLC-Layout-Renderer) -->
        <!--
            Additions to layout: {pobp.env="${mdlc:item=pobp.env}",pobp.service="${mdlc:item=pobp.service}",pobp.version="${mdlc:item=pobp.version}",pobp.trace_id="${mdlc:item=pobp.trace_id}",pobp.span_id="${mdlc:item=pobp.span_id}"}
        -->
        <!--
            Parsing this log line with a custom Pipeline that adds Trace/Log correlation can be done with the following Processors:
            1. Grok Parser: Set the parsing rules to `log_parser %{date("yyyy-MM-pobp HH:mm:ss.SSSS"):time}\|%{word:level}\|%{notSpace:logger}\|\{%{data::keyvalue}}\|%{data:message}`
        -->
        <target name="textFile" xsi:type="File" fileName="log-NLog46-textFile.log"
                layout="${longdate}|${uppercase:${level}}|${logger}|{pobp.env="${mdlc:item=pobp.env}",pobp.service="${mdlc:item=pobp.service}",pobp.version="${mdlc:item=pobp.version}",pobp.trace_id="${mdlc:item=pobp.trace_id}",pobp.span_id="${mdlc:item=pobp.span_id}"}|${message}" />
    </targets>
    <!-- rules to map from logger name to target -->
    <rules>
        <logger name="*" minlevel="Trace" writeTo="jsonFile-includeMdlc-true,jsonFile-includeMdlc-false,textFile" />
    </rules>
</nlog>
Program.cs:
using Protoobp.Trace;
using NLog;
namespace NLog46Example
{
    class Program
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
        static void Main(string[] args)
        {
            using (MappedDiagnosticsLogicalContext.SetScoped("order-number", 1024))
            {
                Logger.Info("Message before a trace.");
                using (var scope = Tracer.Instance.StartActive("NLog46Example - Main()"))
                {
                    Logger.Info("Message during a trace.");
                }
                Logger.Info("Message after a trace.");
            }
        }
    }
}
Поддерживаемые технологии
Версии .NET Core
| .NET Core | Поддерживается | 
|---|---|
| .NET 8 | ✅ | 
| .NET 7 | ✅ | 
| .NET 6 | ✅ | 
| .NET 5 | ✅ | 
| .NET Core 3.1 | ✅ | 
| .NET Core 2.1 | ✅ | 
| .NET Core 3.0 | ✅ | 
| .NET Core 2.2 | ✅ | 
| .NET Core 2.0 | ✅ | 
Версии .NET Framework
| .NET Framework | Поддерживается | 
|---|---|
| 4.8.1 | ✅ | 
| 4.8 | ✅ | 
| 4.7.2 | ✅ | 
| 4.7 | ✅ | 
| 4.6.2 | ✅ | 
| 4.6.1 | ✅ | 
| 4.6 | ❌ | 
| 4.5.2 | ❌ | 
| 4.5.1 | ❌ | 
| 4.5 | ❌ | 
Архитектура
| Архитектура | Поддерживается | 
|---|---|
| Windows x86 ( win-x86) | ✅ | 
| Windows x64 ( win-x64) | ✅ | 
| Linux x64 ( linux-x64) | ✅ | 
| Alpine Linux x64 ( linux-musl-x64) | ✅ | 
Автоматическая инструментация библиотек и фреймворков
.NET Core
| Фреймворк или библиотека | NuGet пакет | Название интеграции | 
|---|---|---|
| ADO.NET | Все AdoNet интеграции | AdoNet | 
| Aerospike | Aerospike.Client4.0.0+ | Aerospike | 
| ASP.NET Core | Microsoft.AspNetCoreMicrosoft.AspNetCore.App2.0+ и 3.0+ | AspNetCore | 
| Azure Functions | Microsoft.Azure.Webjobs3.0+ | AzureFunctions | 
| Amazon DynamoDB | AWSSDK.DynamoDBv23.0+ | AwsDynamoDb | 
| Amazon Kinesis | AWSSDK.Kinesis3.0+ | AwsKinesis | 
| Amazon SNS | AWSSDK.SNS3.0+ | AwsSns | 
| Amazon SQS | AWSSDK.SQS3.0+ | AwsSqs | 
| CosmosDb | Microsoft.Azure.Cosmos3.6.0+ | CosmosDb | 
| Couchbase | CouchbaseNetClient2.2.8+ | Couchbase | 
| Elasticsearch | Elasticsearch.Net5.3.0+ | ElasticsearchNet | 
| GraphQL .NET | GraphQL2.3.0+ | GraphQL | 
| gRPC | Grpc.Net.Client2.30.0+ (только .NET Core 3.0+)Grpc.Core2.30.0+Grpc.AspNetCore2.30.0+ | Grpc | 
| HotChocolate | HotChocolate11.0.0+ | HotChocolate | 
| HttpClient / HttpMessageHandler | System.Net.Http4.0+ | HttpMessageHandler | 
| Kafka | Confluent.Kafka1.4+ | Kafka | 
| IBM MQ | amqmdnetstd9.0.0+ | IbmMq | 
| MongoDB | MongoDB.Driver.Core2.1.0+ | MongoDb | 
| MySql | MySql.Data6.7.0+MySqlConnector0.61.0+ | MySql | 
| Oracle | Oracle.ManagedDataAccess4.122.0+ | Oracle | 
| PostgreSQL | Npgsql4.0+ | Npgsql | 
| Process | "System.Diagnostics.Process"4.0+ | Process | 
| RabbitMQ | RabbitMQ.Client3.6.9+ . | RabbitMQ | 
| Redis (ServiceStack client) | ServiceStack.Redis4.0.48+ | ServiceStackRedis | 
| Redis (StackExchange client) | StackExchange.Redis1.0.187+ | StackExchangeRedis | 
| Service Fabric Remoting | Microsoft.ServiceFabric.Services.Remoting4.0.470+ | ServiceRemoting | 
| SQLite | System.Data.Sqlite2.0.0+Microsoft.Data.Sqlite1.0.0+ | Sqlite | 
| SQL Server | System.Data4.0.0+System.Data.SqlClient4.0.0+Microsoft.Data.SqlClient1.0.0+ | SqlClient | 
| WebClient / WebRequest | System.Net.Requests4.0+ | WebRequest | 
.NET Framework
| Фреймворк или библиотека | NuGet пакет | Название интеграции | 
|---|---|---|
| .NET Remoting | built-in | Remoting | 
| ADO.NET | Все AdoNet интеграции | AdoNet | 
| Aerospike | Aerospike.Client4.0.0+ | Aerospike | 
| ASP.NET (including Web Forms) | встроено | AspNet | 
| ASP.NET MVC | Microsoft.AspNet.Mvc4.0+ | AspNetMvc | 
| ASP.NET Web API 2 | Microsoft.AspNet.WebApi5.1+ | AspNetWebApi2 | 
| Amazon DynamoDB | AWSSDK.DynamoDBv23.0+ | AwsDynamoDb | 
| Amazon Kinesis | AWSSDK.Kinesis3.0+ | AwsKinesis | 
| Amazon SNS | AWSSDK.SNS3.0+ | AwsSns | 
| Amazon SQS | AWSSDK.SQS3.0+ | AwsSqs | 
| CosmosDb | Microsoft.Azure.Cosmos3.6.0+ | CosmosDb | 
| Couchbase | CouchbaseNetClient2.2.8+ | Couchbase | 
| Elasticsearch | Elasticsearch.Net5.3.0+ | ElasticsearchNet | 
| GraphQL .NET | GraphQL2.3.0+ | GraphQL | 
| gRPC | Grpc.Core2.3.0+ | Grpc | 
| HotChocolate | HotChocolate11.0.0+ | HotChocolate | 
| HttpClient / HttpMessageHandler | встроено | HttpMessageHandler | 
| IBM MQ | amqmdnetstd9.0.0+ | IbmMq | 
| Kafka | Confluent.Kafka1.4+ | Kafka | 
| MongoDB | MongoDB.Driver.Core2.1.0+ | MongoDb | 
| MSMQ | встроено | Msmq | 
| MySql | MySql.Data6.7.0+MySqlConnector0.61.0+ | MySql | 
| Oracle | Oracle.ManagedDataAccess4.122.0+ | Oracle | 
| PostgreSQL | Npgsql4.0+ | Npgsql | 
| Process | "System.Diagnostics.Process"4.0+ | Process | 
| RabbitMQ | RabbitMQ.Client3.6.9+, | RabbitMQ | 
| Redis (ServiceStack client) | ServiceStack.Redis4.0.48+ | ServiceStackRedis | 
| Redis (StackExchange client) | StackExchange.Redis1.0.187+ | StackExchangeRedis | 
| SQLite | System.Data.Sqlite2.0.0+Microsoft.Data.Sqlite1.0.0+ | Sqlite | 
| SQL Server | System.Data4.0.0+System.Data.SqlClient4.0.0+Microsoft.Data.SqlClient1.0.0+ | SqlClient | 
| WCF (server) | встроено | Wcf | 
| WebClient / WebRequest | встроено | WebRequest |