菜单
开源

在拉取模式下设置 Go 分析

在拉取模式下,收集器 Grafana Alloy 会定期从 Golang 应用中检索 profiles,特别是针对 /debug/pprof/* 端点。

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

  1. 暴露 pprof 端点。
  2. 安装一个收集器,例如 Grafana Alloy。
  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"

安装收集器

您可以使用 Alloy 收集器示例配置文件将数据发送到 Pyroscope。

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

准备收集器配置文件

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

  1. 添加 pyroscope.write 块。

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

    alloy
    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. 启动 Alloy v1.2 及更高版本:将 configuration.alloy 替换为您的配置文件名
    alloy run configuration.alloy

  3. 在浏览器中打开 https://:4040。页面应列出 profiles。

示例

发送数据到 Grafana Cloud

您的 Grafana Cloud URL、用户名和密码可在 grafana.com 上您的 stack 的 Pyroscope“详情页面”找到。在此同一页面上,创建一个 token 并将其用作 Basic 认证密码。

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

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

}

发现 Kubernetes 目标

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

    alloy
    
    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 块的目标。

    alloy
        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)

参考