Мониторинг .NET приложений с помощью Proto Observability

Подключение трейсинга и сбора метрик для .NET приложений.

На этой странице:

Установка .NET трейсера

Proto Observability Platform поддерживает следующие трейсеры для .NET:

Трейсер ProtoOBP для .NET — основной способ инструментации, описанный на этой странице. Следуйте инструкции по установке ниже.

Proto Observability Platform принимает трейсы от трейсера Datadog для .NET. Установите трейсер по официальной документации Datadog и направьте телеметрию на Агент ProtoOBP.

Этот вариант предназначен для миграции приложений, уже инструментированных агентом New Relic: их распределённые трейсы направляются в Proto Observability Platform без изменения кода. Для новых приложений он не рекомендуется — используйте один из трейсеров, рекомендованных на этой странице.

Подробнее: Подключение приложений с трейсерами New Relic.

  1. Выполните шаги, указанные на странице подключения инструментации OpenTelemetry для .NET:

    https://opentelemetry.io/docs/languages/dotnet/

  2. Выполните шаги, указанные на странице настройки OpenTelemetry в Proto Observability Platform.

После установки и настройки Агента ProtoOBP следующим шагом будет добавление библиотеки трассировки непосредственно в приложение для его инструментации.

Вы можете установить .NET Tracer на всю машину, чтобы все службы на машине были инструментированы, или установить его для каждого приложения отдельно, чтобы разработчики могли управлять инструментацией через зависимости приложения. Чтобы просмотреть инструкции по установке на всю машину, перейдите на вкладку Windows или Linux. Чтобы просмотреть инструкции по установке для каждого приложения, перейдите на вкладку NuGet.

Для установки .NET трейсера на всю машину в Windows:

  1. Скачайте 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"
      )
      
  2. Запустите MSI пакет с привилегиями Администратора в интерактивном режиме, или из PowerShell:

    Start-Process -Wait msiexec -ArgumentList '/qn /i protoobp-dotnet-apm-2.56.0-x64.msi'
    

Для установки .NET трейсера на всю машину в Linux:

  1. Скачайте соответствующий пакет для вашей ОС и архитектуры, замените <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
      
  2. Запустите команды для установки трейсера и создания директории /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 пакетов:

  1. Настройте проксирование ProtoOBP NuGet репозитрия на своем локальном репозитории. Адрес репозитория:

    https://git.proto.group/api/v4/projects/125/packages/nuget/index.json

    Данные аутентификации берутся из вашего лицензионного сертификата.

    Выполните добавление пакета:

    nuget install Protoobp.Trace.Bundle
    
  2. Использование 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> берутся из лицензионного сертификата.

  3. Добавление 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.nupkg
      

      Protoobp.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 трейсер для вашего сервиса, установите необходимые переменные окружения и перезапустите приложение.

  1. MSI установщик .NET трейсера добавляет все необходимые переменные окружения. Дополнительно переменные окружения настраивать не нужно.

    Обратите внимание: Вам следует установит параметр .NET CLR version для application pool в IIS в значение No Managed Code как рекомендовано Microsoft.

  2. Для автоматической инструментации приложений, размещенных в IIS, полностью остановите и запустите IIS, выполнив следующие команды от имени Администратора:

    net stop /y was
    net start w3svc
    # Также запустите все другие службы, которые были остановлены в момент остановки WAS.
    

    Важно: Всегда используйте команды выше для полной остановки и перезапуска IIS для активации трейсера. Не используйте графическую консоль IIS Manager или iisreset.exe.

  1. Чтобы автоматическая инструментация с помощью .NET трейсера подключилась к вашему приложению, необходимы следующие переменные окружения:

    COR_ENABLE_PROFILING=1
    
  2. Для автономных приложений и служб Windows перезапустите приложение вручную.

Активация трейсера для .NET Core приложений

Чтобы включить .NET трейсер для вашего сервиса, установите необходимые переменные окружения и перезапустите приложение.

Internet Information Services (IIS)

  1. MSI установщик .NET трейсера добавляет все необходимые переменные окружения. Дополнительно переменные окружения настраивать не нужно.

    Обратите внимание: Вам следует установит параметр .NET CLR version для application pool в IIS в значение No Managed Code как рекомендовано Microsoft.

  2. Для автоматической инструментации приложений, размещенных в IIS, полностью остановите и запустите IIS, выполнив следующие команды от имени Администратора:

    net stop /y was
    net start w3svc
    # Также запустите все другие службы, которые были остановлены в момент остановки WAS.
    

    Важно: Всегда используйте команды выше для полной остановки и перезапуска IIS для активации трейсера. Не используйте графическую консоль IIS Manager или iisreset.exe.

Сервисы не в IIS

  1. Чтобы автоматическая инструментация с помощью .NET трейсера подключилась к вашему приложению, необходимы следующие переменные окружения:

    CORECLR_ENABLE_PROFILING=1
    
  2. Для автономных приложений и служб Windows перезапустите приложение вручную.

После установки трейсера с помощью deb, rpm или tar.gz пакета, необходимо задать приложению переменные окружения:

  1. Установите следующие необходимые переменные окружения, чтобы трейсер автоматически подключился к вашему приложению:

    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
    
  2. Перезапустите приложение.

При использовании 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

  1. Убедитесь, что у вас успешно установлен и настроен ProtoOBP Агент для Kubernetes.

  2. Убедитесь, что у вас установлен 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>"            
            

Переименование автоматически обнаруженных сервисов в IIS

При установке .NET трейсера на сервер с IIS трейсер автоматически создаёт по сервису на каждый application pool. Для приложений, состоящих из множества внутренних компонентов (например, SharePoint), это приводит к появлению большого количества служебных сервисов с малочитаемыми именами вида sharepoint_web_services/761ed50d49514a79888c64d16745de68, microsoft.servicebus.gateway, microsoft.workflow.servicehost и т.п.

Имена сервисов можно переопределить тремя способами в зависимости от задачи.

Применимость

  • IIS 10.0 (Windows Server 2016 и новее) — поддерживается задание переменных окружения для конкретного application pool через applicationHost.config. Все три способа ниже применимы.
  • IIS 8.5 и старее — задание переменных окружения для отдельного application pool штатно не поддерживается. Доступно только глобальное задание через реестр в ключе HKLM\System\CurrentControlSet\Services\WAS, а также способ 2 (service mapping) и способ 3 (отключение инструментации).

Способ 1. Переменная POBP_SERVICE для конкретного application pool

Переменная POBP_SERVICE, заданная для application pool, переопределяет автоматически определённое имя сервиса для всех приложений этого пула.

PowerShell (от имени Администратора):

Import-Module WebAdministration

Add-WebConfigurationProperty `
  -pspath 'MACHINE/WEBROOT/APPHOST' `
  -filter "system.applicationHost/applicationPools/add[@name='SharePoint Web Services Root']/environmentVariables" `
  -name "." `
  -value @{name='POBP_SERVICE'; value='sharepoint-web-services'}

appcmd.exe:

%windir%\system32\inetsrv\appcmd.exe set config -section:system.applicationHost/applicationPools ^
  /+"[name='SharePoint Web Services Root'].environmentVariables.[name='POBP_SERVICE',value='sharepoint-web-services']" ^
  /commit:apphost

Назначение имён сразу для нескольких application pool’ов (PowerShell):

$mapping = @{
    'SharePoint Web Services Root'    = 'sharepoint-web-services'
    'SecurityTokenServiceApplicationPool' = 'sharepoint-sts'
    'SharePoint Central Administration v4' = 'sharepoint-central-admin'
}

foreach ($pool in $mapping.Keys) {
    Add-WebConfigurationProperty `
      -pspath 'MACHINE/WEBROOT/APPHOST' `
      -filter "system.applicationHost/applicationPools/add[@name='$pool']/environmentVariables" `
      -name "." `
      -value @{name='POBP_SERVICE'; value=$mapping[$pool]}
}

Изменение существующего значения:

Set-WebConfigurationProperty `
  -pspath 'MACHINE/WEBROOT/APPHOST' `
  -filter "system.applicationHost/applicationPools/add[@name='SharePoint Web Services Root']/environmentVariables/add[@name='POBP_SERVICE']" `
  -name "value" `
  -value "sharepoint-web-services-prod"

Удаление переменной:

Remove-WebConfigurationProperty `
  -pspath 'MACHINE/WEBROOT/APPHOST' `
  -filter "system.applicationHost/applicationPools/add[@name='SharePoint Web Services Root']/environmentVariables" `
  -name "." `
  -AtElement @{name='POBP_SERVICE'}

Этот способ — основной для SharePoint, поскольку имена вида sharepoint_web_services/<GUID> различаются на каждой ферме, и единого статического значения для подмены через service mapping у них нет.

Способ 2. POBP_TRACE_SERVICE_MAPPING для статически именованных сервисов

Переменная POBP_TRACE_SERVICE_MAPPING принимает список пар <old_name>:<new_name>, разделённых запятыми, и применяется к именам сервисов на стороне трейсера. Подходит для сервисов с фиксированными именами, не зависящими от установки.

Задаётся глобально на уровне WAS — в реестре HKLM\System\CurrentControlSet\Services\WAS, multi-string значение Environment:

POBP_TRACE_SERVICE_MAPPING=microsoft.servicebus.gateway:sharepoint-servicebus,microsoft.workflow.servicehost:sharepoint-workflow

Эквивалент через PowerShell:

$existing = (Get-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Services\WAS' -Name 'Environment' -ErrorAction SilentlyContinue).Environment
$entry    = 'POBP_TRACE_SERVICE_MAPPING=microsoft.servicebus.gateway:sharepoint-servicebus,microsoft.workflow.servicehost:sharepoint-workflow'

$value = if ($existing) { @($existing) + $entry } else { @($entry) }

Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Services\WAS' `
  -Name 'Environment' `
  -Value $value `
  -Type MultiString

Если на одном application pool заданы и POBP_SERVICE, и в глобальном POBP_TRACE_SERVICE_MAPPING указан соответствующий ключ — приоритет у POBP_SERVICE.

Способ 3. Отключение инструментации отдельных application pool’ов

Если служебные application pool’ы не должны попадать в наблюдение, инструментацию для них можно отключить, переопределив COR_ENABLE_PROFILING=0 (для .NET Framework) или CORECLR_ENABLE_PROFILING=0 (для .NET Core) на уровне application pool. Глобальные значения, выставленные MSI-установщиком на уровне WAS, при этом не меняются — переопределение действует только для указанного пула.

Add-WebConfigurationProperty `
  -pspath 'MACHINE/WEBROOT/APPHOST' `
  -filter "system.applicationHost/applicationPools/add[@name='Microsoft.Workflow.ServiceHost']/environmentVariables" `
  -name "." `
  -value @{name='COR_ENABLE_PROFILING'; value='0'}

После рестарта application pool’а его процессы перестанут загружать профайлер трейсера и сервис исчезнет из списка.

Структура applicationHost.config

Все изменения, выполненные через PowerShell или appcmd, записываются в файл C:\Windows\System32\inetsrv\config\applicationHost.config. Соответствующий фрагмент выглядит следующим образом:

<system.applicationHost>
  <applicationPools>
    <add name="SharePoint Web Services Root" managedRuntimeVersion="" managedPipelineMode="Integrated">
      <environmentVariables>
        <add name="POBP_SERVICE" value="sharepoint-web-services" />
      </environmentVariables>
    </add>
    <add name="SecurityTokenServiceApplicationPool">
      <environmentVariables>
        <add name="POBP_SERVICE" value="sharepoint-sts" />
      </environmentVariables>
    </add>
  </applicationPools>
</system.applicationHost>

Параметры команд:

  • -pspath 'MACHINE/WEBROOT/APPHOST' — указатель на applicationHost.config (а не на web.config отдельного сайта).
  • -filter — XPath-выражение к нужному узлу <environmentVariables>.
  • -name "." (PowerShell) или /+ (appcmd) — добавление дочернего элемента в коллекцию.
  • /commit:apphost (appcmd) — сохранить изменения в applicationHost.config.

Прямое редактирование XML также допустимо, но требует остановки WAS на время правки и повышает риск синтаксической ошибки. Рекомендуется использовать PowerShell или appcmd.

Применение изменений

Переменные окружения application pool считываются при запуске worker-процесса. После любых изменений необходимо перезапустить процессы.

Перезапуск конкретного application pool’а:

Restart-WebAppPool -Name "SharePoint Web Services Root"

Полный перезапуск IIS (необходим, если одновременно меняются переменные на уровне WAS):

net stop /y was
net start w3svc
# Также запустите все остальные службы, которые были остановлены при остановке WAS.

iisreset.exe и графический IIS Manager для перезапуска IIS использовать не следует — они не выполняют полного отключения WAS, и нативный профайлер трейсера может не подхватить новые переменные. См. также раздел Активация трейсера для .NET Core приложений.

Проверка результата

После перезапуска application pool’а можно убедиться, что переменные окружения попали в worker-процесс w3wp.exe.

Список запущенных worker-процессов и application pool’ов, к которым они привязаны:

Get-CimInstance Win32_Process -Filter "Name='w3wp.exe'" |
  Select-Object ProcessId, CommandLine

В параметре CommandLine каждого процесса присутствует имя application pool’а в виде -ap "<pool name>".

Чтобы посмотреть фактические переменные окружения процесса, удобно использовать Process Explorer (Sysinternals): Properties → Environment. Переменные POBP_SERVICE, COR_ENABLE_PROFILING и др., заданные на уровне application pool, должны присутствовать в списке.

Имя сервиса в интерфейсе ProtoOBP начнёт обновляться через несколько минут после первой полезной нагрузки на приложение.

Диагностика неполадок

Если после подключения трейсера данные в интерфейсе ProtoOBP не отображаются:

  1. Проверьте, что установлены все необходимые переменные окружения для работы трейсера.
  2. Проверьте, что переменные окружения указаны с учетом типа ОС (например, для alpine путь должен включать -musl).
  3. Дайте нагрузку на приложение (вызовы к приложению).
  4. Проверьте логи запуска вашего приложения (stdout или файл), в них при успешном подключении трейсера должны быть записи от трейсера.
  5. Проверьте, что на машине/поде с приложением создалась директория /var/log/protoobp/dotnet и в ней есть логи.
  6. Проверьте логи трейсера в директории /var/log/protoobp/dotnet на предмет ошибок подключения к Агенту:
    • dotnet-tracer-managed-{processName}-{timestamp}.log содержит логи конфигурации
    • dotnet-tracer-native-{processName}-{processID}.log содержит логи диагностики (могут отсутствовать)
  7. Проверьте, что от контейнера/пода с приложением есть сетевой доступ до Агента по порту 8126/tcp и 8125/udp (в случае Kubernetes – по NodeIP).
  8. Добавьте переменные окружения к приложению для вывода отладочной инфинформации:
    POBP_TRACE_DEBUG=true
    POBP_TRACE_STARTUP_LOGS=true
    
  9. Заново дайте назрузку на приложение и проверьте данные в интерфейсе 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":[]}
  1. На строне агента:
    1. проверьте логи агента на предмет ошибок подключения к бэкенду.
  2. На стороне бэкенда:
    1. проверьте что в логах контейнера proto-nginx нет ошибок, если есть - перезапустите контейнер.
    2. проверьте что в логах контейнера 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_systemgaugeКоличество миллисекунд, выполняемых в ядре.
runtime_dotnet_cpu_usergaugeКоличество миллисекунд, выполняемых вне ядра.
runtime_dotnet_cpu_percentgaugeПроцент от общего CPU, используемого приложением.
runtime_dotnet_mem_committedgaugeИспользование памяти.
runtime_dotnet_threads_countgaugeКоличество потоков.
runtime_dotnet_threads_workers_countgaugeКоличество worker’ов в threadpool (только для .NET Core 3.1+).
runtime_dotnet_threads_contention_timegaugeСуммарное время, затраченное потоками на ожидание блокировки (только для .NET Core 3.1+).
runtime_dotnet_threads_contention_countcountКоличество раз, когда поток останавливался для ожидания блокировки.
runtime_dotnet_exceptions.countcountКоличество исключений первого шанса.
runtime_dotnet_gc_size_gen0gaugeРазмер кучи 0-го поколения.
runtime_dotnet_gc_size_gen1gaugeРазмер кучи 1-го поколения.
runtime_dotnet_gc_size_gen2gaugeРазмер кучи 2-го поколения.
runtime_dotnet_gc_size_lohgaugeРазмер кучи больших объектов.
runtime_dotnet_gc_memory_loadgaugeПроцент от общего объема памяти, используемой процессом. GC меняет свое поведение, когда это значение становится больше 85. (Только для .NET Core 3.1+).
runtime_dotnet_gc_pause_timegaugeКоличество времени, в течение которого GC приостанавливал потоки приложения (только для .NET Core 3.1+).
runtime_dotnet_gc_cunt_gen0countКоличество сборов мусора 0-го поколения.
runtime_dotnet_gc_cunt_gen1countКоличество сборов мусора 1-го поколения.
runtime_dotnet_gc_cunt_gen2countКоличество сборов мусора 2-го поколения.
runtime_dotnet_aspnetcore_requests_totalgaugeОбщее количество HTTP-запросов, полученных сервером (только для .NET Core 3.1+).
runtime_dotnet_aspnetcore_requests_failedgaugeКоличество неудачных HTTP-запросов, полученных сервером (только для .NET Core 3.1+).
runtime_dotnet_aspnetcore_requests_currentgaugeОбщее количество HTTP-запросов, которые были запущены, но еще не остановлены (только для .NET Core 3.1+).
runtime_dotnet_aspnetcore_requests_queue_lengthgaugeТекущая длина очереди HTTP-запросов сервера (только для .NET 5+).
runtime_dotnet_aspnetcore_connections_totalgaugeОбщее количество HTTP-соединений, установленных с сервером (только для .NET 5+).
runtime_dotnet_aspnetcore_connections_currentgaugeТекущее количество активных HTTP-соединений с сервером (только для .NET 5+).
runtime_dotnet_aspnetcore_connections_queue_lengthgaugeТекущая длина очереди 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=&quot;${mdlc:item=pobp.env}&quot;,pobp.service=&quot;${mdlc:item=pobp.service}&quot;,pobp.version=&quot;${mdlc:item=pobp.version}&quot;,pobp.trace_id=&quot;${mdlc:item=pobp.trace_id}&quot;,pobp.span_id=&quot;${mdlc:item=pobp.span_id}&quot;}
        -->
        <!--
            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=&quot;${mdlc:item=pobp.env}&quot;,pobp.service=&quot;${mdlc:item=pobp.service}&quot;,pobp.version=&quot;${mdlc:item=pobp.version}&quot;,pobp.trace_id=&quot;${mdlc:item=pobp.trace_id}&quot;,pobp.span_id=&quot;${mdlc:item=pobp.span_id}&quot;}|${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
AerospikeAerospike.Client 4.0.0+Aerospike
ASP.NET CoreMicrosoft.AspNetCore
Microsoft.AspNetCore.App
2.0+ и 3.0+
AspNetCore
Azure FunctionsMicrosoft.Azure.Webjobs 3.0+AzureFunctions
Amazon DynamoDBAWSSDK.DynamoDBv2 3.0+AwsDynamoDb
Amazon KinesisAWSSDK.Kinesis 3.0+AwsKinesis
Amazon SNSAWSSDK.SNS 3.0+AwsSns
Amazon SQSAWSSDK.SQS 3.0+AwsSqs
CosmosDbMicrosoft.Azure.Cosmos 3.6.0+CosmosDb
CouchbaseCouchbaseNetClient 2.2.8+Couchbase
ElasticsearchElasticsearch.Net 5.3.0+ElasticsearchNet
GraphQL .NETGraphQL 2.3.0+GraphQL
gRPCGrpc.Net.Client2.30.0+ (только .NET Core 3.0+)
Grpc.Core 2.30.0+
Grpc.AspNetCore 2.30.0+
Grpc
HotChocolateHotChocolate 11.0.0+HotChocolate
HttpClient / HttpMessageHandlerSystem.Net.Http 4.0+HttpMessageHandler
KafkaConfluent.Kafka 1.4+Kafka
IBM MQamqmdnetstd 9.0.0+IbmMq
MongoDBMongoDB.Driver.Core 2.1.0+MongoDb
MySqlMySql.Data 6.7.0+
MySqlConnector 0.61.0+
MySql
OracleOracle.ManagedDataAccess 4.122.0+Oracle
PostgreSQLNpgsql 4.0+Npgsql
Process"System.Diagnostics.Process" 4.0+Process
RabbitMQRabbitMQ.Client 3.6.9+ .RabbitMQ
Redis (ServiceStack client)ServiceStack.Redis 4.0.48+ServiceStackRedis
Redis (StackExchange client)StackExchange.Redis 1.0.187+StackExchangeRedis
Service Fabric RemotingMicrosoft.ServiceFabric.Services.Remoting 4.0.470+ServiceRemoting
SQLiteSystem.Data.Sqlite 2.0.0+
Microsoft.Data.Sqlite 1.0.0+
Sqlite
SQL ServerSystem.Data 4.0.0+
System.Data.SqlClient 4.0.0+
Microsoft.Data.SqlClient 1.0.0+
SqlClient
WebClient / WebRequestSystem.Net.Requests 4.0+WebRequest

.NET Framework

Фреймворк или библиотекаNuGet пакетНазвание интеграции
.NET Remotingbuilt-inRemoting
ADO.NETВсе AdoNet интеграцииAdoNet
AerospikeAerospike.Client 4.0.0+Aerospike
ASP.NET (including Web Forms)встроеноAspNet
ASP.NET MVCMicrosoft.AspNet.Mvc 4.0+AspNetMvc
ASP.NET Web API 2Microsoft.AspNet.WebApi 5.1+AspNetWebApi2
Amazon DynamoDBAWSSDK.DynamoDBv2 3.0+AwsDynamoDb
Amazon KinesisAWSSDK.Kinesis 3.0+AwsKinesis
Amazon SNSAWSSDK.SNS 3.0+AwsSns
Amazon SQSAWSSDK.SQS 3.0+AwsSqs
CosmosDbMicrosoft.Azure.Cosmos 3.6.0+CosmosDb
CouchbaseCouchbaseNetClient 2.2.8+Couchbase
ElasticsearchElasticsearch.Net 5.3.0+ElasticsearchNet
GraphQL .NETGraphQL 2.3.0+GraphQL
gRPCGrpc.Core 2.3.0+Grpc
HotChocolateHotChocolate 11.0.0+HotChocolate
HttpClient / HttpMessageHandlerвстроеноHttpMessageHandler
IBM MQamqmdnetstd 9.0.0+IbmMq
KafkaConfluent.Kafka 1.4+Kafka
MongoDBMongoDB.Driver.Core 2.1.0+MongoDb
MSMQвстроеноMsmq
MySqlMySql.Data 6.7.0+
MySqlConnector 0.61.0+
MySql
OracleOracle.ManagedDataAccess 4.122.0+Oracle
PostgreSQLNpgsql 4.0+Npgsql
Process"System.Diagnostics.Process" 4.0+Process
RabbitMQRabbitMQ.Client 3.6.9+,RabbitMQ
Redis (ServiceStack client)ServiceStack.Redis 4.0.48+ServiceStackRedis
Redis (StackExchange client)StackExchange.Redis 1.0.187+StackExchangeRedis
SQLiteSystem.Data.Sqlite 2.0.0+
Microsoft.Data.Sqlite 1.0.0+
Sqlite
SQL ServerSystem.Data 4.0.0+
System.Data.SqlClient 4.0.0+
Microsoft.Data.SqlClient 1.0.0+
SqlClient
WCF (server)встроеноWcf
WebClient / WebRequestвстроеноWebRequest