Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -270,9 +270,6 @@ release-vlutils-windows-goarch: \
vlagent-windows-$(GOARCH)-prod.exe \
vlogscli-windows-$(GOARCH)-prod.exe

pprof-cpu:
go tool pprof -trim_path=github.com/VictoriaMetrics/VictoriaLogs $(PPROF_FILE)

fmt:
gofmt -l -w -s ./lib
gofmt -l -w -s ./app
Expand Down
67 changes: 67 additions & 0 deletions benchmarks/pprof/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# pprof Source Path Helper

This script is a wrapper around `go tool pprof` designed to
correctly display source code when profiling VictoriaLogs components.

It automatically configures the `-source_path` and `-trim_path` flags to
resolve issues with mismatched paths for modules containing uppercase letters.

## The Problem

By default, pprof looks for source code in the current directory, which often excludes external dependencies.
Even if you manually point the `-source_path` flag to the `GOMODCACHE` directory,
you will find that this approach does not work for modules with uppercase letters in their names:

1. Go escapes uppercase letters in file paths on disk.
For example, the module `github.com/VictoriaMetrics/VictoriaMetrics` is stored as
`github.com/!victoria!metrics/!victoria!metrics`.
2. `pprof` searches for source files using the original import path (`VictoriaMetrics`),
but the directory on disk has a different name (`!victoria!metrics`).
3. As a result, `pprof` fails to locate the file.

As a result, manually configuring `-source_path` and `-trim_path` becomes challenging.

## How It Works

The script resolves this issue by:

1. Removing the module path prefix for problematic modules using the `-trim_path` flag.
2. Constructing the relative path to the source file for problematic modules using the `-source_path` flag.
3. Calling `pprof` with properly generated `-source_path` and `-trim_path` flags.

**Note:** In case of identical relative source paths, the script uses the first match found.
The current working directory has higher priority than external dependencies.
For conflicts between external modules, the script uses the first occurrence in the `MODULES` list.

For example, if the module `github.com/VictoriaMetrics/VictoriaMetrics` contains `pkg/storage/indexdb/indexdb.go`
and the module `github.com/VictoriaMetrics/VictoriaLogs` contains `pkg/storage/indexdb/indexdb.go`,
the script will use the version from the first module in the list.

## Usage

Run the script with the path to the pprof profile as an argument:

```sh
./pprof.sh mem.pprof
```

Or use the HTTP protocol to fetch the profile from a running VictoriaLogs instance:

```sh
./pprof.sh http://localhost:9428/debug/pprof/heap
```

## Configuration

Currently, the script is configured for specific modules with uppercase letters in their names.
If you need to add other libraries that contain uppercase letters in their names,
edit the `MODULES` array inside the script:

```sh
MODULES=(
"github.com/VictoriaMetrics/VictoriaMetrics"
# ...
# Add your module here:
"github.com/VictoriaMetrics/MyLib"
)
```
29 changes: 29 additions & 0 deletions benchmarks/pprof/pprof.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash
set -e

PPROF_FILE="${1:-cpu.pprof}"

# Define the list of paths where pprof can find the source code.
# Initially, this list contains paths to the current directory, the Go standard library, and project dependencies.
SOURCE_PATH="$(pwd):$(go env GOROOT)/src:$(go env GOMODCACHE)"
TRIM_PATH=""

MODULES=(
"github.com/VictoriaMetrics/VictoriaMetrics"
"github.com/VictoriaMetrics/easyproto"
"github.com/VictoriaMetrics/metrics"
)
for mod in "${MODULES[@]}"; do
# Add the local vendor path to source paths.
SOURCE_PATH="$SOURCE_PATH:$(pwd)/vendor/$mod"
# Retrieve the module version to populate trim_path.
MOD_VERSION=$(go list -m -f "$mod@{{.Version}}" "$mod")

if [ -z "$TRIM_PATH" ]; then
TRIM_PATH="$MOD_VERSION"
else
TRIM_PATH="$TRIM_PATH:$MOD_VERSION"
fi
done

go tool pprof -trim_path "$TRIM_PATH" -source_path "$SOURCE_PATH" "$PPROF_FILE"