Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add operator build_info metrics and go runtime metrics #6044

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
2 changes: 2 additions & 0 deletions hack/util.sh
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,7 @@ function util::get_version() {
function util::version_ldflags() {
# Git information
GIT_VERSION=$(util::get_version)
GIT_ABBREVIATIVE_COMMIT=$(git rev-parse --short HEAD)
GIT_COMMIT_HASH=$(git rev-parse HEAD)
if git_status=$(git status --porcelain 2>/dev/null) && [[ -z ${git_status} ]]; then
GIT_TREESTATE="clean"
Expand All @@ -720,6 +721,7 @@ function util::version_ldflags() {
LDFLAGS="-X github.com/karmada-io/karmada/pkg/version.gitVersion=${GIT_VERSION} \
-X github.com/karmada-io/karmada/pkg/version.gitCommit=${GIT_COMMIT_HASH} \
-X github.com/karmada-io/karmada/pkg/version.gitTreeState=${GIT_TREESTATE} \
-X github.com/karmada-io/karmada/pkg/version.gitAbbreviativeCommit=${GIT_ABBREVIATIVE_COMMIT} \
-X github.com/karmada-io/karmada/pkg/version.buildDate=${BUILDDATE}"
echo $LDFLAGS
}
Expand Down
31 changes: 31 additions & 0 deletions operator/cmd/operator/app/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ import (
"flag"
"fmt"
"os"
"regexp"

"github.com/prometheus/client_golang/prometheus/collectors"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/util/sets"
restclient "k8s.io/client-go/rest"
Expand All @@ -32,6 +34,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/config"
"sigs.k8s.io/controller-runtime/pkg/healthz"
ctrlmetrics "sigs.k8s.io/controller-runtime/pkg/metrics"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"

"github.com/karmada-io/karmada/operator/cmd/operator/app/options"
Expand Down Expand Up @@ -110,6 +113,34 @@ func Run(ctx context.Context, o *options.Options) error {
return err
}

// Unregister default NewGoCollector
ctrlmetrics.Registry.Unregister(collectors.NewGoCollector())

ctrlmetrics.Registry.MustRegister(
// Go Runtime metrics about debug.GCStats (base metrics) and
// runtime/metrics.
collectors.NewGoCollector(
collectors.WithGoCollectorRuntimeMetrics(
// go runtime gc metrics. (e.g. `go_gc_duration_seconds`
// means garbage collection cycle pause duration)
collectors.MetricsGC,
// go runtime scheduler metrics. (e.g. `go_sched_gomaxprocs_threads`
// means the current runtime.GOMAXPROCS setting)
collectors.MetricsScheduler,
// go runtime memory metrics. (e.g. `go_memstats_alloc_bytes`
// means number of bytes allocated and still in use)
collectors.MetricsMemory,
// go runtime sync lock metrics. (e.g. `go_sync_mutex_wait_total_seconds_total`
// means Approximate cumulative time goroutines have spent blocked on a sync.Mutex, sync.RWMutex, or runtime-internal lock)
collectors.GoRuntimeMetricsRule{Matcher: regexp.MustCompile(`^/sync/.*`)},
),
),
)
// `karmada_operator_build_info` metrics for operator version upgrade
ctrlmetrics.Registry.MustRegister(
version.NewCollector("karmada_operator"),
)

controllerCtx := ctrlctx.Context{
Controllers: o.Controllers,
Manager: manager,
Expand Down
7 changes: 4 additions & 3 deletions pkg/version/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ package version
// version for ad-hoc builds (e.g. `go build`) that cannot get the version
// information from git.
var (
gitVersion = "v0.0.0-master"
gitCommit = "unknown" // sha1 from git, output of $(git rev-parse HEAD)
gitTreeState = "unknown" // state of git tree, either "clean" or "dirty"
gitVersion = "v0.0.0-master"
gitCommit = "unknown" // sha1 from git, output of $(git rev-parse HEAD)
gitTreeState = "unknown" // state of git tree, either "clean" or "dirty"
gitAbbreviativeCommit = "unknown" // short sha1 from git, output of $(git rev-parse --short HEAD)

buildDate = "unknown" // build date in ISO8601 format, output of $(date -u +'%Y-%m-%dT%H:%M:%SZ')
)
57 changes: 43 additions & 14 deletions pkg/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,20 @@ package version
import (
"fmt"
"runtime"

"github.com/prometheus/client_golang/prometheus"
)

// Info contains versioning information.
type Info struct {
GitVersion string `json:"gitVersion"`
GitCommit string `json:"gitCommit"`
GitTreeState string `json:"gitTreeState"`
BuildDate string `json:"buildDate"`
GoVersion string `json:"goVersion"`
Compiler string `json:"compiler"`
Platform string `json:"platform"`
GitVersion string `json:"gitVersion"`
GitCommit string `json:"gitCommit"`
GitAbbreviativeCommit string `json:"gitAbbreviativeCommit"`
GitTreeState string `json:"gitTreeState"`
BuildDate string `json:"buildDate"`
GoVersion string `json:"goVersion"`
Compiler string `json:"compiler"`
Platform string `json:"platform"`
}

// String returns a Go-syntax representation of the Info.
Expand All @@ -41,12 +44,38 @@ func (info Info) String() string {
// what code a binary was built from.
func Get() Info {
return Info{
GitVersion: gitVersion,
GitCommit: gitCommit,
GitTreeState: gitTreeState,
BuildDate: buildDate,
GoVersion: runtime.Version(),
Compiler: runtime.Compiler,
Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH),
GitVersion: gitVersion,
GitAbbreviativeCommit: gitAbbreviativeCommit,
GitCommit: gitCommit,
GitTreeState: gitTreeState,
BuildDate: buildDate,
GoVersion: runtime.Version(),
Compiler: runtime.Compiler,
Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH),
}
}

// NewCollector returns a collector that exports metrics about current version
// information.
func NewCollector(program string) prometheus.Collector {
return prometheus.NewGaugeFunc(
prometheus.GaugeOpts{
Namespace: program,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can omit the component name?
Because the metric emitted from a component indicates it's build info.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The metrcs specification defines different metrics names, and is not distinguished by different tags of the same metrics name.
ref: https://github.com/prometheus/client_golang/blob/main/prometheus/collectors/version/version.go#L28-L30

Name: "build_info",
Help: fmt.Sprintf(
"A metric with a constant '1' value labeled by version, revision, branch, goversion from which %s was built, and the goos and goarch for the build.",
program,
),
ConstLabels: prometheus.Labels{
"version": Get().GitVersion,
"revision": Get().GitAbbreviativeCommit,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"revision": Get().GitAbbreviativeCommit,
"commit": Get().GitCommit,
"abbr-commit": Get().GitAbbreviativeCommit,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmmm....🤔 @RainbowMango Probably best to stay consistent with prometheus's specification.

Ref: https://github.com/prometheus/client_golang/blob/main/prometheus/collectors/version/version.go#L35-L42

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I apologize for not explaining why I suggested those changes.
I think the most important aspect of naming is clarity, and I feel the terms version and reversion are ambiguous, which could lead to misunderstandings. For example, I can't tell their difference in the context of Prometheus. (Can you give an example of the build info metric from Prometheus?)

Regarding your point about maintaining consistency with Prometheus, I'd love to, but Karmada might emit both commit and abbreviate commit, we should differentiate them in terms of naming to avoid confusion.

"goversion": runtime.Version(),
"goos": runtime.GOOS,
"goarch": runtime.GOARCH,
"compiler": runtime.Compiler,
"platform": fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH),
},
},
func() float64 { return 1 },
)
}
17 changes: 9 additions & 8 deletions pkg/version/version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,16 @@ func TestInfo_String(t *testing.T) {
{
name: "test1",
info: Info{
GitVersion: "1.3.0",
GitCommit: "da070e68f3318410c8c70ed8186a2bc4736dacbd",
GitTreeState: "clean",
BuildDate: "2022-08-31T13:09:22Z",
GoVersion: "go1.18.3",
Compiler: "gc",
Platform: "linux/amd64",
GitVersion: "1.3.0",
GitCommit: "da070e68f3318410c8c70ed8186a2bc4736dacbd",
GitTreeState: "clean",
GitAbbreviativeCommit: "851c78564",
BuildDate: "2022-08-31T13:09:22Z",
GoVersion: "go1.18.3",
Compiler: "gc",
Platform: "linux/amd64",
},
want: `version.Info{GitVersion:"1.3.0", GitCommit:"da070e68f3318410c8c70ed8186a2bc4736dacbd", GitTreeState:"clean", BuildDate:"2022-08-31T13:09:22Z", GoVersion:"go1.18.3", Compiler:"gc", Platform:"linux/amd64"}`,
want: `version.Info{GitVersion:"1.3.0", GitCommit:"da070e68f3318410c8c70ed8186a2bc4736dacbd", GitAbbreviativeCommit:"851c78564", GitTreeState:"clean", BuildDate:"2022-08-31T13:09:22Z", GoVersion:"go1.18.3", Compiler:"gc", Platform:"linux/amd64"}`,
},
}
for _, tt := range tests {
Expand Down