服务器 HTTP API
Grafana Pyroscope 暴露了一个 HTTP API,用于查询性能剖析数据以及从其他源摄入性能剖析数据。
认证
Pyroscope 不包含认证层。操作者应使用认证反向代理以确保安全。
在多租户模式下,Pyroscope 要求将 X-Scope-OrgID HTTP 请求头设置为标识租户的字符串。认证反向代理负责处理此任务。有关更多信息,请参阅多租户文档。
摄入
有一个主要端点:POST /ingest
。它接受请求体中的性能剖析数据以及查询参数中的元数据。
接受以下查询参数
名称 | 描述 | 备注 |
---|---|---|
name | 应用名称 | 必需 |
from | 性能剖析开始时的 UNIX 时间 | 必需 |
until | 性能剖析停止时的 UNIX 时间 | 必需 |
format | 性能剖析数据的格式 | 可选(默认为 folded ) |
sampleRate | 使用的采样率(单位:赫兹) | 可选(默认为 100 赫兹) |
spyName | 使用的 spy 名称 | 可选 |
units | 性能剖析数据单位名称 | 可选(默认为 samples ) |
aggregrationType | 用于合并性能剖析的聚合类型 | 可选(默认为 sum ) |
name
指定应用名称。例如
my.awesome.app.cpu{env=staging,region=us-west-1}
请求体包含性能剖析数据,并可与格式一起使用 Content-Type 请求头来确定数据格式。
某些查询参数取决于性能剖析数据的格式。Pyroscope 当前支持三种主要的摄入格式。
文本格式
这些格式处理简单的性能剖析数据摄入,例如 cpu
samples,并且通常不支持格式内的元数据(例如标签)。所有必需的元数据都从查询参数中获取,并且格式由 format
查询参数指定。
支持的格式
- Folded:也称为
collapsed
,这是默认格式。每一行包含一个堆栈追踪,后跟该堆栈追踪的采样计数。例如
foo;bar 100
foo;baz 200
- Lines:类似于
folded
,但它将每个采样表示为单独一行,而不是按堆栈追踪聚合采样。例如
foo;bar
foo;bar
foo;baz
foo;bar
pprof 格式
pprof 格式是一种广泛使用的二进制性能剖析数据格式,在 Go 生态系统中尤为常见。
使用此格式时,某些查询参数具有特定行为
- format:应设置为
pprof
。 - name:此参数包含应用名称的*前缀*。由于单个请求可能包含多个性能剖析类型,完整的应用名称由此前缀与性能剖析类型连接而成。例如,如果您发送 CPU 性能剖析数据并将
name
设置为my-app{}
,它在 Pyroscope 中将显示为my-app.cpu{}
。 - units、aggregationType 和 sampleRate:这些参数将被忽略。实际值根据数据中存在的性能剖析类型确定(有关更多详细信息,请参阅“采样类型配置”部分)。
采样类型配置
Pyroscope 服务器本身支持标准的 Go 性能剖析类型,例如 cpu
、inuse_objects
、inuse_space
、alloc_objects
和 alloc_space
。处理生成 pprof 格式数据的软件时,您可能需要提供自定义采样类型配置,以便 Pyroscope 正确解释数据。
有关摄入带有自定义采样类型配置的 pprof 文件的 Python 示例脚本,请参阅 此 Python 脚本。
要摄入带有自定义采样类型配置的 pprof 数据,请按如下方式修改您的请求
- 将 Content-Type 设置为
multipart/form-data
。 - 将性能剖析数据作为名为
profile
的表单文件字段上传。 - 将采样类型配置包含在名为
sample_type_config
的表单文件字段中。
采样类型配置是格式化如下的 JSON 对象
{
"inuse_space": {
"units": "bytes",
"aggregation": "average",
"display-name": "inuse_space_bytes",
"sampled": false
},
"alloc_objects": {
"units": "objects",
"aggregation": "sum",
"display-name": "alloc_objects_count",
"sampled": true
},
"cpu": {
"units": "samples",
"aggregation": "sum",
"display-name": "cpu_samples",
"sampled": true
},
// pprof supports multiple profiles types in one file,
// so there can be multiple of these objects
}
采样类型配置字段说明
- units
- 支持的值:
samples
、objects
、bytes
- 描述:更改前端显示的单位。
samples
= CPU 采样,objects
= RAM 中的对象,bytes
= RAM 中的字节。
- 支持的值:
- display-name
- 支持的值:任意字符串。
- 描述:这成为应用名称的后缀,例如
my-app.inuse_space_bytes
。
- aggregation
- 支持的值:
sum
、average
。 - 描述:改变数据在前端的聚合方式。对于随时间累加的数据(例如 CPU 采样、内存分配)使用
sum
,对于随时间平均的数据(例如内存占用对象)使用average
。
- 支持的值:
- sampled
- 支持的值:
true
、false
。 - 描述:确定是否考虑采样率(在 pprof 文件中指定)。对于采样事件(例如 CPU 采样)设置为
true
,对于内存性能剖析设置为false
。
- 支持的值:
此配置允许在 Pyroscope 中对各种性能剖析类型进行自定义可视化和分析。
JFR 格式
这是 Java Flight Recorder 格式,通常由基于 JVM 的性能剖析工具使用,我们的 Java 集成也支持此格式。
使用此格式时,某些查询参数的行为略有不同
format
应设置为jfr
。name
包含应用名称的前缀。由于单个请求可能包含多个性能剖析类型,最终的应用名称由此前缀与性能剖析类型连接而成。例如,如果您发送 cpu 性能剖析数据并将name
设置为my-app{}
,它在 pyroscope 中将显示为my-app.cpu{}
。units
被忽略,实际单位取决于数据中可用的性能剖析类型。aggregationType
被忽略,实际聚合类型取决于数据中可用的性能剖析类型。
JFR 摄入支持使用性能剖析元数据来确定包含哪些性能剖析类型,这取决于正在进行的性能剖析的种类。目前支持的性能剖析类型包括
cpu
采样,仅包含来自可运行线程的性能剖析数据。itimer
采样,类似于cpu
性能剖析。wall
采样,包含来自任意线程的采样,与其状态无关。alloc_in_new_tlab_objects
,表示创建的新 TLAB 对象数量。alloc_in_new_tlab_bytes
,表示创建的新 TLAB 对象的字节大小。alloc_outside_tlab_objects
,表示在任何 TLAB 之外分配的新对象数量。alloc_outside_tlab_bytes
,表示在任何 TLAB 之外分配的新对象的字节大小。
带标签的 JFR
为了摄入带有动态标签的 JFR 数据,您需要对您的请求进行以下更改
- 使用 HTTP 表单(
multipart/form-data
)Content-Type。 - 将 JFR 数据作为名为
jfr
的表单文件字段发送。 - 将
LabelsSnapshot
protobuf 消息作为名为labels
的表单文件字段发送。
message Context {
// string_id -> string_id
map<int64, int64> labels = 1;
}
message LabelsSnapshot {
// context_id -> Context
map<int64, Context> contexts = 1;
// string_id -> string
map<int64, string> strings = 2;
}
其中 context_id
是在 async-profiler 中设置的参数
示例
这是一个向 pyroscope 上传非常简单性能剖析数据的示例代码
printf "foo;bar 100\n foo;baz 200" | curl \
-X POST \
--data-binary @- \
'https://:4040/ingest?name=curl-test-app&from=1615709120&until=1615709130'
import requests
import urllib.parse
from datetime import datetime
now = round(datetime.now().timestamp()) / 10 * 10
params = {'from': f'{now - 10}', 'name': 'python.example{foo=bar}'}
url = f'https://:4040/ingest?{urllib.parse.urlencode(params)}'
data = "foo;bar 100\n" \
"foo;baz 200"
requests.post(url, data = data)
这是一个向 pyroscope 上传带标签 JFR 性能剖析数据的示例代码
curl -X POST \
-F jfr=@profile.jfr \
-F labels=@labels.pb \
"https://:4040/ingest?name=curl-test-app&units=samples&aggregationType=sum&sampleRate=100&from=1655834200&until=1655834210&spyName=javaspy&format=jfr"
查询性能剖析数据
有一个用于查询性能剖析数据的主要端点:GET /pyroscope/render
。
搜索输入通过查询参数提供。输出通常是一个 JSON 对象,包含一个或多个时间序列和一个火焰图。
查询参数
以下是接受的查询参数概览
名称 | 描述 | 备注 |
---|---|---|
query | 包含性能剖析类型和标签选择器 | 必需 |
from | 搜索窗口开始的 UNIX 时间 | 必需 |
until | 搜索窗口结束的 UNIX 时间 | 可选(默认为 now ) |
format | 性能剖析数据的格式 | 可选(默认为 json ) |
maxNodes | 结果火焰图将包含的最大节点数 | 可选(默认为 max_flamegraph_nodes_default ) |
groupBy | 一个或多个标签名称,用于对时间序列进行分组(不适用于火焰图) | 可选(默认为不分组) |
query
query
参数是唯一必需的搜索输入。它携带性能剖析类型以及我们想要用来缩小输出范围的任何标签。此参数的格式类似于 PromQL 查询,可以定义为
<profile_type>{<label_name>="<label_value>", <label_name>="<label_value>", ...}
这是一个具体示例
process_cpu:cpu:nanoseconds:cpu:nanoseconds{service_name="my_application_name"}
在 Kubernetes 环境中,查询也可能看起来像
process_cpu:cpu:nanoseconds:cpu:nanoseconds{namespace="dev", container="my_application_name"}
注意
请参阅
性能剖析类型文档以获取更多信息,以及 profile-metrics.json 获取有效性能剖析类型列表。
from 和 until
from
和 until
参数确定查询的时间段的开始和结束。它们可以以绝对形式和相对形式提供。
绝对时间
此表详细说明了传递绝对值的选项。
选项 | 示例 | 备注 |
---|---|---|
日期 | 20231223 | 格式:YYYYMMDD |
Unix 时间(秒) | 1577836800 | |
Unix 时间(毫秒) | 1577836800000 | |
Unix 时间(微秒) | 1577836800000000 | |
Unix 时间(纳秒) | 1577836800000000000 |
相对时间
相对值始终表示为与 now
的偏移量。
选项 | 示例 |
---|---|
3 小时前 | now-3h |
30 分钟前 | now-30m |
2 天前 | now-2d |
1 周前 | now-7d 或 now-1w |
请注意,必须提供单个偏移量,诸如 now-3h30m
的值将不起作用。
验证
from
和 until
参数受制于与 max_query_lookback
和 max_query_length
服务器参数相关的验证规则。您可以在服务器配置文档的limits 部分找到有关这些参数的更多详细信息。
- 如果配置了
max_query_lookback
并且from
在now - max_query_lookback
之前,则from
将被设置为now - max_query_lookback
。 - 如果配置了
max_query_lookback
并且until
在now - max_query_lookback
之前,则查询将不会执行。 - 如果配置了
max_query_length
并且查询间隔长于此配置,则查询将不会执行。
format
格式可以是
json
,在这种情况下响应将包含一个 JSON 对象dot
,在这种情况下响应将是包含性能剖析 DOT 表示的文本
有关响应结构的更多信息,请参阅查询输出部分。
maxNodes
maxNodes
参数截断性能剖析响应中的元素数量,以便工具(例如前端)高效地渲染大型性能剖析数据。这通常用于已知具有大型堆栈追踪的性能剖析。
未提供值时,默认值取自 max_flamegraph_nodes_default
配置参数。提供值时,其上限为 max_flamegraph_nodes_max
配置参数。
groupBy
groupBy
参数影响响应的时间序列部分的输出。提供有效标签时,响应将包含与给定标签的标签值数量一样多的序列。
注意
Pyroscope 支持单个标签用于 group by 功能。
查询输出
/pyroscope/render
端点的输出是基于以下 schema 的 JSON 对象
type FlamebearerProfileV1 struct {
Flamebearer FlamebearerV1 `json:"flamebearer"`
Metadata FlamebearerMetadataV1 `json:"metadata"`
Timeline *FlamebearerTimelineV1 `json:"timeline"`
Groups map[string]*FlamebearerTimelineV1 `json:"groups"`
}
flamebearer
flamebearer
字段包含适合渲染火焰图的数据。flamebearer
中的数据组织在单独的数组中,包含性能剖析符号和采样值。
metadata
metadata
字段包含有助于解释 flamebearer
数据的附加信息,例如单位(纳秒、字节)、采样率等。
timeline
timeline
字段表示性能剖析的时间序列。Pyroscope 使用查询间隔(from
和 until
)预先计算时间线的步长间隔(分辨率)。最小步长间隔为 10 秒。
原始性能剖析采样数据使用聚合函数下采样到步长间隔(分辨率)。目前仅支持 sum
。
时间线包含开始时间、采样值列表和步长间隔
{
"timeline": {
"startTime": 1577836800,
"samples": [
100,
200,
400
],
"durationDelta": 10
}
}
groups
groups
字段仅在通过 groupBy
查询参数请求分组时填充。在这种情况下,groups
字段会为查询找到的每个标签值包含一个条目。
此示例按集群分组
{
"groups": {
"eu-west-2": { "startTime": 1577836800, "samples": [ 200, 300, 500 ] },
"us-east-1": { "startTime": 1577836800, "samples": [ 100, 200, 400 ] }
}
}
替代查询输出
当 format
查询参数为 dot
时,端点响应包含表示所查询性能剖析的 DOT 格式数据。这可用于创建性能剖析的替代可视化。
查询示例
此示例查询本地 Pyroscope 服务器,获取 pyroscope
服务过去一小时的 CPU 性能剖析数据。
curl \
'https://:4040/pyroscope/render?query=process_cpu%3Acpu%3Ananoseconds%3Acpu%3Ananoseconds%7Bservice_name%3D%22pyroscope%22%7D&from=now-1h'
这是同一查询,使其更具可读性
curl --get \
--data-urlencode "query=process_cpu:cpu:nanoseconds:cpu:nanoseconds{service_name=\"pyroscope\"}" \
--data-urlencode "from=now-1h" \
https://:4040/pyroscope/render
这是用 Python 编写的同一示例
import requests
application_name = 'my_application_name'
query = f'process_cpu:cpu:nanoseconds:cpu:nanoseconds{{service_name="{application_name}"}}'
query_from = 'now-1h'
url = f'https://:4040/pyroscope/render?query={query}&from={query_from}'
requests.get(url)
有关完整示例,请参阅此 Python 脚本。
性能剖析 CLI
profilecli
工具也可用于与 Pyroscope 服务器 API 交互。该工具支持摄入性能剖析、查询现有性能剖析等操作。有关更多信息,请参阅性能剖析 CLI 页面。