diff --git a/.github/workflows/auto-upgrade-ci.yaml b/.github/workflows/auto-upgrade-ci.yaml index 109644f1a0..fb1b962442 100644 --- a/.github/workflows/auto-upgrade-ci.yaml +++ b/.github/workflows/auto-upgrade-ci.yaml @@ -214,7 +214,7 @@ jobs: - name: Setup Golang uses: actions/setup-go@v5 with: - go-version: 1.21.4 + go-version: 1.23.0 - name: Install Kind Bin uses: helm/kind-action@v1.10.0 diff --git a/.github/workflows/e2e-init.yaml b/.github/workflows/e2e-init.yaml index 02df82c9f2..f349252240 100644 --- a/.github/workflows/e2e-init.yaml +++ b/.github/workflows/e2e-init.yaml @@ -96,7 +96,7 @@ jobs: - name: Setup Golang uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.23.0 - name: Install Tools run: | diff --git a/.github/workflows/lint-golang.yaml b/.github/workflows/lint-golang.yaml index 2b911c1b20..e1f2bccdef 100644 --- a/.github/workflows/lint-golang.yaml +++ b/.github/workflows/lint-golang.yaml @@ -82,7 +82,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: 1.21.4 + go-version: 1.23.0 - name: Checkout code uses: actions/checkout@v4 @@ -138,7 +138,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: 1.21.4 + go-version: 1.23.0 - name: Checkout code uses: actions/checkout@v4 @@ -192,7 +192,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: 1.21.4 + go-version: 1.23.0 - name: Checkout code uses: actions/checkout@v4 diff --git a/.github/workflows/update-golang-version.yaml b/.github/workflows/update-golang-version.yaml new file mode 100644 index 0000000000..f7a3a585a8 --- /dev/null +++ b/.github/workflows/update-golang-version.yaml @@ -0,0 +1,77 @@ +name: Update Golang Version + +permissions: write-all + +on: + schedule: + # each day + - cron: "0 20 * * *" + workflow_dispatch: + +jobs: + update-golang-version: + runs-on: ubuntu-latest + steps: + - name: Checkout Source Code + uses: actions/checkout@v4 + with: + persist-credentials: false + ref: main + + - name: Get latest Go version + id: get-go-version + run: | + LATEST_GOLANG_VERSION=$(curl -s --retry 10 https://go.dev/dl/ | grep -oP 'go[0-9]+\.[0-9]+\.[0-9]+' | head -n 1) + echo "LATEST_GOLANG_VERSION=${LATEST_GOLANG_VERSION}" >> $GITHUB_ENV + + - name: Read current Go version from Makefile.version + id: read-makefile-version + run: | + CURRENT_GO_VERSION=$(grep '^GO_VERSION := ' Makefile.version | awk '{print $3}') + echo "CURRENT_GO_VERSION=${CURRENT_GO_VERSION}" >> $GITHUB_ENV + + - name: Compare versions and update Makefile.version + run: | + LATEST_GOLANG_VERSION=$(echo $LATEST_GOLANG_VERSION | sed 's/go//') + if [ "$(printf '%s\n' "${LATEST_GOLANG_VERSION}" "${CURRENT_GO_VERSION}" | sort -r | head -n1)" = "${LATEST_GOLANG_VERSION}" ]; then + echo "LATEST_GOLANG_VERSION:${LATEST_GOLANG_VERSION} is greater than CURRENT_GO_VERSION:${CURRENT_GO_VERSION}" + sed -i "s/^GO_VERSION := .*/GO_VERSION := ${LATEST_GOLANG_VERSION}/" Makefile.version + echo "updated=true" >> $GITHUB_ENV + else + echo "no update needed, current version CURRENT_GO_VERSION:${CURRENT_GO_VERSION} is up to date." + echo "updated=false" >> $GITHUB_ENV + fi + + - name: update golang version + if: ${{ env.updated == 'true' }} + run: | + RESULT=0 + make update-go-version || RESULT=1 + if ((RESULT==0)) ; then + echo "succeeded to update golang version from CURRENT_GO_VERSION:${CURRENT_GO_VERSION} to LATEST_GOLANG_VERSION:${LATEST_GOLANG_VERSION}" + else + echo "failed to update golang version from CURRENT_GO_VERSION:${CURRENT_GO_VERSION} to LATEST_GOLANG_VERSION:${LATEST_GOLANG_VERSION}" + fi + + - uses: crazy-max/ghaction-import-gpg@v6 + if: ${{ env.updated == 'true' }} + with: + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.GPG_PASSPHRASE }} + git_user_signingkey: true + git_commit_gpgsign: true + + - name: Create Pull Request + id: create_pr + if: ${{ env.updated == 'true' }} + uses: peter-evans/create-pull-request@v6.1.0 + with: + title: "robot updated golang version" + commit-message: "robot updated golang version" + branch: robot/update_golang_version + committer: ty-dc + delete-branch: true + base: main + signoff: true + token: ${{ secrets.WELAN_PAT }} + labels: pr/release/robot_update_version diff --git a/Makefile.version b/Makefile.version index 9076a854c7..7f003fc6c6 100644 --- a/Makefile.version +++ b/Makefile.version @@ -1,2 +1,2 @@ -GO_VERSION := 1.21.4 +GO_VERSION := 1.23.0 GINKGO_VERSION := 2.1.3 diff --git a/go.mod b/go.mod index acff765a57..a34db27545 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/spidernet-io/spiderpool -go 1.22.0 +go 1.23.0 require ( github.com/agiledragon/gomonkey/v2 v2.11.0 @@ -19,7 +19,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/golang/mock v1.6.0 github.com/google/gops v0.3.27 - github.com/grafana/pyroscope-go v1.1.1 + github.com/grafana/pyroscope-go v1.1.2 github.com/jessevdk/go-flags v1.5.0 github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.4.0 github.com/kdoctor-io/kdoctor v0.2.0 @@ -116,7 +116,7 @@ require ( github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/handlers v1.5.1 // indirect - github.com/grafana/pyroscope-go/godeltaprof v0.1.6 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/huandu/xstrings v1.3.3 // indirect @@ -125,7 +125,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/josharian/native v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.3 // indirect + github.com/klauspost/compress v1.17.8 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect diff --git a/go.sum b/go.sum index 47eb466601..0c1e51866a 100644 --- a/go.sum +++ b/go.sum @@ -303,10 +303,10 @@ github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grafana/pyroscope-go v1.1.1 h1:PQoUU9oWtO3ve/fgIiklYuGilvsm8qaGhlY4Vw6MAcQ= -github.com/grafana/pyroscope-go v1.1.1/go.mod h1:Mw26jU7jsL/KStNSGGuuVYdUq7Qghem5P8aXYXSXG88= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6 h1:nEdZ8louGAplSvIJi1HVp7kWvFvdiiYg3COLlTwJiFo= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6/go.mod h1:Tk376Nbldo4Cha9RgiU7ik8WKFkNpfds98aUzS8omLE= +github.com/grafana/pyroscope-go v1.1.2 h1:7vCfdORYQMCxIzI3NlYAs3FcBP760+gWuYWOyiVyYx8= +github.com/grafana/pyroscope-go v1.1.2/go.mod h1:HSSmHo2KRn6FasBA4vK7BMiQqyQq8KSuBKvrhkXxYPU= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= @@ -350,8 +350,8 @@ github.com/kdoctor-io/kdoctor v0.2.0/go.mod h1:TxkjBwM4sdnOTHABxgL1gO68tlzHUnbiu github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA= -github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= diff --git a/images/spiderpool-agent/Dockerfile b/images/spiderpool-agent/Dockerfile index 7e5b9511b9..ad09835989 100644 --- a/images/spiderpool-agent/Dockerfile +++ b/images/spiderpool-agent/Dockerfile @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 ARG BASE_IMAGE=ghcr.io/spidernet-io/spiderpool/spiderpool-base:1f8330482d25b58d2ae26bc6252e20384bac92ad -ARG GOLANG_IMAGE=docker.io/library/golang:1.22.0@sha256:03082deb6ae090a0caa4e4a8f666bc59715bc6fa67f5fd109f823a0c4e1efc2a +ARG GOLANG_IMAGE=docker.io/library/golang:1.23.0@sha256:613a108a4a4b1dfb6923305db791a19d088f77632317cfc3446825c54fb862cd #======= build bin ========== FROM --platform=${BUILDPLATFORM} ${GOLANG_IMAGE} as builder diff --git a/images/spiderpool-base/Dockerfile b/images/spiderpool-base/Dockerfile index 89a74935ed..30170b90de 100644 --- a/images/spiderpool-base/Dockerfile +++ b/images/spiderpool-base/Dockerfile @@ -3,7 +3,7 @@ # docker buildx build -t testbase:latest --platform=linux/arm64,linux/amd64 --output type=docker . -ARG GOLANG_IMAGE=docker.io/library/golang:1.22.0@sha256:03082deb6ae090a0caa4e4a8f666bc59715bc6fa67f5fd109f823a0c4e1efc2a +ARG GOLANG_IMAGE=docker.io/library/golang:1.23.0@sha256:613a108a4a4b1dfb6923305db791a19d088f77632317cfc3446825c54fb862cd ARG UBUNTU_IMAGE=docker.io/library/ubuntu:20.04@sha256:bea6d19168bbfd6af8d77c2cc3c572114eb5d113e6f422573c93cb605a0e2ffb diff --git a/images/spiderpool-controller/Dockerfile b/images/spiderpool-controller/Dockerfile index 225ded6659..ee3206aff8 100644 --- a/images/spiderpool-controller/Dockerfile +++ b/images/spiderpool-controller/Dockerfile @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 ARG BASE_IMAGE=ghcr.io/spidernet-io/spiderpool/spiderpool-base:1f8330482d25b58d2ae26bc6252e20384bac92ad -ARG GOLANG_IMAGE=docker.io/library/golang:1.22.0@sha256:03082deb6ae090a0caa4e4a8f666bc59715bc6fa67f5fd109f823a0c4e1efc2a +ARG GOLANG_IMAGE=docker.io/library/golang:1.23.0@sha256:613a108a4a4b1dfb6923305db791a19d088f77632317cfc3446825c54fb862cd #======= build bin ========== FROM --platform=${BUILDPLATFORM} ${GOLANG_IMAGE} as builder diff --git a/images/spiderpool-plugins/Dockerfile b/images/spiderpool-plugins/Dockerfile index b4655edd55..12d908657e 100644 --- a/images/spiderpool-plugins/Dockerfile +++ b/images/spiderpool-plugins/Dockerfile @@ -1,7 +1,7 @@ # Copyright 2023 Authors of spidernet-io # SPDX-License-Identifier: Apache-2.0 -ARG GOLANG_IMAGE=docker.io/library/golang:1.22.0@sha256:03082deb6ae090a0caa4e4a8f666bc59715bc6fa67f5fd109f823a0c4e1efc2a +ARG GOLANG_IMAGE=docker.io/library/golang:1.23.0@sha256:613a108a4a4b1dfb6923305db791a19d088f77632317cfc3446825c54fb862cd #======= build plugins ========== FROM --platform=${BUILDPLATFORM} ${GOLANG_IMAGE} as builder diff --git a/vendor/github.com/grafana/pyroscope-go/CODEOWNERS b/vendor/github.com/grafana/pyroscope-go/CODEOWNERS new file mode 100644 index 0000000000..bee0e6422c --- /dev/null +++ b/vendor/github.com/grafana/pyroscope-go/CODEOWNERS @@ -0,0 +1 @@ +* @grafana/pyroscope-go diff --git a/vendor/github.com/grafana/pyroscope-go/Makefile b/vendor/github.com/grafana/pyroscope-go/Makefile index abbaf43bbd..5b7a6ed0a4 100644 --- a/vendor/github.com/grafana/pyroscope-go/Makefile +++ b/vendor/github.com/grafana/pyroscope-go/Makefile @@ -1,5 +1,5 @@ -GO_VERSION_PRE20 := $(shell go version | awk '{print $$3}' | awk -F '.' '{print ($$1 == "go1" && int($$2) < 20)}') -TEST_PACKAGES := ./... ./godeltaprof/compat/... ./godeltaprof/... +GO_VERSION_PRE20 := $(shell go version | awk '{print $$3}' | awk -F '.' '{print ($$1 == "go1" && int($$2) < 20)}') +TEST_PACKAGES := ./... ./godeltaprof/compat/... ./godeltaprof/... ./x/k6/... .PHONY: test test: @@ -12,11 +12,7 @@ go/mod: GO111MODULE=on go mod tidy cd godeltaprof/compat/ && GO111MODULE=on go mod download cd godeltaprof/compat/ && GO111MODULE=on go mod tidy - cd godeltaprof/ && GO111MODULE=on go mod download + cd godeltaprof/ && GO111MODULE=on go mod download cd godeltaprof/ && GO111MODULE=on go mod tidy - -.PHONY: go/mod_16_for_testing -go/mod_16_for_testing: - rm -rf godeltaprof/compat/go.mod godeltaprof/compat/go.sum godeltaprof/go.mod godeltaprof/go.sum go.work otelpyroscope/ - cat go.mod_go16_test.txt > go.mod - go mod tidy + cd x/k6/ && GO111MODULE=on go mod download + cd x/k6/ && GO111MODULE=on go mod tidy diff --git a/vendor/github.com/grafana/pyroscope-go/README.md b/vendor/github.com/grafana/pyroscope-go/README.md index 111b242646..4c079c7fd5 100644 --- a/vendor/github.com/grafana/pyroscope-go/README.md +++ b/vendor/github.com/grafana/pyroscope-go/README.md @@ -4,7 +4,7 @@ This is a golang integration for Pyroscope — open source continuous profiling For more information, please visit our [golang integration documentation](https://grafana.com/docs/pyroscope/latest/configure-client/language-sdks/go_push/). -### Profiling Go applications +## Profiling Go applications To start profiling a Go application, you need to include our go module in your app: @@ -73,6 +73,10 @@ Go integration supports pull mode, which means that you can profile applications import _ "net/http/pprof" ``` -### Examples +## Examples Check out the [examples](https://grafana.com/docs/pyroscope/latest/configure-client/grafana-agent/go_pull/) directory in our repository to learn more 🔥 + +## Maintainers + +This package is maintained by [@grafana/pyroscope-go](https://github.com/orgs/grafana/teams/pyroscope-go). Mention this team on issues or PRs for feedback. diff --git a/vendor/github.com/grafana/pyroscope-go/go.mod_go16_test.txt b/vendor/github.com/grafana/pyroscope-go/go.mod_go16_test.txt deleted file mode 100644 index 0f0f0dc19e..0000000000 --- a/vendor/github.com/grafana/pyroscope-go/go.mod_go16_test.txt +++ /dev/null @@ -1,12 +0,0 @@ -module github.com/grafana/pyroscope-go - -go 1.16 - -require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/google/pprof v0.0.0-20231127191134-f3a68a39ae15 - github.com/stretchr/testify v1.7.0 - golang.org/x/mod v0.14.0 // indirect - golang.org/x/tools v0.12.0 - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/vendor/github.com/grafana/pyroscope-go/go.work b/vendor/github.com/grafana/pyroscope-go/go.work index b42a1a5c7e..7176f4635d 100644 --- a/vendor/github.com/grafana/pyroscope-go/go.work +++ b/vendor/github.com/grafana/pyroscope-go/go.work @@ -4,4 +4,5 @@ use ( . godeltaprof godeltaprof/compat + x/k6 ) diff --git a/vendor/github.com/grafana/pyroscope-go/go.work.sum b/vendor/github.com/grafana/pyroscope-go/go.work.sum index e663de31aa..6ab106be40 100644 --- a/vendor/github.com/grafana/pyroscope-go/go.work.sum +++ b/vendor/github.com/grafana/pyroscope-go/go.work.sum @@ -6,28 +6,32 @@ github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3I github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww= github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk= github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/ianlancetaylor/demangle v0.0.0-20230524184225-eabc099b10ab h1:BA4a7pe6ZTd9F8kXETBoijjFJ/ntaa//1wiH9BZu4zU= github.com/ianlancetaylor/demangle v0.0.0-20230524184225-eabc099b10ab/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +go.opentelemetry.io/otel/metric v1.17.0 h1:iG6LGVz5Gh+IuO0jmgvpTB6YVrCGngi8QGm+pMd8Pdc= +go.opentelemetry.io/otel/metric v1.17.0/go.mod h1:h4skoxdZI17AxwITdmdZjjYJQH5nzijUUjm+wtPph5o= +go.opentelemetry.io/otel/trace v1.17.0 h1:/SWhSRHmDPOImIAetP1QAeMnZYiQXrTy4fMMYOdSKWQ= +go.opentelemetry.io/otel/trace v1.17.0/go.mod h1:I/4vKTgFclIsXRVucpH25X0mpFSczM7aHeaz0ZBLWjY= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= diff --git a/vendor/github.com/grafana/pyroscope-go/godeltaprof/README.md b/vendor/github.com/grafana/pyroscope-go/godeltaprof/README.md index fccda096f5..78aed1a361 100644 --- a/vendor/github.com/grafana/pyroscope-go/godeltaprof/README.md +++ b/vendor/github.com/grafana/pyroscope-go/godeltaprof/README.md @@ -91,8 +91,11 @@ CPU profiles: [BenchmarkOG](https://flamegraph.com/share/a8f68312-98c7-11ee-a502 # upstreaming -TODO(korniltsev): create golang issue and ask if godeltaprof is something that could be considered merging to upstream golang repo -in some way(maybe not as is, maybe with different APIs) +In the perfect world, this functionality exists in golang runtime/stdlib and we don't need godeltaprof library at all. + +See golang proposals: +https://github.com/golang/go/issues/57765 +https://github.com/golang/go/issues/67942 diff --git a/vendor/github.com/grafana/pyroscope-go/godeltaprof/block.go b/vendor/github.com/grafana/pyroscope-go/godeltaprof/block.go index 825130b729..349c77a97c 100644 --- a/vendor/github.com/grafana/pyroscope-go/godeltaprof/block.go +++ b/vendor/github.com/grafana/pyroscope-go/godeltaprof/block.go @@ -28,6 +28,7 @@ type BlockProfiler struct { mutex sync.Mutex runtimeProfile func([]runtime.BlockProfileRecord) (int, bool) scaleProfile pprof.MutexProfileScaler + options pprof.ProfileBuilderOptions } // NewMutexProfiler creates a new BlockProfiler instance for profiling mutex contention. @@ -42,11 +43,10 @@ func NewMutexProfiler() *BlockProfiler { return &BlockProfiler{ runtimeProfile: runtime.MutexProfile, scaleProfile: pprof.ScalerMutexProfile, - impl: pprof.DeltaMutexProfiler{ - Options: pprof.ProfileBuilderOptions{ - GenericsFrames: true, - LazyMapping: true, - }, + impl: pprof.DeltaMutexProfiler{}, + options: pprof.ProfileBuilderOptions{ + GenericsFrames: true, + LazyMapping: true, }, } } @@ -55,11 +55,10 @@ func NewMutexProfilerWithOptions(options ProfileOptions) *BlockProfiler { return &BlockProfiler{ runtimeProfile: runtime.MutexProfile, scaleProfile: pprof.ScalerMutexProfile, - impl: pprof.DeltaMutexProfiler{ - Options: pprof.ProfileBuilderOptions{ - GenericsFrames: options.GenericsFrames, - LazyMapping: options.LazyMappings, - }, + impl: pprof.DeltaMutexProfiler{}, + options: pprof.ProfileBuilderOptions{ + GenericsFrames: options.GenericsFrames, + LazyMapping: options.LazyMappings, }, } } @@ -76,11 +75,10 @@ func NewBlockProfiler() *BlockProfiler { return &BlockProfiler{ runtimeProfile: runtime.BlockProfile, scaleProfile: pprof.ScalerBlockProfile, - impl: pprof.DeltaMutexProfiler{ - Options: pprof.ProfileBuilderOptions{ - GenericsFrames: true, - LazyMapping: true, - }, + impl: pprof.DeltaMutexProfiler{}, + options: pprof.ProfileBuilderOptions{ + GenericsFrames: true, + LazyMapping: true, }, } } @@ -89,11 +87,10 @@ func NewBlockProfilerWithOptions(options ProfileOptions) *BlockProfiler { return &BlockProfiler{ runtimeProfile: runtime.BlockProfile, scaleProfile: pprof.ScalerBlockProfile, - impl: pprof.DeltaMutexProfiler{ - Options: pprof.ProfileBuilderOptions{ - GenericsFrames: options.GenericsFrames, - LazyMapping: options.LazyMappings, - }, + impl: pprof.DeltaMutexProfiler{}, + options: pprof.ProfileBuilderOptions{ + GenericsFrames: options.GenericsFrames, + LazyMapping: options.LazyMappings, }, } } @@ -115,5 +112,7 @@ func (d *BlockProfiler) Profile(w io.Writer) error { sort.Slice(p, func(i, j int) bool { return p[i].Cycles > p[j].Cycles }) - return d.impl.PrintCountCycleProfile(w, "contentions", "delay", d.scaleProfile, p) + stc := pprof.MutexProfileConfig() + b := pprof.NewProfileBuilder(w, &d.options, stc) + return d.impl.PrintCountCycleProfile(b, d.scaleProfile, p) } diff --git a/vendor/github.com/grafana/pyroscope-go/godeltaprof/heap.go b/vendor/github.com/grafana/pyroscope-go/godeltaprof/heap.go index 8f26755cbd..964b8ad6cf 100644 --- a/vendor/github.com/grafana/pyroscope-go/godeltaprof/heap.go +++ b/vendor/github.com/grafana/pyroscope-go/godeltaprof/heap.go @@ -28,28 +28,28 @@ import ( // ... // err := hp.Profile(someWriter) type HeapProfiler struct { - impl pprof.DeltaHeapProfiler - mutex sync.Mutex + impl pprof.DeltaHeapProfiler + mutex sync.Mutex + options pprof.ProfileBuilderOptions } func NewHeapProfiler() *HeapProfiler { return &HeapProfiler{ - impl: pprof.DeltaHeapProfiler{ - Options: pprof.ProfileBuilderOptions{ - GenericsFrames: true, - LazyMapping: true, - }, + impl: pprof.DeltaHeapProfiler{}, + options: pprof.ProfileBuilderOptions{ + GenericsFrames: true, + LazyMapping: true, }} } func NewHeapProfilerWithOptions(options ProfileOptions) *HeapProfiler { return &HeapProfiler{ - impl: pprof.DeltaHeapProfiler{ - Options: pprof.ProfileBuilderOptions{ - GenericsFrames: options.GenericsFrames, - LazyMapping: options.LazyMappings, - }, - }} + impl: pprof.DeltaHeapProfiler{}, + options: pprof.ProfileBuilderOptions{ + GenericsFrames: options.GenericsFrames, + LazyMapping: options.LazyMappings, + }, + } } func (d *HeapProfiler) Profile(w io.Writer) error { @@ -76,6 +76,7 @@ func (d *HeapProfiler) Profile(w io.Writer) error { } // Profile grew; try again. } - - return d.impl.WriteHeapProto(w, p, int64(runtime.MemProfileRate), "") + rate := int64(runtime.MemProfileRate) + b := pprof.NewProfileBuilder(w, &d.options, pprof.HeapProfileConfig(rate)) + return d.impl.WriteHeapProto(b, p, rate) } diff --git a/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/builder.go b/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/builder.go new file mode 100644 index 0000000000..fc35cdc947 --- /dev/null +++ b/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/builder.go @@ -0,0 +1,18 @@ +package pprof + +type ProfileBuilder interface { + LocsForStack(stk []uintptr) (newLocs []uint64) + Sample(values []int64, locs []uint64, blockSize int64) + Build() +} + +type ProfileConfig struct { + PeriodType ValueType + Period int64 + SampleType []ValueType + DefaultSampleType string +} + +type ValueType struct { + Typ, Unit string +} diff --git a/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/delta_heap.go b/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/delta_heap.go index 47674a55da..883d02008f 100644 --- a/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/delta_heap.go +++ b/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/delta_heap.go @@ -1,38 +1,47 @@ package pprof import ( - "io" "math" "runtime" "strings" ) +type heapPrevValue struct { + allocObjects int64 +} + +type heapAccValue struct { + allocObjects int64 + inuseObjects int64 +} + type DeltaHeapProfiler struct { - m profMap - mem []memMap - Options ProfileBuilderOptions + m profMap[heapPrevValue, heapAccValue] + //todo consider adding an option to remove block size label and merge allocations of different size } // WriteHeapProto writes the current heap profile in protobuf format to w. -func (d *DeltaHeapProfiler) WriteHeapProto(w io.Writer, p []runtime.MemProfileRecord, rate int64, defaultSampleType string) error { - if d.mem == nil || !d.Options.LazyMapping { - d.mem = readMapping() - } - b := newProfileBuilder(w, d.Options, d.mem) - b.pbValueType(tagProfile_PeriodType, "space", "bytes") - b.pb.int64Opt(tagProfile_Period, rate) - b.pbValueType(tagProfile_SampleType, "alloc_objects", "count") - b.pbValueType(tagProfile_SampleType, "alloc_space", "bytes") - b.pbValueType(tagProfile_SampleType, "inuse_objects", "count") - b.pbValueType(tagProfile_SampleType, "inuse_space", "bytes") - if defaultSampleType != "" { - b.pb.int64Opt(tagProfile_DefaultSampleType, b.stringIndex(defaultSampleType)) - } - +func (d *DeltaHeapProfiler) WriteHeapProto(b ProfileBuilder, p []runtime.MemProfileRecord, rate int64) error { values := []int64{0, 0, 0, 0} var locs []uint64 - for _, r := range p { - // do the delta + // deduplicate: accumulate allocObjects and inuseObjects in entry.acc for equal stacks + for i := range p { + r := &p[i] + if r.AllocBytes == 0 && r.AllocObjects == 0 && r.FreeObjects == 0 && r.FreeBytes == 0 { + // it is a fresh bucket and it will be published after next 1-2 gc cycles + continue + } + var blockSize int64 + if r.AllocObjects > 0 { + blockSize = r.AllocBytes / r.AllocObjects + } + entry := d.m.Lookup(r.Stack(), uintptr(blockSize)) + entry.acc.allocObjects += r.AllocObjects + entry.acc.inuseObjects += r.InUseObjects() + } + // do the delta using the accumulated values and previous values + for i := range p { + r := &p[i] if r.AllocBytes == 0 && r.AllocObjects == 0 && r.FreeObjects == 0 && r.FreeBytes == 0 { // it is a fresh bucket and it will be published after next 1-2 gc cycles continue @@ -42,17 +51,27 @@ func (d *DeltaHeapProfiler) WriteHeapProto(w io.Writer, p []runtime.MemProfileRe blockSize = r.AllocBytes / r.AllocObjects } entry := d.m.Lookup(r.Stack(), uintptr(blockSize)) + if entry.acc == (heapAccValue{}) { + continue + } - if (r.AllocObjects - entry.count.v1) < 0 { + allocObjects := entry.acc.allocObjects - entry.prev.allocObjects + if allocObjects < 0 { continue } - AllocObjects := r.AllocObjects - entry.count.v1 - AllocBytes := r.AllocBytes - entry.count.v2 - entry.count.v1 = r.AllocObjects - entry.count.v2 = r.AllocBytes - values[0], values[1] = scaleHeapSample(AllocObjects, AllocBytes, rate) - values[2], values[3] = scaleHeapSample(r.InUseObjects(), r.InUseBytes(), rate) + // allocBytes, inuseBytes is calculated as multiplication of number of objects by blockSize + // This is done to reduce the size of the map entry (i.e. heapAccValue for deduplication and + // heapPrevValue for keeping the delta). + + allocBytes := allocObjects * blockSize + entry.prev.allocObjects = entry.acc.allocObjects + inuseBytes := entry.acc.inuseObjects * blockSize + + values[0], values[1] = ScaleHeapSample(allocObjects, allocBytes, rate) + values[2], values[3] = ScaleHeapSample(entry.acc.inuseObjects, inuseBytes, rate) + + entry.acc = heapAccValue{} if values[0] == 0 && values[1] == 0 && values[2] == 0 && values[3] == 0 { continue @@ -74,24 +93,20 @@ func (d *DeltaHeapProfiler) WriteHeapProto(w io.Writer, p []runtime.MemProfileRe break } } - locs = b.appendLocsForStack(locs[:0], stk) + locs = b.LocsForStack(stk) if len(locs) > 0 { break } hideRuntime = false // try again, and show all frames next time. } - b.pbSample(values, locs, func() { - if blockSize != 0 { - b.pbLabel(tagSample_Label, "bytes", "", blockSize) - } - }) + b.Sample(values, locs, blockSize) } - b.build() + b.Build() return nil } -// scaleHeapSample adjusts the data from a heap Sample to +// ScaleHeapSample adjusts the data from a heap Sample to // account for its probability of appearing in the collected // data. heap profiles are a sampling of the memory allocations // requests in a program. We estimate the unsampled value by dividing @@ -100,7 +115,7 @@ func (d *DeltaHeapProfiler) WriteHeapProto(w io.Writer, p []runtime.MemProfileRe // which samples to collect, based on the desired average collection // rate R. The probability of a sample of size S to appear in that // profile is 1-exp(-S/R). -func scaleHeapSample(count, size, rate int64) (int64, int64) { +func ScaleHeapSample(count, size, rate int64) (int64, int64) { if count == 0 || size == 0 { return 0, 0 } @@ -116,3 +131,17 @@ func scaleHeapSample(count, size, rate int64) (int64, int64) { return int64(float64(count) * scale), int64(float64(size) * scale) } + +func HeapProfileConfig(rate int64) ProfileConfig { + return ProfileConfig{ + PeriodType: ValueType{Typ: "space", Unit: "bytes"}, + Period: rate, + SampleType: []ValueType{ + {"alloc_objects", "count"}, + {"alloc_space", "bytes"}, + {"inuse_objects", "count"}, + {"inuse_space", "bytes"}, + }, + DefaultSampleType: "", + } +} diff --git a/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/delta_mutex.go b/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/delta_mutex.go index 40ae63ffeb..5c177e3fca 100644 --- a/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/delta_mutex.go +++ b/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/delta_mutex.go @@ -1,14 +1,21 @@ package pprof import ( - "io" "runtime" ) +type mutexPrevValue struct { + count int64 + inanosec int64 +} + +type mutexAccValue struct { + count int64 + cycles int64 +} + type DeltaMutexProfiler struct { - m profMap - mem []memMap - Options ProfileBuilderOptions + m profMap[mutexPrevValue, mutexAccValue] } // PrintCountCycleProfile outputs block profile records (for block or mutex profiles) @@ -16,31 +23,39 @@ type DeltaMutexProfiler struct { // are done because The proto expects count and time (nanoseconds) instead of count // and the number of cycles for block, contention profiles. // Possible 'scaler' functions are scaleBlockProfile and scaleMutexProfile. -func (d *DeltaMutexProfiler) PrintCountCycleProfile(w io.Writer, countName, cycleName string, scaler MutexProfileScaler, records []runtime.BlockProfileRecord) error { - if d.mem == nil || !d.Options.LazyMapping { - d.mem = readMapping() - } - // Output profile in protobuf form. - b := newProfileBuilder(w, d.Options, d.mem) - b.pbValueType(tagProfile_PeriodType, countName, "count") - b.pb.int64Opt(tagProfile_Period, 1) - b.pbValueType(tagProfile_SampleType, countName, "count") - b.pbValueType(tagProfile_SampleType, cycleName, "nanoseconds") +func (d *DeltaMutexProfiler) PrintCountCycleProfile(b ProfileBuilder, scaler MutexProfileScaler, records []runtime.BlockProfileRecord) error { cpuGHz := float64(runtime_cyclesPerSecond()) / 1e9 values := []int64{0, 0} var locs []uint64 - for _, r := range records { - count, nanosec := ScaleMutexProfile(scaler, r.Count, float64(r.Cycles)/cpuGHz) + // deduplicate: accumulate count and cycles in entry.acc for equal stacks + for i := range records { + r := &records[i] + entry := d.m.Lookup(r.Stack(), 0) + entry.acc.count += r.Count // accumulate unscaled + entry.acc.cycles += r.Cycles + } + + // do the delta using the accumulated values and previous values + for i := range records { + r := &records[i] + stk := r.Stack() + entry := d.m.Lookup(stk, 0) + accCount := entry.acc.count + accCycles := entry.acc.cycles + if accCount == 0 && accCycles == 0 { + continue + } + entry.acc = mutexAccValue{} + count, nanosec := ScaleMutexProfile(scaler, accCount, float64(accCycles)/cpuGHz) inanosec := int64(nanosec) // do the delta - entry := d.m.Lookup(r.Stack(), 0) - values[0] = count - entry.count.v1 - values[1] = inanosec - entry.count.v2 - entry.count.v1 = count - entry.count.v2 = inanosec + values[0] = count - entry.prev.count + values[1] = inanosec - entry.prev.inanosec + entry.prev.count = count + entry.prev.inanosec = inanosec if values[0] < 0 || values[1] < 0 { continue @@ -51,9 +66,20 @@ func (d *DeltaMutexProfiler) PrintCountCycleProfile(w io.Writer, countName, cycl // For count profiles, all stack addresses are // return PCs, which is what appendLocsForStack expects. - locs = b.appendLocsForStack(locs[:0], r.Stack()) - b.pbSample(values, locs, nil) + locs = b.LocsForStack(stk) + b.Sample(values, locs, 0) } - b.build() + b.Build() return nil } + +func MutexProfileConfig() ProfileConfig { + return ProfileConfig{ + PeriodType: ValueType{"contentions", "count"}, + Period: 1, + SampleType: []ValueType{ + {"contentions", "count"}, + {"delay", "nanoseconds"}, + }, + } +} diff --git a/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/map.go b/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/map.go index 188001ed16..dcb6e569c8 100644 --- a/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/map.go +++ b/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/map.go @@ -8,30 +8,23 @@ import "unsafe" // A profMap is a map from (stack, tag) to mapEntry. // It grows without bound, but that's assumed to be OK. -type profMap struct { - hash map[uintptr]*profMapEntry - all *profMapEntry - last *profMapEntry - free []profMapEntry +type profMap[PREV any, ACC any] struct { + hash map[uintptr]*profMapEntry[PREV, ACC] + free []profMapEntry[PREV, ACC] freeStk []uintptr } -type count struct { - // alloc_objects, alloc_bytes for heap - // mutex_count, mutex_duration for mutex - v1, v2 int64 -} - // A profMapEntry is a single entry in the profMap. -type profMapEntry struct { - nextHash *profMapEntry // next in hash list - nextAll *profMapEntry // next in list of all entries +// todo use unsafe.Pointer + len for stk ? +type profMapEntry[PREV any, ACC any] struct { + nextHash *profMapEntry[PREV, ACC] // next in hash list stk []uintptr tag uintptr - count count + prev PREV + acc ACC } -func (m *profMap) Lookup(stk []uintptr, tag uintptr) *profMapEntry { +func (m *profMap[PREV, ACC]) Lookup(stk []uintptr, tag uintptr) *profMapEntry[PREV, ACC] { // Compute hash of (stk, tag). h := uintptr(0) for _, x := range stk { @@ -42,7 +35,7 @@ func (m *profMap) Lookup(stk []uintptr, tag uintptr) *profMapEntry { h += uintptr(tag) * 41 // Find entry if present. - var last *profMapEntry + var last *profMapEntry[PREV, ACC] Search: for e := m.hash[h]; e != nil; last, e = e, e.nextHash { if len(e.stk) != len(stk) || e.tag != tag { @@ -64,7 +57,7 @@ Search: // Add new entry. if len(m.free) < 1 { - m.free = make([]profMapEntry, 128) + m.free = make([]profMapEntry[PREV, ACC], 128) } e := &m.free[0] m.free = m.free[1:] @@ -82,15 +75,8 @@ Search: e.stk[j] = uintptr(stk[j]) } if m.hash == nil { - m.hash = make(map[uintptr]*profMapEntry) + m.hash = make(map[uintptr]*profMapEntry[PREV, ACC]) } m.hash[h] = e - if m.all == nil { - m.all = e - m.last = e - } else { - m.last.nextAll = e - m.last = e - } return e } diff --git a/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/proto.go b/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/proto.go index a75dceab18..78246b0fbb 100644 --- a/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/proto.go +++ b/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/proto.go @@ -25,6 +25,14 @@ type ProfileBuilderOptions struct { // pre 1.21 - always use runtime.Frame->Function - produces frames with generic types ommited [...] GenericsFrames bool LazyMapping bool + mem []memMap +} + +func (d *ProfileBuilderOptions) mapping() []memMap { + if d.mem == nil || !d.LazyMapping { + d.mem = readMapping() + } + return d.mem } // A profileBuilder writes a profile incrementally from a @@ -45,8 +53,9 @@ type profileBuilder struct { funcs map[string]int // Package path-qualified function name to Function.ID mem []memMap deck pcDeck + tmplocs []uint64 - opt ProfileBuilderOptions + opt *ProfileBuilderOptions } type memMap struct { @@ -162,13 +171,13 @@ func (b *profileBuilder) pbValueType(tag int, typ, unit string) { b.pb.endMessage(tag, start) } -// pbSample encodes a Sample message to b.pb. -func (b *profileBuilder) pbSample(values []int64, locs []uint64, labels func()) { +// Sample encodes a Sample message to b.pb. +func (b *profileBuilder) Sample(values []int64, locs []uint64, blockSize int64) { start := b.pb.startMessage() b.pb.int64s(tagSample_Value, values) b.pb.uint64s(tagSample_Location, locs) - if labels != nil { - labels() + if blockSize != 0 { + b.pbLabel(tagSample_Label, "bytes", "", blockSize) } b.pb.endMessage(tagProfile_Sample, start) b.flush() @@ -258,11 +267,11 @@ type locInfo struct { firstPCSymbolizeResult symbolizeFlag } -// newProfileBuilder returns a new profileBuilder. +// NewProfileBuilder returns a new profileBuilder. // CPU profiling data obtained from the runtime can be added // by calling b.addCPUData, and then the eventual profile // can be obtained by calling b.finish. -func newProfileBuilder(w io.Writer, opt ProfileBuilderOptions, mapping []memMap) *profileBuilder { +func NewProfileBuilder(w io.Writer, opt *ProfileBuilderOptions, stc ProfileConfig) ProfileBuilder { zw := newGzipWriter(w) b := &profileBuilder{ w: w, @@ -273,13 +282,22 @@ func newProfileBuilder(w io.Writer, opt ProfileBuilderOptions, mapping []memMap) locs: map[uintptr]locInfo{}, funcs: map[string]int{}, opt: opt, + tmplocs: make([]uint64, 0, 128), + } + b.mem = opt.mapping() + b.pbValueType(tagProfile_PeriodType, stc.PeriodType.Typ, stc.PeriodType.Unit) + b.pb.int64Opt(tagProfile_Period, stc.Period) + for _, st := range stc.SampleType { + b.pbValueType(tagProfile_SampleType, st.Typ, st.Unit) + } + if stc.DefaultSampleType != "" { + b.pb.int64Opt(tagProfile_DefaultSampleType, b.stringIndex(stc.DefaultSampleType)) } - b.mem = mapping return b } -// build completes and returns the constructed profile. -func (b *profileBuilder) build() { +// Build completes and returns the constructed profile. +func (b *profileBuilder) Build() { b.end = time.Now() b.pb.int64Opt(tagProfile_TimeNanos, b.start.UnixNano()) @@ -304,7 +322,7 @@ func (b *profileBuilder) build() { b.zw.Close() } -// appendLocsForStack appends the location IDs for the given stack trace to the given +// LocsForStack appends the location IDs for the given stack trace to the given // location ID slice, locs. The addresses in the stack are return PCs or 1 + the PC of // an inline marker as the runtime traceback function returns. // @@ -313,7 +331,8 @@ func (b *profileBuilder) build() { // get the right cumulative sample count. // // It may emit to b.pb, so there must be no message encoding in progress. -func (b *profileBuilder) appendLocsForStack(locs []uint64, stk []uintptr) (newLocs []uint64) { +func (b *profileBuilder) LocsForStack(stk []uintptr) (newLocs []uint64) { + locs := b.tmplocs[:0] b.deck.reset() // The last frame might be truncated. Recover lost inline frames. @@ -474,7 +493,7 @@ func (d *pcDeck) tryAdd(pc uintptr, frames []runtime.Frame, symbolizeResult symb if last.Entry != newFrame.Entry { // newFrame is for a different function. return false } - if last.Function == newFrame.Function { // maybe recursion. + if runtime_FrameSymbolName(&last) == runtime_FrameSymbolName(&newFrame) { // maybe recursion. return false } } @@ -524,13 +543,14 @@ func (b *profileBuilder) emitLocation() uint64 { b.pb.uint64Opt(tagLocation_Address, uint64(firstFrame.PC)) for _, frame := range b.deck.frames { // Write out each line in frame expansion. - funcID := uint64(b.funcs[frame.Function]) + funcName := runtime_FrameSymbolName(&frame) + funcID := uint64(b.funcs[funcName]) if funcID == 0 { funcID = uint64(len(b.funcs)) + 1 - b.funcs[frame.Function] = int(funcID) + b.funcs[funcName] = int(funcID) var name string if b.opt.GenericsFrames { - name = runtime_FrameSymbolName(&frame) + name = funcName } else { name = frame.Function } diff --git a/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/stub.go b/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/stub.go index c617015ecd..5b7d583d1b 100644 --- a/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/stub.go +++ b/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/stub.go @@ -1,17 +1,5 @@ -//go:build go1.16 && !go1.23 -// +build go1.16,!go1.23 - package pprof -// unsafe is required for go:linkname -import _ "unsafe" - -//go:linkname runtime_expandFinalInlineFrame runtime/pprof.runtime_expandFinalInlineFrame -func runtime_expandFinalInlineFrame(stk []uintptr) []uintptr - -//go:linkname runtime_cyclesPerSecond runtime/pprof.runtime_cyclesPerSecond -func runtime_cyclesPerSecond() int64 - func Runtime_cyclesPerSecond() int64 { return runtime_cyclesPerSecond() } diff --git a/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/stub_go20.go b/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/stub_go20.go index d271cbc0ba..7a32846722 100644 --- a/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/stub_go20.go +++ b/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/stub_go20.go @@ -3,7 +3,10 @@ package pprof -import "runtime" +import ( + "runtime" + _ "unsafe" +) // runtime_FrameStartLine is defined in runtime/symtab.go. func runtime_FrameStartLine(f *runtime.Frame) int { @@ -14,3 +17,9 @@ func runtime_FrameStartLine(f *runtime.Frame) int { func runtime_FrameSymbolName(f *runtime.Frame) string { return f.Function } + +//go:linkname runtime_expandFinalInlineFrame runtime/pprof.runtime_expandFinalInlineFrame +func runtime_expandFinalInlineFrame(stk []uintptr) []uintptr + +//go:linkname runtime_cyclesPerSecond runtime/pprof.runtime_cyclesPerSecond +func runtime_cyclesPerSecond() int64 diff --git a/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/stub_go22.go b/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/stub_go22.go new file mode 100644 index 0000000000..02c726faa3 --- /dev/null +++ b/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/stub_go22.go @@ -0,0 +1,27 @@ +//go:build go1.21 && !go1.23 +// +build go1.21,!go1.23 + +package pprof + +import ( + "runtime" + _ "unsafe" +) + +// runtime_FrameStartLine is defined in runtime/symtab.go. +// +//go:noescape +//go:linkname runtime_FrameStartLine runtime/pprof.runtime_FrameStartLine +func runtime_FrameStartLine(f *runtime.Frame) int + +// runtime_FrameSymbolName is defined in runtime/symtab.go. +// +//go:noescape +//go:linkname runtime_FrameSymbolName runtime/pprof.runtime_FrameSymbolName +func runtime_FrameSymbolName(f *runtime.Frame) string + +//go:linkname runtime_expandFinalInlineFrame runtime/pprof.runtime_expandFinalInlineFrame +func runtime_expandFinalInlineFrame(stk []uintptr) []uintptr + +//go:linkname runtime_cyclesPerSecond runtime/pprof.runtime_cyclesPerSecond +func runtime_cyclesPerSecond() int64 diff --git a/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/stub_go21.go b/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/stub_go23.go similarity index 60% rename from vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/stub_go21.go rename to vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/stub_go23.go index 178ce251cb..d587cad75c 100644 --- a/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/stub_go21.go +++ b/vendor/github.com/grafana/pyroscope-go/godeltaprof/internal/pprof/stub_go23.go @@ -1,5 +1,5 @@ -//go:build go1.21 -// +build go1.21 +//go:build go1.23 +// +build go1.23 package pprof @@ -19,3 +19,9 @@ func runtime_FrameStartLine(f *runtime.Frame) int //go:noescape //go:linkname runtime_FrameSymbolName runtime/pprof.runtime_FrameSymbolName func runtime_FrameSymbolName(f *runtime.Frame) string + +//go:linkname runtime_expandFinalInlineFrame runtime/pprof.runtime_expandFinalInlineFrame +func runtime_expandFinalInlineFrame(stk []uintptr) []uintptr + +//go:linkname runtime_cyclesPerSecond runtime/pprof.runtime_cyclesPerSecond +func runtime_cyclesPerSecond() int64 diff --git a/vendor/github.com/grafana/pyroscope-go/upstream/remote/remote.go b/vendor/github.com/grafana/pyroscope-go/upstream/remote/remote.go index 33b81d7f21..287ff75954 100644 --- a/vendor/github.com/grafana/pyroscope-go/upstream/remote/remote.go +++ b/vendor/github.com/grafana/pyroscope-go/upstream/remote/remote.go @@ -26,7 +26,7 @@ const cloudHostnameSuffix = "pyroscope.cloud" type Remote struct { cfg Config jobs chan *upstream.UploadJob - client *http.Client + client HTTPClient logger Logger done chan struct{} @@ -35,6 +35,10 @@ type Remote struct { flushWG sync.WaitGroup } +type HTTPClient interface { + Do(req *http.Request) (*http.Response, error) +} + type Config struct { AuthToken string BasicAuthUser string // http basic auth user @@ -45,6 +49,7 @@ type Config struct { Address string Timeout time.Duration Logger Logger + HTTPClient HTTPClient // optional, custom client } type Logger interface { @@ -74,6 +79,9 @@ func NewRemote(cfg Config) (*Remote, error) { logger: cfg.Logger, done: make(chan struct{}), } + if cfg.HTTPClient != nil { + r.client = cfg.HTTPClient + } // parse the upstream address u, err := url.Parse(cfg.Address) diff --git a/vendor/github.com/klauspost/compress/flate/deflate.go b/vendor/github.com/klauspost/compress/flate/deflate.go index de912e187c..66d1657d2c 100644 --- a/vendor/github.com/klauspost/compress/flate/deflate.go +++ b/vendor/github.com/klauspost/compress/flate/deflate.go @@ -212,7 +212,7 @@ func (d *compressor) writeBlockSkip(tok *tokens, index int, eof bool) error { // Should only be used after a start/reset. func (d *compressor) fillWindow(b []byte) { // Do not fill window if we are in store-only or huffman mode. - if d.level <= 0 { + if d.level <= 0 && d.level > -MinCustomWindowSize { return } if d.fast != nil { diff --git a/vendor/github.com/klauspost/compress/gzip/gunzip.go b/vendor/github.com/klauspost/compress/gzip/gunzip.go index dc2362a63b..00a0a2c386 100644 --- a/vendor/github.com/klauspost/compress/gzip/gunzip.go +++ b/vendor/github.com/klauspost/compress/gzip/gunzip.go @@ -238,6 +238,11 @@ func (z *Reader) readHeader() (hdr Header, err error) { } } + // Reserved FLG bits must be zero. + if flg>>5 != 0 { + return hdr, ErrHeader + } + z.digest = 0 if z.decompressor == nil { z.decompressor = flate.NewReader(z.r) diff --git a/vendor/modules.txt b/vendor/modules.txt index db506d07e1..57e75de1db 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -285,7 +285,7 @@ github.com/google/uuid # github.com/gorilla/handlers v1.5.1 ## explicit; go 1.14 github.com/gorilla/handlers -# github.com/grafana/pyroscope-go v1.1.1 +# github.com/grafana/pyroscope-go v1.1.2 ## explicit; go 1.17 github.com/grafana/pyroscope-go github.com/grafana/pyroscope-go/internal/flameql @@ -293,8 +293,8 @@ github.com/grafana/pyroscope-go/internal/pprof github.com/grafana/pyroscope-go/internal/sortedmap github.com/grafana/pyroscope-go/upstream github.com/grafana/pyroscope-go/upstream/remote -# github.com/grafana/pyroscope-go/godeltaprof v0.1.6 -## explicit; go 1.16 +# github.com/grafana/pyroscope-go/godeltaprof v0.1.8 +## explicit; go 1.18 github.com/grafana/pyroscope-go/godeltaprof github.com/grafana/pyroscope-go/godeltaprof/internal/pprof # github.com/hashicorp/errwrap v1.1.0 @@ -345,8 +345,8 @@ github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils ## explicit; go 1.20 github.com/kdoctor-io/kdoctor/pkg/k8s/apis/kdoctor.io/v1beta1 github.com/kdoctor-io/kdoctor/pkg/utils/string -# github.com/klauspost/compress v1.17.3 -## explicit; go 1.19 +# github.com/klauspost/compress v1.17.8 +## explicit; go 1.20 github.com/klauspost/compress/flate github.com/klauspost/compress/gzip # github.com/kr/pretty v0.3.1