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

metrics: add build info into metrics server #1209

Merged
merged 4 commits into from
Nov 29, 2022
Merged
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
14 changes: 5 additions & 9 deletions .github/workflows/pre-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,8 @@ jobs:

- name: Build Binary for ARM
if: matrix.os == 'ubuntu-18.04'
env:
GOPATH: /home/runner/work/woodpecker/go
run: |
mkdir -p $GOPATH/src/github.com/bnb-chain/bsc/
cp -r ./* $GOPATH/src/github.com/bnb-chain/bsc/
cd $GOPATH/src/github.com/bnb-chain/bsc/ && make geth-linux-arm
make geth-linux-arm
# ==============================
# Upload artifacts
# ==============================
Expand Down Expand Up @@ -86,28 +82,28 @@ jobs:
if: matrix.os == 'ubuntu-18.04'
with:
name: arm5
path: /home/runner/work/woodpecker/go/src/github.com/bnb-chain/bsc/build/bin/geth-linux-arm-5
path: ./build/bin/geth-linux-arm-5

- name: Upload ARM-6 Build
uses: actions/upload-artifact@v2
if: matrix.os == 'ubuntu-18.04'
with:
name: arm6
path: /home/runner/work/woodpecker/go/src/github.com/bnb-chain/bsc/build/bin/geth-linux-arm-6
path: ./build/bin/geth-linux-arm-6

- name: Upload ARM-7 Build
uses: actions/upload-artifact@v2
if: matrix.os == 'ubuntu-18.04'
with:
name: arm7
path: /home/runner/work/woodpecker/go/src/github.com/bnb-chain/bsc/build/bin/geth-linux-arm-7
path: ./build/bin/geth-linux-arm-7

- name: Upload ARM-64 Build
uses: actions/upload-artifact@v2
if: matrix.os == 'ubuntu-18.04'
with:
name: arm64
path: /home/runner/work/woodpecker/go/src/github.com/bnb-chain/bsc/build/bin/geth-linux-arm64
path: ./build/bin/geth-linux-arm64

release:
name: Release
Expand Down
14 changes: 5 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,8 @@ jobs:

- name: Build Binary for ARM
if: matrix.os == 'ubuntu-18.04'
env:
GOPATH: /home/runner/work/woodpecker/go
run: |
mkdir -p $GOPATH/src/github.com/bnb-chain/bsc/
cp -r ./* $GOPATH/src/github.com/bnb-chain/bsc/
cd $GOPATH/src/github.com/bnb-chain/bsc/ && make geth-linux-arm
make geth-linux-arm
# ==============================
# Upload artifacts
# ==============================
Expand Down Expand Up @@ -87,28 +83,28 @@ jobs:
if: matrix.os == 'ubuntu-18.04'
with:
name: arm5
path: /home/runner/work/woodpecker/go/src/github.com/bnb-chain/bsc/build/bin/geth-linux-arm-5
path: ./build/bin/geth-linux-arm-5

- name: Upload ARM-6 Build
uses: actions/upload-artifact@v2
if: matrix.os == 'ubuntu-18.04'
with:
name: arm6
path: /home/runner/work/woodpecker/go/src/github.com/bnb-chain/bsc/build/bin/geth-linux-arm-6
path: ./build/bin/geth-linux-arm-6

- name: Upload ARM-7 Build
uses: actions/upload-artifact@v2
if: matrix.os == 'ubuntu-18.04'
with:
name: arm7
path: /home/runner/work/woodpecker/go/src/github.com/bnb-chain/bsc/build/bin/geth-linux-arm-7
path: ./build/bin/geth-linux-arm-7

- name: Upload ARM-64 Build
uses: actions/upload-artifact@v2
if: matrix.os == 'ubuntu-18.04'
with:
name: arm64
path: /home/runner/work/woodpecker/go/src/github.com/bnb-chain/bsc/build/bin/geth-linux-arm64
path: ./build/bin/geth-linux-arm64

release:
name: Release
Expand Down
13 changes: 9 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,30 @@
GOBIN = ./build/bin
GO ?= latest
GORUN = env GO111MODULE=on go run
GIT_COMMIT=$(shell git rev-parse HEAD)
GIT_COMMIT_DATE=$(shell git log -n1 --pretty='format:%cd' --date=format:'%Y%m%d')

geth:
$(GORUN) build/ci.go install ./cmd/geth
@echo "Done building."
@echo "Run \"$(GOBIN)/geth\" to launch geth."

ldflags = -X main.gitCommit=$(GIT_COMMIT) \
-X main.gitDate=$(GIT_COMMIT_DATE)

geth-linux-arm: geth-linux-arm5 geth-linux-arm6 geth-linux-arm7 geth-linux-arm64

geth-linux-arm5:
env GO111MODULE=on GOARCH=arm GOARM=5 GOOS=linux go build -o build/bin/geth-linux-arm-5 ./cmd/geth
env GO111MODULE=on GOARCH=arm GOARM=5 GOOS=linux go build -ldflags="$(ldflags)" -o build/bin/geth-linux-arm-5 ./cmd/geth

geth-linux-arm6:
env GO111MODULE=on GOARCH=arm GOARM=6 GOOS=linux go build -o build/bin/geth-linux-arm-6 ./cmd/geth
env GO111MODULE=on GOARCH=arm GOARM=6 GOOS=linux go build -ldflags="$(ldflags)" -o build/bin/geth-linux-arm-6 ./cmd/geth

geth-linux-arm7:
env GO111MODULE=on GOARCH=arm GOARM=7 GOOS=linux go build -o build/bin/geth-linux-arm-7 ./cmd/geth
env GO111MODULE=on GOARCH=arm GOARM=7 GOOS=linux go build -ldflags="$(ldflags)" -o build/bin/geth-linux-arm-7 ./cmd/geth

geth-linux-arm64:
env GO111MODULE=on GOARCH=arm64 GOOS=linux go build -o build/bin/geth-linux-arm64 ./cmd/geth
env GO111MODULE=on GOARCH=arm64 GOOS=linux go build -ldflags="$(ldflags)" -o build/bin/geth-linux-arm64 ./cmd/geth

all:
$(GORUN) build/ci.go install
Expand Down
2 changes: 1 addition & 1 deletion cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ func prepare(ctx *cli.Context) {
}

// Start metrics export if enabled
utils.SetupMetrics(ctx)
utils.SetupMetrics(ctx, utils.EnableBuildInfo(gitCommit, gitDate))

// Start system runtime metrics collection
go metrics.CollectProcessMetrics(3 * time.Second)
Expand Down
23 changes: 22 additions & 1 deletion cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"math/big"
"os"
"path/filepath"
"runtime"
godebug "runtime/debug"
"strconv"
"strings"
Expand Down Expand Up @@ -1931,7 +1932,23 @@ func RegisterGraphQLService(stack *node.Node, backend ethapi.Backend, cfg node.C
}
}

func SetupMetrics(ctx *cli.Context) {
type SetupMetricsOption func()

func EnableBuildInfo(gitCommit, gitDate string) SetupMetricsOption {
return func() {
// register build info into metrics
metrics.NewRegisteredLabel("build-info", nil).Mark(map[string]interface{}{
"version": params.VersionWithMeta,
"git-commit": gitCommit,
"git-commit-date": gitDate,
"go-version": runtime.Version(),
"operating-system": runtime.GOOS,
"architecture": runtime.GOARCH,
})
}
}

func SetupMetrics(ctx *cli.Context, options ...SetupMetricsOption) {
if metrics.Enabled {
log.Info("Enabling metrics collection")

Expand Down Expand Up @@ -1987,6 +2004,10 @@ func SetupMetrics(ctx *cli.Context) {
log.Info("Enabling stand-alone metrics HTTP endpoint", "address", address)
exp.Setup(address)
}

for _, opt := range options {
opt()
}
}
}

Expand Down
70 changes: 70 additions & 0 deletions metrics/exp/exp.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,20 @@ func (exp *exp) getFloat(name string) *expvar.Float {
return v
}

func (exp *exp) getMap(name string) *expvar.Map {
var v *expvar.Map
exp.expvarLock.Lock()
p := expvar.Get(name)
if p != nil {
v = p.(*expvar.Map)
} else {
v = new(expvar.Map)
expvar.Publish(name, v)
}
exp.expvarLock.Unlock()
return v
}

func (exp *exp) publishCounter(name string, metric metrics.Counter) {
v := exp.getInt(name)
v.Set(metric.Count())
Expand Down Expand Up @@ -162,6 +176,60 @@ func (exp *exp) publishResettingTimer(name string, metric metrics.ResettingTimer
exp.getInt(name + ".99-percentile").Set(ps[3])
}

func (exp *exp) publishLabel(name string, metric metrics.Label) {
labels := metric.Value()
for k, v := range labels {
exp.getMap(name).Set(k, exp.interfaceToExpVal(v))
}
}

func (exp *exp) interfaceToExpVal(v interface{}) expvar.Var {
switch i := v.(type) {
case string:
newV := new(expvar.String)
newV.Set(i)
return newV
case int64:
newV := new(expvar.Int)
newV.Set(i)
return newV
case int32:
newV := new(expvar.Int)
newV.Set(int64(i))
return newV
case int16:
newV := new(expvar.Int)
newV.Set(int64(i))
return newV
case int8:
newV := new(expvar.Int)
newV.Set(int64(i))
return newV
case int:
newV := new(expvar.Int)
newV.Set(int64(i))
return newV
case float32:
newV := new(expvar.Float)
newV.Set(float64(i))
return newV
case float64:
newV := new(expvar.Float)
newV.Set(i)
return newV
case map[string]interface{}:
newV := new(expvar.Map)
for k, v := range i {
newV.Set(k, exp.interfaceToExpVal(v))
}
return newV
default:
newV := new(expvar.String)
newV.Set(fmt.Sprint(v))
return newV
}
}

func (exp *exp) syncToExpvar() {
exp.registry.Each(func(name string, i interface{}) {
switch i := i.(type) {
Expand All @@ -179,6 +247,8 @@ func (exp *exp) syncToExpvar() {
exp.publishTimer(name, i)
case metrics.ResettingTimer:
exp.publishResettingTimer(name, i)
case metrics.Label:
exp.publishLabel(name, i)
default:
panic(fmt.Sprintf("unsupported type for '%s': %T", name, i))
}
Expand Down
48 changes: 48 additions & 0 deletions metrics/label.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package metrics

import "encoding/json"

// Label hold an map[string]interface{} value that can be set arbitrarily.
type Label interface {
Value() map[string]interface{}
String() string
Mark(map[string]interface{})
}

// NewRegisteredLabel constructs and registers a new StandardLabel.
func NewRegisteredLabel(name string, r Registry) Label {
c := NewStandardLabel()
if nil == r {
r = DefaultRegistry
}
r.Register(name, c)
return c
}

// NewStandardLabel constructs a new StandardLabel.
func NewStandardLabel() *StandardLabel {
return &StandardLabel{}
}

// StandardLabel is the standard implementation of a Label.
type StandardLabel struct {
value map[string]interface{}
jsonStr string
}

// Value returns label values.
func (l *StandardLabel) Value() map[string]interface{} {
return l.value
}

// Mark records the label.
func (l *StandardLabel) Mark(value map[string]interface{}) {
buf, _ := json.Marshal(value)
l.jsonStr = string(buf)
l.value = value
}

// String returns label by JSON format.
func (l *StandardLabel) String() string {
return l.jsonStr
}
10 changes: 10 additions & 0 deletions metrics/prometheus/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ var (
typeSummaryTpl = "# TYPE %s summary\n"
keyValueTpl = "%s %v\n\n"
keyQuantileTagValueTpl = "%s {quantile=\"%s\"} %v\n"
keyLabelValueTpl = "%s%s %v\n\n"
)

// collector is a collection of byte buffers that aggregate Prometheus reports
Expand Down Expand Up @@ -98,6 +99,15 @@ func (c *collector) addResettingTimer(name string, m metrics.ResettingTimer) {
c.buff.WriteRune('\n')
}

func (c *collector) addLabel(name string, m metrics.Label) {
c.writeLabel(mutateKey(name), m.String())
}

func (c *collector) writeLabel(name string, value interface{}) {
c.buff.WriteString(fmt.Sprintf(typeGaugeTpl, name))
c.buff.WriteString(fmt.Sprintf(keyLabelValueTpl, name, value, 1))
}

func (c *collector) writeGaugeCounter(name string, value interface{}) {
name = mutateKey(name)
c.buff.WriteString(fmt.Sprintf(typeGaugeTpl, name))
Expand Down
2 changes: 2 additions & 0 deletions metrics/prometheus/prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ func Handler(reg metrics.Registry) http.Handler {
c.addTimer(name, m.Snapshot())
case metrics.ResettingTimer:
c.addResettingTimer(name, m.Snapshot())
case metrics.Label:
c.addLabel(name, m)
default:
log.Warn("Unknown Prometheus metric type", "type", fmt.Sprintf("%T", i))
}
Expand Down
2 changes: 1 addition & 1 deletion metrics/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ func (r *StandardRegistry) register(name string, i interface{}) error {
return DuplicateMetric(name)
}
switch i.(type) {
case Counter, Gauge, GaugeFloat64, Healthcheck, Histogram, Meter, Timer, ResettingTimer:
case Counter, Gauge, GaugeFloat64, Healthcheck, Histogram, Meter, Timer, ResettingTimer, Label:
r.metrics[name] = i
}
return nil
Expand Down