查看数据

创建时间:2024-08-08 最近修改时间:2024-08-23

#1. 获取指定进程的 Profile

#1.1 Grafana Panel

app_service 中选择一个进程名之后,Grafana 中的展示效果图如下:

On-CPU - Process

On-CPU - Process

#1.2 API

Profile 查询 API 示例:

# 确认 deepflow-server 的监听 IP 和端口
deepflow_server_node_ip=FIXME # 注意修改
port=$(kubectl get --namespace deepflow -o jsonpath="{.spec.ports[0].nodePort}" services deepflow-server)

# 请求 deepflow-server 的 API
curl -X POST http://${deepflow_server_node_ip}:$port/v1/profile/ProfileTracing \
  -H 'Content-Type: application/json' \
  -d '{
    "app_service": "deepflow-agent",
    "profile_language_type": "eBPF",
    "profile_event_type": "on-cpu",
    "tag_filter": "",
    "time_start": 1708479421,
    "time_end": 1708480321
  }'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

API 请求参数说明:

  • app_service:进程名
  • profile_language_type:获取 eBPF Profile 数据时使用 eBPF
  • profile_event_type:对于 eBPF On-CPU Profile 数据赋值为 on-cpu 即可
  • tag_filter:当进程名冲突时,可使用其他 Tag 过滤
    • 例如 "tag_filter": "pod_cluster='prod-cluster' AND pod_ns='app'"
  • time_starttime_end:时间范围

profile.in_process 表支持使用的 tag_filter 字段如下:

Name DisplayName Description
_id UID
time 时间
region 区域
az 可用区
host 宿主机 承载虚拟机的宿主机。
chost 云服务器 包括虚拟机、裸金属服务器。
vpc VPC
router 路由器
dhcpgw DHCP 网关
lb 负载均衡器
lb_listener 负载均衡监听器
natgw NAT 网关
redis Redis
rds RDS
pod_cluster K8s 容器集群
pod_ns K8s 命名空间
pod_node K8s 容器节点
pod_ingress K8s Ingress
pod_service K8s 容器服务
pod_group_type K8s 工作负载类型
pod_group K8s 工作负载 例如 Deployment、StatefulSet、Daemonset 等。
pod K8s 容器 POD
service 服务 已废弃,请使用 pod_service
auto_instance_type 自动实例类型 auto_instance实例对应的类型。
auto_instance 自动实例 IP 对应的实例,实例为IP时,auto_instance_id显示为子网ID。
auto_service_type 自动服务类型 auto_service实例对应的类型。
auto_service 自动服务 auto_instance基础上,将容器服务的 ClusterIP 与工作负载聚合为服务,实例为IP时,auto_service_id显示为子网ID。
gprocess 进程
host_ip 宿主机 宿主机的管理 IP。
host_hostname 宿主机 宿主机的 Hostname。
chost_ip 云服务器 云服务器的主 IP。
chost_hostname 云服务器 云服务器的 Hostname。
pod_node_ip K8s 容器节点 容器节点的主 IP。
pod_node_hostname K8s 容器节点 容器节点的 Hostname。
k8s.label K8s Label
k8s.annotation K8s Annotation
k8s.env K8s Env
cloud.tag Cloud Tag
ip IP 地址
is_ipv4 IPv4 标志
app_service 应用服务
app_instance 应用实例
process_id 进程 ID
trace_id TraceID
span_name Span名称
vtap 采集器 已废弃,请使用 agent。
agent 采集器
profile_value_unit 单位
profile_event_type 剖析类型
profile_create_timestamp 聚合时间
profile_in_timestamp 写入时间
profile_language_type 语言类型
profile_id ProfileID

generate from csv file: in_process.ch

API 返回结果示例:

{
  "OPT_STATUS": "SUCCESS",
  "DESCRIPTION": "",
  "result": {
    "functions": [
      "deepflow-agent",
      "[t] platform-synchr",
      "[k] entry_SYSCALL_64_after_hwframe",
      // ...
      "[l] __write"
    ],
    "function_types": [
      "P",
      "T",
      "K",
      // ...
      "K"
    ],
    "function_values": {
      "columns": ["self_value", "total_value"],
      "values": [
        [0, 640352895],
        [0, 6292923],
        [0, 46848438],
        // ...
        [0, 1797978]
      ]
    },
    "node_values": {
      "columns": ["function_id", "parent_node_id", "self_value", "total_value"],
      "values": [
        [0, -1, 0, 640352895],
        [1, 0, 0, 6292923],
        [2, 1, 0, 1444443],
        // ...
        [3, 2, 0, 10101]
      ]
    }
  },
  "debug": null
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

API 返回结果说明:

  • functions:函数名
  • function_types: 函数类型
    • [t] thread_name:线程,只会出现在火焰图的第二层
    • [k] function_name:Linux 内核函数、CUDA 动态链接库函数(libcuda (opens new window)libcublas (opens new window) 等)
    • [l] function_name:动态链接库中的函数
    • function_name:表示应用程序的业务函数
    • $app_service:火焰图最顶层的节点,名字为进程名
    • 除此之外,当函数名未成功翻译时,可能显示为如下几种形式之一
      • [/tmp/perf-29887.map]:方括号中为进程号 29887 的 Java 进程符号文件名,函数地址未能在该文件中找到。Java 进程符号文件会自动周期性生成,此时一般由于该符号文件生成时该函数尚未加载导致。
      • [/lib/ld-musl-x86_64.so.1]:方括号中为动态链接库的文件路径(带有 so),函数地址属于该文件但未能成功翻译,一般是符号表被裁剪导致。
      • [/usr/local/bin/kube-apiserver]:方括号中为可执行文件的路径,函数地址属于该文件但未能成功翻译,一般是符号表被裁剪导致。
      • [unknown] 0x0000000003932388:除上述所有情况以外,当某个地址无法成功翻译为函数名时显示如此。特别地,当火焰图第三层函数地址(一般是线程的入口函数)未能翻译为函数名时,显示为 [unknown start_thread?]
  • function_values: 函数的 CPU 时长,单位是微秒(us)。
  • node_values: 函数作为节点的 CPU 时长,单位是微秒(us)。
  • function_id:函数唯一标识
  • parent_node_id:该函数的父节点在火焰图中的唯一标识
  • total_value:该函数的 CPU 时长,单位是微秒(us)。
    • On-CPU Profile:此值表示函数花费 CPU 的时长
    • Off-CPU Profile:此值表示函数等待 CPU 的时长
  • self_value:该函数作为叶子节点(最底层函数)的 CPU 时长,单位是微秒(us)。
    • On-CPU 和 Off-CPU 的差异同上

使用 API 的返回结果,可以绘制指定进程的 CPU 火焰图。

#2. 获取指定主机的 Profile

#2.1 Grafana Panel

app_service 中选择 Total 之后,Grafana 中的展示效果图如下(火焰图只有三层):

On-CPU - Host

On-CPU - Host

#2.2 API

提示

当前仅 On-CPU Profile 支持查询主机的整体数据。

当请求参数携带 "app_service": "Total" 时,能够获取到名为 Total 的特殊 On-CPU Profile 数据,它是一台主机上所有进程的、精细到线程粒度的 Profile。可用于当 On-CPU regex 未配置某个进程时,能够快速定位瓶颈进程和线程。此时的返回结果示例:

{
  "OPT_STATUS": "SUCCESS",
  "DESCRIPTION": "",
  "result": {
    "functions": [
      "Total",
      "[p] java",
      // ...
      "[t] DefaultTimer10-"
    ],
    "function_types": [
      "H",
      "P",
      // ...
      "T"
    ],
    "function_values": {
      "columns": ["self_value", "total_value"],
      "values": [
        [0, 4563875153],
        [4616160, 325630360],
        // ...
        [6565660, 6565660]
      ]
    },
    "node_values": {
      "columns": ["function_id", "parent_node_id", "self_value", "total_value"],
      "values": [
        [0, -1, 0, 4563875153],
        [1, 0, 4616160, 325630360],
        // ...
        [2, 1, 6565660, 6565660]
      ]
    }
  },
  "debug": null
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

上述返回结果中 functions 的补充说明如下:

  • $app_service:火焰图最顶层的节点,名字固定为 Total
  • [p] name:一个进程的名称
  • [t] name:一个线程的名称,它的父节点是一个 [p] name 类型的节点,表示这个线程所属的进程

使用 API 的返回结果,可以绘制指定主机的 On-CPU 火焰图。

#3. 关于 Function Type

Function Type 含义 Profile Event Type 特征
O 对象类型 mem-* Memory Profile 的叶子节点
H 云主机 * 等于 Total 的根节点
P 进程 * [p] 开头,以及不等于 Total 的根节点
T 线程 * [t] 开头
K 内核函数 * [k] 开头
C CUDA 驱动函数 * [c] 开头
L 动态链接库函数 * [l] 开头
? 未知函数 * 其他 [ 开头
A 应用函数 * 除以上之外的函数