github.com/grafana/pyroscope@v1.18.0/docs/sources/configure-client/grafana-alloy/go_pull.md (about) 1 --- 2 title: Set up Go profiling in pull mode 3 menuTitle: Set up Go profiling in pull mode 4 description: Learn how to set up Go profiling in pull mode. 5 weight: 10 6 --- 7 8 # Set up Go profiling in pull mode 9 10 In pull mode, the collector, Grafana Alloy, periodically retrieves profiles from Golang applications, specifically targeting the 11 `/debug/pprof/*` endpoints. 12 13 To set up Golang profiling in pull mode, you need to: 14 15 1. Expose pprof endpoints. 16 2. Install a collector, such as Grafana Alloy. 17 3. Prepare the collector's configuration file. 18 4. Start the collector. 19 20 ## Expose pprof endpoints 21 22 Ensure your Golang application exposes pprof endpoints. 23 24 1. Get `godeltaprof` package 25 26 ```bash 27 go get github.com/grafana/pyroscope-go/godeltaprof@latest 28 ``` 29 30 2. Import `net/http/pprof` and `godeltaprof/http/pprof` packages at the start of your application. 31 32 ```go 33 import _ "net/http/pprof" 34 import _ "github.com/grafana/pyroscope-go/godeltaprof/http/pprof" 35 ``` 36 37 ## Install the collector 38 39 [//]: # (TODO(korniltsev) What should go here?) 40 41 You can use the sample Alloy collector configuration file to send data to Pyroscope. 42 43 To install Alloy, refer to [Grafana Alloy installation](https://grafana.com/docs/alloy/<ALLOY_VERSION>/get-started/install/). 44 45 ### Prepare the collector configuration file 46 47 In the Alloy configuration file, you need to add at least two blocks: `pyroscope.write` and `pyroscope.scrape`. 48 49 1. Add `pyroscope.write` block. 50 51 ```alloy 52 pyroscope.write "write_job_name" { 53 endpoint { 54 url = "http://localhost:4040" 55 } 56 } 57 ``` 58 59 1. Add `pyroscope.scrape` block. 60 61 ```alloy 62 pyroscope.scrape "scrape_job_name" { 63 targets = [{"__address__" = "localhost:4040", "service_name" = "example_service"}] 64 forward_to = [pyroscope.write.write_job_name.receiver] 65 66 profiling_config { 67 profile.process_cpu { 68 enabled = true 69 } 70 71 profile.godeltaprof_memory { 72 enabled = true 73 } 74 75 profile.memory { // disable memory, use godeltaprof_memory instead 76 enabled = false 77 } 78 79 profile.godeltaprof_mutex { 80 enabled = true 81 } 82 83 profile.mutex { // disable mutex, use godeltaprof_mutex instead 84 enabled = false 85 } 86 87 profile.godeltaprof_block { 88 enabled = true 89 } 90 91 profile.block { // disable block, use godeltaprof_block instead 92 enabled = false 93 } 94 95 profile.goroutine { 96 enabled = true 97 } 98 } 99 } 100 101 ``` 102 103 1. Save the changes to the file. 104 105 ### Start the collector 106 107 1. Start a local Pyroscope instance for testing purposes: 108 ```bash 109 docker run -p 4040:4040 grafana/pyroscope 110 ``` 111 112 1. To start Alloy v1.2 and later: Replace `configuration.alloy` with your configuration filename: <br> `alloy run configuration.alloy` 113 114 1. Open a browser to `http://localhost:4040`. The page should list profiles. 115 116 ## Examples 117 118 ### Send data to Grafana Cloud 119 120 Your Grafana Cloud URL, username, and password can be found on the "Details Page" for Pyroscope from your stack on 121 grafana.com. 122 On this same page, create a token and use it as the Basic authentication password. 123 124 ```alloy 125 pyroscope.write "write_job_name" { 126 endpoint { 127 url = "<Grafana Cloud URL>" 128 129 basic_auth { 130 username = "<Grafana Cloud User>" 131 password = "<Grafana Cloud Password>" 132 } 133 } 134 135 } 136 ``` 137 138 ### Discover Kubernetes targets 139 140 1. Select all pods 141 142 ```alloy 143 discovery.kubernetes "all_pods" { 144 role = "pod" 145 } 146 ``` 147 148 1. Drop not running pods, create `namespace`, `pod`, `node` and `container` labels. 149 Compose `service_name` label based on `namespace` and `container` labels. 150 Select only services matching regex pattern `(ns1/.*)|(ns2/container-.*0)`. 151 ```alloy 152 153 discovery.relabel "specific_pods" { 154 targets = discovery.kubernetes.all_pods.targets 155 156 rule { 157 action = "drop" 158 regex = "Succeeded|Failed|Completed" 159 source_labels = ["__meta_kubernetes_pod_phase"] 160 } 161 162 rule { 163 action = "replace" 164 source_labels = ["__meta_kubernetes_namespace"] 165 target_label = "namespace" 166 } 167 168 rule { 169 action = "replace" 170 source_labels = ["__meta_kubernetes_pod_name"] 171 target_label = "pod" 172 } 173 174 rule { 175 action = "replace" 176 source_labels = ["__meta_kubernetes_node_name"] 177 target_label = "node" 178 } 179 180 rule { 181 action = "replace" 182 source_labels = ["__meta_kubernetes_pod_container_name"] 183 target_label = "container" 184 } 185 186 rule { 187 action = "replace" 188 regex = "(.*)@(.*)" 189 replacement = "${1}/${2}" 190 separator = "@" 191 source_labels = ["__meta_kubernetes_namespace", "__meta_kubernetes_pod_container_name"] 192 target_label = "service_name" 193 } 194 195 rule { 196 action = "keep" 197 regex = "(ns1/.*)|(ns2/container-.*0)" 198 source_labels = ["service_name"] 199 } 200 } 201 ``` 202 203 1. Use `discovery.relabel.specific_pods.output` as a target for `pyroscope.scrape` block. 204 205 ```alloy 206 pyroscope.scrape "scrape_job_name" { 207 targets = discovery.relabel.specific_pods.output 208 ... 209 } 210 ``` 211 212 ### Exposing pprof endpoints 213 214 If you don't use `http.DefaultServeMux`, you can register `/debug/pprof/*` handlers to your own `http.ServeMux`: 215 216 ```go 217 var mux *http.ServeMux 218 mux.Handle("/debug/pprof/", http.DefaultServeMux) 219 ``` 220 221 Or, if you use gorilla/mux: 222 223 ```go 224 var router *mux.Router 225 router.PathPrefix("/debug/pprof").Handler(http.DefaultServeMux) 226 ``` 227 228 ## References 229 230 - [Grafana Alloy](https://grafana.com/docs/alloy/<ALLOY_VERSION>/) 231 - [pyroscope.scrape](https://grafana.com/docs/alloy/<ALLOY_VERSION>/reference/components/pyroscope/pyroscope.scrape/) 232 - [pyroscope.write](https://grafana.com/docs/alloy/<ALLOY_VERSION>/reference/components/pyroscope/pyroscope.write/) 233 - [discovery.kubernetes](https://grafana.com/docs/alloy/<ALLOY_VERSION>/reference/components/discovery/discovery.kubernetes/) 234 - [discovery.docker](https://grafana.com/docs/alloy/<ALLOY_VERSION>/reference/components/discovery/discovery.docker/) 235 - [discovery.relabel](https://grafana.com/docs/alloy/<ALLOY_VERSION>/reference/components/discovery/discovery.relabel/)