diff --git a/.github/workflows/build_and_release_pprof_image.yaml b/.github/workflows/build_and_release_pprof_image.yaml new file mode 100644 index 0000000..1f9edd8 --- /dev/null +++ b/.github/workflows/build_and_release_pprof_image.yaml @@ -0,0 +1,13 @@ +name: Build and Publish PProf Enabled Docker Images +on: + - push # Perform a build of the contents from the branch + - pull_request # Perform a build after merging with the target branch + - workflow_dispatch +jobs: + build_and_release: + uses: Cray-HPE/hms-build-image-workflows/.github/workflows/build_and_release_image.yaml@v2 + with: + image-name: hms-hmcollector-pprof + docker-build-file: Dockerfile.pprof + enable-pr-comment: true + secrets: inherit diff --git a/.version b/.version index dc15918..aa5388f 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -2.34.0 +2.35.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 79ccdac..0f045a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,12 @@ Fixed - for any bug fixes Security - in case of vulnerabilities --> +## [2.35.0] - 2025-01-08 + +### Added + +- Added support for ppprof builds + ## [2.34.0] - 2024-12-06 ### Fixed diff --git a/Dockerfile.pprof b/Dockerfile.pprof new file mode 100644 index 0000000..303fc03 --- /dev/null +++ b/Dockerfile.pprof @@ -0,0 +1,94 @@ +# MIT License +# +# (C) Copyright [2019-2022,2024-2025] Hewlett Packard Enterprise Development LP +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +# Dockerfile for building HMS Redfish Collector with pprof support. +# The only difference from primary dockerfile is building with the pprof tag + +# v1.1.0 of Confluent Go Kafka requires at least v1.1.0 of librdkafka. +ARG LIBRDKAFKA_VER_MIN=1.1.0 + +# Build base just has the packages installed we need. +FROM artifactory.algol60.net/docker.io/library/golang:1.23-alpine AS build-base + +ARG LIBRDKAFKA_VER_MIN + +RUN set -ex \ + && apk -U upgrade \ + && apk add --no-cache \ + build-base \ + "librdkafka-dev>${LIBRDKAFKA_VER_MIN}" \ + pkgconf + +# Base copies in the files we need to test/build. +FROM build-base AS base + +RUN go env -w GO111MODULE=auto + +# Copy all the necessary files to the image. +COPY cmd $GOPATH/src/github.com/Cray-HPE/hms-hmcollector/cmd +COPY internal $GOPATH/src/github.com/Cray-HPE/hms-hmcollector/internal +COPY vendor $GOPATH/src/github.com/Cray-HPE/hms-hmcollector/vendor + +### Build Stage ### +FROM base AS builder + +RUN set -ex && go build -v -tags pprof -o /usr/local/bin/hmcollector github.com/Cray-HPE/hms-hmcollector/cmd/hmcollector + +## Final Stage ### + +FROM artifactory.algol60.net/docker.io/alpine:3.15 +LABEL maintainer="Hewlett Packard Enterprise" +EXPOSE 80 + +ARG LIBRDKAFKA_VER_MIN + +COPY --from=builder /usr/local/bin/hmcollector /usr/local/bin + +RUN set -ex \ + && apk -U upgrade \ + && apk add --no-cache \ + "librdkafka-dev>${LIBRDKAFKA_VER_MIN}" \ + pkgconf \ + curl \ + libcap \ + iputils \ + && setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/hmcollector + + +ENV LOG_LEVEL=info +ENV POLLING_ENABLED=false +ENV RF_SUBSCRIBE_ENABLED=false +ENV REST_ENABLED=true +ENV KAFKA_HOST=localhost +ENV KAFKA_PORT=9092 +ENV POLLING_INTERVAL=1 +ENV PDU_POLLING_INTERVAL=30 +ENV PRUNE_OLD_SUBSCRIPTIONS=true +ENV HSM_REFRESH_INTERVAL=30 +ENV SM_URL=https://cray-smd +ENV REST_URL=localhost +ENV REST_PORT=80 + +# nobody 65534:65534 +USER 65534:65534 + +CMD ["sh", "-c", "hmcollector"] diff --git a/cmd/hmcollector/rest.go b/cmd/hmcollector/rest.go index ef893b2..f293882 100644 --- a/cmd/hmcollector/rest.go +++ b/cmd/hmcollector/rest.go @@ -1,6 +1,6 @@ // MIT License // -// (C) Copyright [2020-2024] Hewlett Packard Enterprise Development LP +// (C) Copyright [2020-2025] Hewlett Packard Enterprise Development LP // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -347,6 +347,10 @@ func doRest() { // Health function for Kubernetes liveness/readiness. http.HandleFunc("/health", doHealth) + // If the 'pprof' build tag is set, then this will register pprof handlers, + // otherwise this function is stubbed and will do nothing. + hmcollector.RegisterPProfHandlers() + go func() { defer WaitGroup.Done() err := srv.ListenAndServe() diff --git a/internal/hmcollector/pprof.go b/internal/hmcollector/pprof.go new file mode 100644 index 0000000..1b7676b --- /dev/null +++ b/internal/hmcollector/pprof.go @@ -0,0 +1,53 @@ +// This file contains the code to enable pprof profiling. It is only +// included in the build when the 'pprof' build tag is set in the Dockerfile. +// +//go:build pprof + +/* + * (C) Copyright [2025] Hewlett Packard Enterprise Development LP + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package hmcollector + +import ( + "net/http" + "net/http/pprof" + _ "net/http/pprof" +) + +func RegisterPProfHandlers() { + // Main profiling entry point + http.HandleFunc("/debug/pprof/", pprof.Index) // Index listing all pprof endpoints + + // Specific profiling handlers + http.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) // Command-line arguments + http.HandleFunc("/debug/pprof/profile", pprof.Profile) // CPU profile (default: 30 seconds) + http.HandleFunc("/debug/pprof/symbol", pprof.Symbol) // Symbol resolution for addresses + http.HandleFunc("/debug/pprof/trace", pprof.Trace) // Execution trace (default: 1 second) + + // Additional profiling endpoints + http.Handle("/debug/pprof/allocs", pprof.Handler("allocs")) // Heap allocation samples + http.Handle("/debug/pprof/block", pprof.Handler("block")) // Goroutine blocking events + http.Handle("/debug/pprof/goroutine", pprof.Handler("goroutine")) // Stack traces of all goroutines + http.Handle("/debug/pprof/heap", pprof.Handler("heap")) // Memory heap profile + http.Handle("/debug/pprof/mutex", pprof.Handler("mutex")) // Mutex contention profile + http.Handle("/debug/pprof/threadcreate", pprof.Handler("threadcreate")) // Stack traces of thread creation +} diff --git a/internal/hmcollector/pprof_stub.go b/internal/hmcollector/pprof_stub.go new file mode 100644 index 0000000..5b43828 --- /dev/null +++ b/internal/hmcollector/pprof_stub.go @@ -0,0 +1,31 @@ +// This file contains a stub implementation of the RegisterPProfHandlers() +// function which is a noop.  It is included in the build by default by +// way of the 'pprof' build tag not being set in the Dockerfile. +// +//go:build !pprof + +/* + * (C) Copyright [2025] Hewlett Packard Enterprise Development LP + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package hmcollector + +func RegisterPProfHandlers() { } \ No newline at end of file