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

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

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

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

После установки и настройки Агента 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
    
  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

Для .NET Framework:

COR_ENABLE_PROFILING=1
COR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8}
COR_PROFILER_PATH=<зависит от системы, смотри ниже>
POBP_DOTNET_TRACER_HOME=<APP_DIRECTORY>/protoobp

<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
    
  • Для .NET Framework

    SET COR_ENABLE_PROFILING=1
    

Для установки дополнительных переменные окружения конфигурации трейсера:


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

# Запуск приложения
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

# Запуск приложения
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

В конфигурационном файле службы укажите этот файл как EnvironmentFile в блоке службы:

[Service]
EnvironmentFile=/path/to/environment.env
ExecStart=<command used to start the application>

Перезапустите службу .NET, чтобы настройки переменной окружения применились.

Если приложение работает в Kubernetes

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

Дополнительно необходимо передать поду переменную окружения POBP_AGENT_HOST со значением IP адреса воркер-ноды, а также переменные окружения для связи трейсов с инфраструктурой (имя k8s кластера нужно задать вручную).

apiVersion: apps/v1
kind: Deployment
#(...)
    spec:
      containers:
      - name: "<CONTAINER_NAME>"
        image: "<CONTAINER_IMAGE>/<TAG>"
        env:
          - name: POBP_SERVICE
            value: dispatch			
          - 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:<my_cluster_name>"            
            

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

Если после подключения трейсера данные в интерфейсе 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. На строне агента: проверьте логи агента на предмет ошибок подключения к бэкенду.
  9. На стороне бэкенда: проверьте что в логах контейнера proto-nginx нет ошибок, если есть - перезапустите контейнер.
  10. На стороне бэкенда: проверьте что в логах контейнера proto-trace-processor нет ошибок (например, что закончился срок действия лицензии), если есть ошибки – перезапустите контейнер.
  11. Заново дайте назрузку на приложение и проверьте данные в интерфейсе 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":[]}

Метрики .NET

Для каждого инстанса трейсер ProtoOBP собирает и отображает runtime метрики .NET. Посмотреть их можно выбрав Сервисы > дашборд .NET Сервиса, далее выбрать вкладку Инстансы > инстанс сервиса с вызовами > вкладка .NET.

Сбор метрик .NET отключен по умолчанию. Он может быть включен с помощью переменной окружения:

POBP_RUNTIME_METRICS_ENABLED=true

По умолчанию, метрики из приложений отсылаются Агенту на порт 8125.

Если Агент работает в контейнере:

  • убедитесь, что переменная POBP_DOGSTATSD_NON_LOCAL_TRAFFIC установлена в значение true, и что порт 8125 открыт на агенте;
  • дополнительно для Kubernetes порт DogstatsD должен быть host port.

Список метрик JVM, собираемых 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

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

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

# Запуск скрипта 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

# Запуск скрипта 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
Aerospike Aerospike.Client 4.0.0+ Aerospike
ASP.NET Core Microsoft.AspNetCore
Microsoft.AspNetCore.App
2.0+ и 3.0+
AspNetCore
Azure Functions Microsoft.Azure.Webjobs 3.0+ AzureFunctions
Amazon DynamoDB AWSSDK.DynamoDBv2 3.0+ AwsDynamoDb
Amazon Kinesis AWSSDK.Kinesis 3.0+ AwsKinesis
Amazon SNS AWSSDK.SNS 3.0+ AwsSns
Amazon SQS AWSSDK.SQS 3.0+ AwsSqs
CosmosDb Microsoft.Azure.Cosmos 3.6.0+ CosmosDb
Couchbase CouchbaseNetClient 2.2.8+ Couchbase
Elasticsearch Elasticsearch.Net 5.3.0+ ElasticsearchNet
GraphQL .NET GraphQL 2.3.0+ GraphQL
gRPC Grpc.Net.Client2.30.0+ (только .NET Core 3.0+)
Grpc.Core 2.30.0+
Grpc.AspNetCore 2.30.0+
Grpc
HotChocolate HotChocolate 11.0.0+ HotChocolate
HttpClient / HttpMessageHandler System.Net.Http 4.0+ HttpMessageHandler
Kafka Confluent.Kafka 1.4+ Kafka
IBM MQ amqmdnetstd 9.0.0+ IbmMq
MongoDB MongoDB.Driver.Core 2.1.0+ MongoDb
MySql MySql.Data 6.7.0+
MySqlConnector 0.61.0+
MySql
Oracle Oracle.ManagedDataAccess 4.122.0+ Oracle
PostgreSQL Npgsql 4.0+ Npgsql
Process "System.Diagnostics.Process" 4.0+ Process
RabbitMQ RabbitMQ.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 Remoting Microsoft.ServiceFabric.Services.Remoting 4.0.470+ ServiceRemoting
SQLite System.Data.Sqlite 2.0.0+
Microsoft.Data.Sqlite 1.0.0+
Sqlite
SQL Server System.Data 4.0.0+
System.Data.SqlClient 4.0.0+
Microsoft.Data.SqlClient 1.0.0+
SqlClient
WebClient / WebRequest System.Net.Requests 4.0+ WebRequest

.NET Framework

Фреймворк или библиотека NuGet пакет Название интеграции
.NET Remoting built-in Remoting
ADO.NET Все AdoNet интеграции AdoNet
Aerospike Aerospike.Client 4.0.0+ Aerospike
ASP.NET (including Web Forms) встроено AspNet
ASP.NET MVC Microsoft.AspNet.Mvc 4.0+ AspNetMvc
ASP.NET Web API 2 Microsoft.AspNet.WebApi 5.1+ AspNetWebApi2
Amazon DynamoDB AWSSDK.DynamoDBv2 3.0+ AwsDynamoDb
Amazon Kinesis AWSSDK.Kinesis 3.0+ AwsKinesis
Amazon SNS AWSSDK.SNS 3.0+ AwsSns
Amazon SQS AWSSDK.SQS 3.0+ AwsSqs
CosmosDb Microsoft.Azure.Cosmos 3.6.0+ CosmosDb
Couchbase CouchbaseNetClient 2.2.8+ Couchbase
Elasticsearch Elasticsearch.Net 5.3.0+ ElasticsearchNet
GraphQL .NET GraphQL 2.3.0+ GraphQL
gRPC Grpc.Core 2.3.0+ Grpc
HotChocolate HotChocolate 11.0.0+ HotChocolate
HttpClient / HttpMessageHandler встроено HttpMessageHandler
IBM MQ amqmdnetstd 9.0.0+ IbmMq
Kafka Confluent.Kafka 1.4+ Kafka
MongoDB MongoDB.Driver.Core 2.1.0+ MongoDb
MSMQ встроено Msmq
MySql MySql.Data 6.7.0+
MySqlConnector 0.61.0+
MySql
Oracle Oracle.ManagedDataAccess 4.122.0+ Oracle
PostgreSQL Npgsql 4.0+ Npgsql
Process "System.Diagnostics.Process" 4.0+ Process
RabbitMQ RabbitMQ.Client 3.6.9+, RabbitMQ
Redis (ServiceStack client) ServiceStack.Redis 4.0.48+ ServiceStackRedis
Redis (StackExchange client) StackExchange.Redis 1.0.187+ StackExchangeRedis
SQLite System.Data.Sqlite 2.0.0+
Microsoft.Data.Sqlite 1.0.0+
Sqlite
SQL Server System.Data 4.0.0+
System.Data.SqlClient 4.0.0+
Microsoft.Data.SqlClient 1.0.0+
SqlClient
WCF (server) встроено Wcf
WebClient / WebRequest встроено WebRequest