菜单
开源

在拉取模式下设置 Go 分析

在拉取模式下,收集器(无论是 Grafana Alloy(首选)还是 Grafana Agent(传统))会定期从 Golang 应用程序中检索分析结果,具体目标是 /debug/pprof/* 端点。

要设置 Golang 分析的拉取模式,您需要

  1. 公开 pprof 端点。
  2. 安装收集器,无论是 Grafana Alloy(首选)还是 Grafana Agent(传统)。
  3. 准备收集器的配置文件。
  4. 启动收集器。

公开 pprof 端点

确保您的 Golang 应用程序公开了 pprof 端点。

  1. 获取 godeltaprof

    bash
    go get github.com/grafana/pyroscope-go/godeltaprof@latest
  2. 在应用程序的开头导入 net/http/pprofgodeltaprof/http/pprof 包。

    Go
    import _ "net/http/pprof"
    import _ "github.com/grafana/pyroscope-go/godeltaprof/http/pprof"

安装收集器

此过程可用于 Grafana Alloy 或 Grafana Agent 收集器。您可以使用示例收集器配置文件将数据发送到 Pyroscope。此配置文件适用于 Grafana Alloy 或 Grafana Agent 的流模式。

Grafana Alloy 是首选收集器。

要安装 Alloy,请参考 Grafana Alloy 安装

注意

Grafana Alloy 是我们 OTel 收集器发行版的全新名称。Grafana Agent 已被弃用,将在 2025 年 10 月 31 日之前提供长期支持 (LTS)。Grafana Agent 将于 2025 年 11 月 1 日正式停止服务 (EOL)。了解我们推荐迁移到 Grafana Alloy 的原因。

如果您使用的是旧版 Grafana Agent Flow,请使用 Grafana Agent 在 Flow 模式下 文档进行安装。

准备收集器配置文件

在 Grafana Alloy 或 Grafana Agent Flow 配置文件中,您需要添加至少两个块:pyroscope.writepyroscope.scrape

  1. 添加 pyroscope.write 块。

    river
    pyroscope.write "write_job_name" {
            endpoint {
                    url = "https://127.0.0.1:4040"
            }
    }
  2. 添加 pyroscope.scrape 块。

    river
    pyroscope.scrape "scrape_job_name" {
            targets    = [{"__address__" = "localhost:4040", "service_name" = "example_service"}]
            forward_to = [pyroscope.write.write_job_name.receiver]
    
            profiling_config {
                    profile.process_cpu {
                            enabled = true
                    }
    
                    profile.godeltaprof_memory {
                            enabled = true
                    }
    
                    profile.memory { // disable memory, use godeltaprof_memory instead
                            enabled = false
                    }
    
                    profile.godeltaprof_mutex {
                            enabled = true
                    }
    
                    profile.mutex { // disable mutex, use godeltaprof_mutex instead
                            enabled = false
                    }
    
                    profile.godeltaprof_block {
                            enabled = true
                    }
    
                    profile.block { // disable block, use godeltaprof_block instead
                            enabled = false
                    }
    
                    profile.goroutine {
                            enabled = true
                    }
            }
    }
  3. 保存对文件的更改。

启动收集器

  1. 为测试目的启动本地 Pyroscope 实例

    bash
    docker run -p 4040:4040 grafana/pyroscope
  2. 启动收集器

  • 要启动 Grafana Alloy v1.2:将 configuration.alloy 替换为您的配置文件名
    alloy run configuration.alloy
  • 要启动 Grafana Alloy v1.0/1.1:将 configuration.alloy 替换为您的配置文件名
    alloy run --stability.level=public-preview configuration.alloy stability.level 选项对于 Alloy v1.0 或 v1.1 的 pyroscope.scrape 是必需的。有关 stability.level 的更多信息,请参考 The run command 文档。
  • 要启动 Grafana Agent,请将 configuration.river 替换为您的配置文件名
    grafana-agent-flow run configuration.river
  1. 在浏览器中打开 https://127.0.0.1:4040。页面应列出配置文件。

示例

将数据发送到 Grafana Cloud

您的 Grafana Cloud URL、用户名和密码可以在 grafana.com 上的堆栈中从 Pyroscope 的“详细信息页面”找到。在此页面上,创建一个令牌并将其用作基本身份验证密码。

river
pyroscope.write "write_job_name" {
        endpoint {
                url = "<Grafana Cloud URL>"

                basic_auth {
                        username = "<Grafana Cloud User>"
                        password = "<Grafana Cloud Password>"
                }
        }

}

发现 Kubernetes 目标

  1. 选择所有 Pod
river
discovery.kubernetes "all_pods" {
        role = "pod"
}
  1. 删除未运行的 Pod,创建 namespacepodnodecontainer 标签。根据 namespacecontainer 标签组合 service_name 标签。仅选择与正则表达式模式 (ns1/.*)|(ns2/container-.*0) 匹配的服务。

    river
    
    discovery.relabel "specific_pods" {
            targets = discovery.kubernetes.all_pods.targets
    
            rule {
                    action        = "drop"
                    regex         = "Succeeded|Failed|Completed"
                    source_labels = ["__meta_kubernetes_pod_phase"]
            }
    
            rule {
                    action        = "replace"
                    source_labels = ["__meta_kubernetes_namespace"]
                    target_label  = "namespace"
            }
    
            rule {
                    action        = "replace"
                    source_labels = ["__meta_kubernetes_pod_name"]
                    target_label  = "pod"
            }
    
            rule {
                    action        = "replace"
                    source_labels = ["__meta_kubernetes_node_name"]
                    target_label  = "node"
            }
    
            rule {
                    action        = "replace"
                    source_labels = ["__meta_kubernetes_pod_container_name"]
                    target_label  = "container"
            }
    
            rule {
                    action        = "replace"
                    regex         = "(.*)@(.*)"
                    replacement   = "${1}/${2}"
                    separator     = "@"
                    source_labels = ["__meta_kubernetes_namespace", "__meta_kubernetes_pod_container_name"]
                    target_label  = "service_name"
            }
    
            rule {
                    action        = "keep"
                    regex         = "(ns1/.*)|(ns2/container-.*0)"
                    source_labels = ["service_name"]
            }
    }
  2. 使用 discovery.relabel.specific_pods.output 作为 pyroscope.scrape 块的目标。

    river
        pyroscope.scrape "scrape_job_name" {
                targets    = discovery.relabel.specific_pods.output
                ...
        }

公开 pprof 端点

如果您不使用 http.DefaultServeMux,则可以将 /debug/pprof/* 处理程序注册到您自己的 http.ServeMux

Go
var mux *http.ServeMux
mux.Handle("/debug/pprof/", http.DefaultServeMux)

或者,如果您使用 gorilla/mux

Go
var router *mux.Router
router.PathPrefix("/debug/pprof").Handler(http.DefaultServeMux)

参考

Grafana Alloy

Grafana Agent