菜单
开源

.NET

我们的 .NET Profiler 是一款强大的工具,旨在增强 .NET 应用程序的性能分析和优化。它与 Pyroscope 无缝集成,提供对您的 .NET 代码库中的资源使用和瓶颈的实时洞察。此集成使开发者能够精确定位低效之处,提高应用程序速度,并确保资源高效运行。

注意

请参阅可用的性能剖析类型,了解每种语言支持的性能剖析类型列表。

支持的性能剖析类型

.NET Profiler 支持以下性能剖析类型

  • CPU
  • 挂钟时间
  • 分配
  • 锁竞争
  • 异常
  • Live Heap (需要 .NET 7+)

兼容性

我们的 .NET profiler 支持以下 .NET 版本

  • .NET 6
  • .NET 7
  • .NET 8

开始之前

要捕获和分析性能剖析数据,您需要一个托管的 Pyroscope OSS 服务器,或一个包含 Grafana Cloud Profiles 的托管 Pyroscope 实例(需要免费的 Grafana Cloud 帐户)。

Pyroscope 服务器可以是用于开发的本地服务器,也可以是用于生产的远程服务器。

配置 Dotnet 客户端

  1. 最新的 tarball 获取 Pyroscope.Profiler.Native.soPyroscope.Linux.ApiWrapper.x64.so
bash
curl -s -L https://github.com/grafana/pyroscope-dotnet/releases/download/v0.9.4-pyroscope/pyroscope.0.9.4-glibc-x86_64.tar.gz  | tar xvz -C .

或者从最新的 docker 镜像中复制它们。我们提供了 glibcmusl 版本

dockerfile
COPY --from=pyroscope/pyroscope-dotnet:0.9.4-glibc /Pyroscope.Profiler.Native.so ./Pyroscope.Profiler.Native.so
COPY --from=pyroscope/pyroscope-dotnet:0.9.4-glibc /Pyroscope.Linux.ApiWrapper.x64.so ./Pyroscope.Linux.ApiWrapper.x64.so
  1. 设置以下必需的环境变量以启用 profiler
shell
PYROSCOPE_APPLICATION_NAME=rideshare.dotnet.app
PYROSCOPE_SERVER_ADDRESS=https://:4040
PYROSCOPE_PROFILING_ENABLED=1
CORECLR_ENABLE_PROFILING=1
CORECLR_PROFILER={BD1A650D-AC5D-4896-B64F-D6FA25D6B26A}
CORECLR_PROFILER_PATH=Pyroscope.Profiler.Native.so
LD_PRELOAD=Pyroscope.Linux.ApiWrapper.x64.so

注意

从 .NET 8 版本开始,环境变量 DOTNET_EnableDiagnostics=0(或其旧版等效项 COMPlus_EnableDiagnostics=0)也将禁用 profiler。为了获得之前的行为(允许性能剖析,但关闭 IPC 和调试),应设置以下环境变量替代。

shell
DOTNET_EnableDiagnostics=1
DOTNET_EnableDiagnostics_IPC=0
DOTNET_EnableDiagnostics_Debugger=0
DOTNET_EnableDiagnostics_Profiler=1

.NET Profiler API

使用托管的辅助程序,您可以从 .NET 运行时与 Pyroscope profiler 进行交互。您可以添加标签、开启/关闭性能剖析类型等。

要使用它,首先添加 Pyroscope 依赖项

shell
dotnet add package Pyroscope

 

为您的应用程序添加性能剖析标签

您可以为性能剖析数据添加标签,以便在 UI 中过滤数据。常见的标签包括

  • hostname
  • region
  • team
  • api_endpoint

创建一个 LabelSet 并使用 Pyroscope.LabelsWrapper 包裹一段代码。

cs
var labels = Pyroscope.LabelSet.Empty.BuildUpon()
    .Add("key1", "value1")
    .Build();
Pyroscope.LabelsWrapper.Do(labels, () =>
{
  SlowCode();
});

标签可以嵌套。对于嵌套 LabelSets,请在非空集合上使用 LabelSet.BuildUpon

cs
var labels = Pyroscope.LabelSet.Empty.BuildUpon()
    .Add("key1", "value1")
    .Build();
Pyroscope.LabelsWrapper.Do(labels, () =>
{
  var labels2 = labels.BuildUpon()
    .Add("key2", "value2")
    .Build();
  Pyroscope.LabelsWrapper.Do(labels2, () =>
  {
    SlowCode();
  });
  FastCode();
});

动态控制

可以动态启用/禁用特定的性能剖析类型。性能剖析类型必须事先配置好。

cs
// Enables or disables CPU/wall profiling dynamically.
// This function works in conjunction with the PYROSCOPE_PROFILING_CPU_ENABLED and
// PYROSCOPE_PROFILING_WALLTIME_ENABLED environment variables. If CPU/wall profiling is not
// configured, this function will have no effect.
Pyroscope.Profiler.Instance.SetCPUTrackingEnabled(enabled);
// Enables or disables allocation profiling dynamically.
// This function works in conjunction with the PYROSCOPE_PROFILING_ALLOCATION_ENABLED environment variable.
// If allocation profiling is not configured, this function will have no effect.
Pyroscope.Profiler.Instance.SetAllocationTrackingEnabled(enabled);
// Enables or disables contention profiling dynamically.
// This function works in conjunction with the PYROSCOPE_PROFILING_LOCK_ENABLED environment variable.
// If contention profiling is not configured, this function will have no effect.
Pyroscope.Profiler.Instance.SetContentionTrackingEnabled(enabled);
// Enables or disables exception profiling dynamically.
// This function works in conjunction with the PYROSCOPE_PROFILING_EXCEPTION_ENABLED environment variable.
// If exception profiling is not configured, this function will have no effect.
Pyroscope.Profiler.Instance.SetExceptionTrackingEnabled(enabled);

可以动态更改授权凭据

cs
// Set Basic authorization username and password. Clears any previous authorization credentials.
Pyroscope.Profiler.Instance.SetBasicAuth(basicAuthUser, BasicAuthPassword);

这里有一个简单的示例 将这些 API 公开为 HTTP 端点。

配置选项

环境变量类型描述
PYROSCOPE_PROFILING_LOG_DIR字符串设置 .NET Profiler 日志目录。默认为 /var/log/pyroscope/。
PYROSCOPE_LABELS字符串要应用于上传的性能剖析数据的静态标签。必须是逗号分隔的 key:value 列表,例如:layer:api 或 team:intake。
PYROSCOPE_SERVER_ADDRESS字符串Pyroscope 服务器地址
PYROSCOPE_PROFILING_ENABLED布尔值如果设置为 true,启用 .NET Profiler。默认为 false。
PYROSCOPE_PROFILING_WALLTIME_ENABLED布尔值如果设置为 false,禁用挂钟时间性能剖析。默认为 false。
PYROSCOPE_PROFILING_CPU_ENABLED布尔值如果设置为 false,禁用 CPU 性能剖析。默认为 true。
PYROSCOPE_PROFILING_EXCEPTION_ENABLED布尔值如果设置为 true,启用异常性能剖析。默认为 false。
PYROSCOPE_PROFILING_ALLOCATION_ENABLED布尔值如果设置为 true,启用分配性能剖析。默认为 false。
PYROSCOPE_PROFILING_LOCK_ENABLED布尔值如果设置为 true,启用锁竞争性能剖析。默认为 false。
PYROSCOPE_PROFILING_HEAP_ENABLED布尔值如果设置为 true,启用 Live Heap 性能剖析。需要 .NET 7+。默认为 false。
PYROSCOPE_BASIC_AUTH_USER字符串对于 HTTP Basic 身份验证,使用此选项将性能剖析数据发送到已验证的服务器,例如 Grafana Cloud
PYROSCOPE_BASIC_AUTH_PASSWORD字符串对于 HTTP Basic 身份验证,使用此选项将性能剖析数据发送到已验证的服务器,例如 Grafana Cloud
PYROSCOPE_TENANT_ID字符串仅当 Pyroscope 中启用多租户时需要。

将数据发送到 Pyroscope OSS 或 Grafana Cloud Profiles

要从 .NET 应用程序发送性能剖析数据,请按照以下步骤为 Pyroscope OSS 或 Grafana Cloud Profiles 配置环境

bash
export CORECLR_ENABLE_PROFILING=1
export CORECLR_PROFILER={BD1A650D-AC5D-4896-B64F-D6FA25D6B26A}
export CORECLR_PROFILER_PATH=/dotnet/Pyroscope.Profiler.Native.so
export LD_PRELOAD=/dotnet/Pyroscope.Linux.ApiWrapper.x64.so
export PYROSCOPE_PROFILING_ENABLED=1
export PYROSCOPE_APPLICATION_NAME=example.dotnet.app
export PYROSCOPE_SERVER_ADDRESS=<URL>
# Use these environment variables to send data to Grafana Cloud Profiles
export PYROSCOPE_BASIC_AUTH_USER=<User>
export PYROSCOPE_BASIC_AUTH_PASSWORD=<Password>
# Optional Pyroscope tenant ID (only needed if using multi-tenancy). Not needed for Grafana Cloud.
# export PYROSCOPE_TENANT_ID=<TenantID>

要配置 .NET SDK 将数据发送到 Grafana Cloud Profiles 或 Pyroscope,请将 <URL> 占位符替换为相应的服务器 URL。这可以是 Grafana Cloud URL 或您自己的自定义 Pyroscope 服务器 URL。

如果您需要将数据发送到 Grafana Cloud,您需要配置 HTTP Basic 身份验证。将 <User> 替换为您的 Grafana Cloud stack 用户,将 <Password> 替换为您的 Grafana Cloud API 密钥。

如果您的开源 Pyroscope 服务器启用了多租户,您需要指定一个租户 ID。将 <TenantID> 替换为您的 Pyroscope 租户 ID。