github.com/grafana/pyroscope@v1.18.0/docs/sources/view-and-analyze-profile-data/line-by-line.md (about) 1 --- 2 description: Integrate your source code on GitHub with Pyroscope profiling data. 3 keywords: 4 - GitHub 5 - continuous profiling 6 - flame graphs 7 menuTitle: Show usage line by line 8 title: Integrate your source code on GitHub with Pyroscope profiling data. 9 weight: 550 10 --- 11 12 # Integrate your source code on GitHub with Pyroscope profiling data. 13 14 The Grafana Pyroscope source code integration offers seamless integration between your GitHub code repositories and Grafana. 15 Using this app, you can map your code directly within Grafana and visualize resource performance line by line. 16 With these powerful capabilities, you can gain deep insights into your code's execution and identify performance bottlenecks. 17 18 Every profile type works with the integration for code written in Go, Java, and Python. 19 20 For information on profile types and the profiles available with Go, Java, and Python, refer to [Profiling types and their uses](../../introduction/profiling-types/). 21 22  23 24 ## How it works 25 26 The Pyroscope source code integration uses labels configured in the application being profiled to associate profiles with source code. 27 The integration is available for Go, Java, and Python applications. 28 29 The Pyroscope source code integration uses three labels, `service_repository`, `service_git_ref`, and `service_root_path`, to add commit information, repository link, and an enhanced source code preview to the **Function Details** screen. 30 31 {{< admonition type="note" >}} 32 The source code mapping is only available to people who have access to the source code in GitHub. 33 {{< /admonition >}} 34 35 ## Before you begin 36 37 To use the Pyroscope source code integration with GitHub, you need an application that emits profiling data, a GitHub account, and a Grafana instance with a Grafana Pyroscope backend. 38 39 ### Application with profiling data requirements 40 41 {{< admonition type="warning" >}} 42 - Applications in other languages aren't supported 43 {{< /admonition >}} 44 45 - A Go application which is profiled by Grafana Alloy's `pyroscope.scrape`, `pyroscope.ebpf` (Alloy v1.11.0+), or using the [Go Push SDK](../../configure-client/language-sdks/go_push/). 46 - A Java application which is profiled by Grafana Alloy's `pyroscope.java`, `pyroscope.ebpf` (Alloy v1.11.0+), or using the [Java SDK](../../configure-client/language-sdks/java). For Java applications, a committed `.pyroscope.yaml` file is required to map package names to source code locations (see [Advanced source code mapping with `.pyroscope.yaml`](#advanced-source-code-mapping-with-pyroscopeyaml)). 47 - A Python application which is profiled by Grafana Alloy's `pyroscope.ebpf` (Alloy v1.11.0+) or using the [Python SDK](../../configure-client/language-sdks/python). 48 49 Your application provides the following labels (tags): 50 51 - `service_git_ref` points to the Git commit or [reference](https://docs.github.com/en/rest/git/refs?apiVersion=2022-11-28#about-git-references) from which the binary was built 52 - `service_repository` is the GitHub repository that hosts the source code 53 - `service_root_path` (Optional) is the path where the code lives inside the repository 54 55 To activate this integration, add at least the two mandatory labels when 56 sending profiles: `service_repository` and `service_git_ref`. Set them to the 57 full repository GitHub URL and the current [`git 58 ref`](https://docs.github.com/en/rest/git/refs?apiVersion=2022-11-28#about-git-references) 59 respectively. 60 61 For example, using the Go SDK you can set these labels as tags in the configuration: 62 63 ```go 64 pyroscope.Start(pyroscope.Config{ 65 Tags: map[string]string{ 66 "service_git_ref": "<GIT_REF>", 67 "service_repository": "https://github.com/<YOUR_ORG>/<YOUR_REPOSITORY>", 68 "service_root_path": "<PATH_TO_SERVICE_ROOT>", // optional 69 }, 70 // Other configuration 71 }) 72 ``` 73 74 You can also override these values directly in the UI by clicking the edit 75 button next to the repository information in the Function Details panel. This 76 is useful for testing new configurations before deploying label changes, or for 77 quickly setting up source code viewing during an incident. 78 79  80 81 ### GitHub requirements 82 83 - A GitHub account 84 - Source code hosted on GitHub 85 86 {{< admonition type="note" >}} 87 Data from your GitHub repository may be limited if your GitHub organization or repository restricts third-party applications. 88 For example, the organization may need to add this app to an allowlist to access organizational resources. 89 Contact your organization administrator for assistance. 90 Refer to [Requesting a GitHub App from your organization owner](https://docs.github.com/en/apps/using-github-apps/requesting-a-github-app-from-your-organization-owner). 91 {{< /admonition >}} 92 93 ### Ensure the source code integration is configured in Grafana Pyroscope 94 95 Refer to [Configure Pyroscope source code integration](../../configure-server/configuring-github-integration/) on the steps required. 96 97 ### Ensure the Grafana Pyroscope data source is configured correctly 98 99 In order to make use of the GitHub integration, the Pyroscope data source needs to be configured to pass a particular cookie through. 100 101 To configure cookie passthrough in Grafana: 102 103 1. Navigate to **Configuration** > **Data sources** in Grafana. 104 1. Select your Pyroscope data source. 105 1. Under **Additional settings** > **Advanced HTTP settings** , locate **Allowed cookies**. 106 1. Add `pyroscope_git_session` to the list of cookies to forward. 107 1. Click **Save & test** to apply the changes. 108 109 110  111 112 {{< admonition type="note" >}} 113 Cookie forwarding must be enabled for the source code integration to work properly. Without it, you won't be able to connect to GitHub repositories from within Grafana Profiles Drilldown. 114 {{< /admonition >}} 115 116 117 ## Authorize access to GitHub 118 119 You can authorize with GitHub using the **Connect to GitHub** in the **Function Details** panel. 120 121 1. From within **Single view** with a configured Pyroscope app plugin. 122 1. Select **Pyroscope service**. For this example, select `cpu_profile`. 123 1. Click in the flame graph on a function you want to explore. Select **Function details**. 124 1. On **Function Details**, locate the **Repository** field and select **Connect to \<GITHUB REPOSITORY\>**, where `<GITHUB REPOSITORY>` is replaced with the repository name where the files reside. In this case, it’s connecting to the `grafana/pyroscope` repository. 125 1. If prompted, log in to GitHub. 126 1. After Grafana connects to your GitHub account, review the permissions and select **Authorize Grafana Pyroscope**. 127 128 {{< admonition type="note" >}} 129 Organization owners may disallow third-party apps for the entire organization or specific organization resources, like repositories. 130 If this is the case, you won't be able authorize the Grafana Pyroscope GitHub integration to view source code or commit information for the protected resources. 131 {{< /admonition >}} 132 133 ### Modify or remove the Pyroscope source code integration from your GitHub account 134 135 The Pyroscope source code integration for GitHub uses a GitHub app called "Grafana Pyroscope" to connect to GitHub. 136 This application authorizes Grafana Cloud to access source code and commit information. 137 138 After authorizing the app, your GitHub account, **GitHub** > **Settings** > **Applications** lists the Grafana Pyroscope app. 139 140 You can change the repositories the Pyroscope source code integration can access on the **Applications** page. 141 142 You can use also remove the app's permissions by selecting **Revoke**. 143 Revoking the permissions disables the integration in your Grafana Cloud account. 144 145 For more information about GitHub applications: 146 147 - [Using GitHub apps](https://docs.github.com/en/apps/using-github-apps/about-using-github-apps) 148 - [Authorizing GitHub apps](https://docs.github.com/en/apps/using-github-apps/authorizing-github-apps) 149 - [Differences between installing and authorizing apps](https://docs.github.com/en/apps/using-github-apps/installing-a-github-app-from-a-third-party#difference-between-installation-and-authorization) 150 151 ## How your GitHub code shows up in profile data queries 152 153 After authorizing the Pyroscope Grafana source code integration, you see more details in the **Function Details** from flame graphs in Profiles Drilldown. 154 155 1. Open a browser to your Pyroscope instance. 156 1. Sign in to your account, if prompted. 157 1. After the Grafana instance loads, select **Drilldown**. 158 1. Next, select **Profiles** > **Single view** from the left-side menu. 159 1. Optional: Select a **Service** and **Profile**. 160 1. Click in the flame graph and select **Function details** from the pop-up menu. 161 162 ### Function Details 163 164 The Function Details section provides information about the function you selected from the flame graph. 165 166 {{< figure max-width="80%" class="center" caption-align="center" src="/media/docs/grafana-cloud/profiles/screenshot-profiles-github-funct-details-v3.png" caption="Function Details panel from a connected Pyroscope source code integration." >}} 167 168 The table explains the main fields in the table. 169 The values for some of the fields, such as Self and Total, change depending whether a profile uses time or memory amount. 170 Refer to [Understand Self versus Total metrics in profiling with Pyroscope](https://grafana.com/docs/pyroscope/latest/view-and-analyze-profile-data/self-vs-total/) for more information. 171 172 | Field | Meaning | Notes | 173 | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------- | 174 | Function name | The name of the selected function | | 175 | Start time | The line where the function definition starts | | 176 | File | Path where the function is defined | You can use the clipboard icon to copy the path. | 177 | Repository | The repository configured for the selected service | | 178 | Commit | The version of the application (commit) where the function is defined. Use the drop-down menu to target a specific commit. | Click the Commit ID to view the commit in the repository. | 179 | Breakdown per line (table) | Provides the function location in the code and self and total values. | | 180 | Self | 'Self' refers to the resource usage (CPU time, memory allocation, etc.) directly attributed to a specific function or a code segment, excluding the resources used by its sub-functions or calls | This value can be a time or memory amount depending on the profile selected. | 181 | Total | 'Total' encompasses the combined resource usage of a function along with all the functions it calls. | This value can be a time or memory amount depending on the profile selected. | 182 183 ## Advanced source code mapping with `.pyroscope.yaml` 184 185 For more complex applications with multiple dependencies and external libraries, you can configure custom source code mappings using a `.pyroscope.yaml` configuration file in your repository. This feature enables Pyroscope to resolve and display source code from: 186 187 - Multiple GitHub repositories (for example, third-party dependencies) 188 - Different versions and branches of dependencies 189 - Standard library code (Go, Java) 190 - Vendor directories and local paths 191 192 ### How source code mapping works 193 194 When you click on a function in the flame graph, Pyroscope performs the following steps to retrieve the source code: 195 196 1. **Load configuration**: Pyroscope checks for a `.pyroscope.yaml` file in your service's root path. This is determined by labels on the profiling data as mentioned in [How this works](#how-this-works). 197 2. **Match file location**: If a configuration file exists, the system matches the file path or function name from the profiling data against the configured mappings using a longest-prefix-match algorithm. 198 3. **Resolve matched source location**: If a mapping matches, Pyroscope determines whether to fetch code from: 199 - A local path within your repository 200 - An external GitHub repository at a specific version 201 4. **Automatic mapping**: If no configuration file exists or no mappings matched, the system tries to find the related source code using heuristics: 202 - Go: Detect standard library functions and `go.mod` dependencies 203 - All languages: Resolve using the file path relative to the service root 204 5. **Fetch and display**: The source code is retrieved and displayed in the Function Details panel with line-by-line profiling data 205 206 ### Supported languages 207 208 Pyroscope's source code integration supports the following languages: 209 210 - **Go**: Full support including standard library, Go modules, and vendor directories. Works automatically without configuration, but can be customized with `.pyroscope.yaml`. 211 - **Python**: Full support including standard library and installed packages. Works automatically without configuration, but can be customized with `.pyroscope.yaml`. 212 - **Java**: Requires a `.pyroscope.yaml` file with explicit mappings for application code and dependencies. 213 214 {{< admonition type="note" >}} 215 While Go and Python work automatically, you can use a `.pyroscope.yaml` file to customize source mappings for any language. 216 {{< /admonition >}} 217 218 ### Configuration file format 219 220 Create a `.pyroscope.yaml` file in the root of your repository (or in the path specified by `service_root_path` if configured) with the following structure: 221 222 ```yaml 223 version: v1 # Config format version (currently only v1 is supported) 224 source_code: 225 mappings: # Array of source-to-repository mappings 226 - path: # Match files by path prefix (optional if function_name is specified) 227 - prefix: path/to/match 228 - prefix: another/path 229 function_name: # Match by function name prefix (optional if path is specified) 230 - prefix: function/prefix 231 language: go # Required: "go", "java", or "python" 232 source: # Define where to fetch the source code 233 local: 234 path: src/main/java # Path relative to the location of the .pyroscope.yaml file 235 # OR 236 github: 237 owner: organization # GitHub repository owner 238 repo: repository # GitHub repository name 239 ref: v1.0.0 # Branch, tag, or commit SHA 240 path: src # Path within the external repository 241 ``` 242 243 ### Configuration rules 244 245 - Each mapping must specify either a `local` or `github` source (not both) 246 - Multiple `path` or `function_name` prefixes can be specified per mapping (they are OR'd together) 247 - Mappings are evaluated using longest-prefix-match (more specific mappings take precedence) 248 - If no mapping matches, Pyroscope falls back to language-specific default behavior (automatic resolution for Go; Java requires explicit mappings) 249 250 ### Example: Go standard library mapping 251 252 Map the Go standard library to a specific Go version: 253 254 ```yaml 255 version: v1 256 source_code: 257 mappings: 258 - path: 259 - prefix: $GOROOT/src 260 language: go 261 source: 262 github: 263 owner: golang 264 repo: go 265 ref: go1.24.10 266 path: src 267 ``` 268 269 This configuration ensures that when you view standard library functions like `fmt.Println` or `net/http.Server`, Pyroscope fetches the source code from the `golang/go` repository at version 1.24.10. 270 271 ### Example: Java application with dependencies 272 273 Configure mappings for a Java Spring application: 274 275 ```yaml 276 version: v1 277 source_code: 278 mappings: 279 # Local application code 280 - function_name: 281 - prefix: org/example/myapp 282 language: java 283 source: 284 local: 285 path: src/main/java 286 287 # JDK standard library 288 - function_name: 289 - prefix: java 290 - prefix: javax 291 language: java 292 source: 293 github: 294 owner: openjdk 295 repo: jdk 296 ref: jdk-17+0 297 path: src/java.base/share/classes 298 299 # Spring Framework dependencies 300 - function_name: 301 - prefix: org/springframework/web/servlet 302 language: java 303 source: 304 github: 305 owner: spring-projects 306 repo: spring-framework 307 ref: v5.3.20 308 path: spring-webmvc/src/main/java 309 310 - function_name: 311 - prefix: org/springframework/web 312 - prefix: org/springframework/http 313 language: java 314 source: 315 github: 316 owner: spring-projects 317 repo: spring-framework 318 ref: v5.3.20 319 path: spring-web/src/main/java 320 ``` 321 322 This configuration demonstrates: 323 324 - **Longest-prefix matching**: `org/springframework/web/servlet` matches the more specific mapping, while `org/springframework/web/client` matches the less specific one 325 - **Multiple prefixes**: HTTP and web packages from Spring are grouped together 326 - **Mixed sources**: Local application code and external dependencies 327 328 ### Example: Go application with vendor dependencies 329 330 Map vendored dependencies and modules: 331 332 ```yaml 333 version: v1 334 source_code: 335 mappings: 336 # Vendor directory (for dependencies copied into your repo) 337 - path: 338 - prefix: vendor/ 339 language: go 340 source: 341 local: 342 path: vendor 343 344 # External dependency at specific version 345 - path: 346 - prefix: github.com/prometheus/client_golang 347 language: go 348 source: 349 github: 350 owner: prometheus 351 repo: client_golang 352 ref: v1.19.0 353 path: "" 354 ``` 355 356 ### Example: Python application with dependencies 357 358 Map Python application code and external dependencies: 359 360 ```yaml 361 version: v1 362 source_code: 363 mappings: 364 # Local application code 365 - path: 366 - prefix: /app/src 367 language: python 368 source: 369 local: 370 path: src 371 372 # Python standard library 373 - path: 374 - prefix: /usr/lib/python3.12 375 - prefix: /usr/local/lib/python3.12 376 language: python 377 source: 378 github: 379 owner: python 380 repo: cpython 381 ref: v3.12.0 382 path: Lib 383 384 # External package (requests) 385 - path: 386 - prefix: /usr/local/lib/python3.12/site-packages/requests 387 language: python 388 source: 389 github: 390 owner: psf 391 repo: requests 392 ref: v2.31.0 393 path: src/requests 394 ``` 395 396 This configuration demonstrates: 397 398 - **Local application code**: Maps your application's source directory 399 - **Standard library**: Maps Python standard library paths to the CPython repository 400 - **External packages**: Maps third-party packages to their GitHub repositories 401 402 ### Language-specific behavior 403 404 #### Go 405 406 For Go applications, Pyroscope provides intelligent fallback behavior even without a `.pyroscope.yaml` file: 407 408 - **Standard library**: Automatically detected and mapped to the appropriate `golang/go` repository version 409 - **Go modules**: Parsed from `go.mod` in your repository, with automatic version resolution 410 - **Vanity URLs**: Resolved to canonical repositories (for example, `gopkg.in`, `google.golang.org`) 411 - **Vendor directories**: Files in `vendor/` are searched relative to repository root 412 413 The system extracts Go version information from paths like `/usr/local/go/go1.24.10/src/fmt/print.go`. 414 415 #### Java 416 417 Java applications **require** explicit mappings in `.pyroscope.yaml`: 418 419 - **Function name conversion**: Java function names like `org/example/App$Inner.method` are automatically converted to `org/example/App.java` 420 - **No fallback**: Unlike Go and Python, Java files cannot be resolved without configuration 421 - **Inner classes**: Automatically handled (inner class markers are stripped) 422 423 #### Python 424 425 For Python applications, Pyroscope provides intelligent fallback behavior similar to Go: 426 427 - **Standard library**: Automatically detected and mapped to the appropriate `python/cpython` repository version 428 - **Installed packages**: Resolved from virtual environments or system packages 429 - **File paths**: Direct file paths are used when available from profiling data 430 431 The system extracts Python version information from paths to map to the correct CPython repository version. 432 433 ### Troubleshooting 434 435 **No source code displayed** 436 437 - Verify the `.pyroscope.yaml` file is in your service's configured root path and that the root path is configured as expected 438 - Check that the `path` or `function_name` prefixes match your profiling data 439 - For Java applications, ensure all dependencies have mappings configured 440 - Confirm GitHub OAuth authorization is active and hasn't expired 441 442 **Wrong version displayed** 443 444 - Check the `ref` field in your mapping points to the correct branch, tag, or commit 445 - For Go standard library, verify the Go version in your mapping matches your application's Go version 446 - Use explicit commit SHAs for reproducibility 447 448 **Mapping precedence issues** 449 450 Pyroscope uses longest-prefix-match. If a more specific mapping isn't being used: 451 452 - Verify the prefix exactly matches the beginning of the path or function name 453 - Check that more specific mappings are listed in the configuration (order doesn't matter, but clarity helps) 454 - Test with exact prefixes from your profiling data