Skip to content

Commit

Permalink
Merge pull request #1209 from j75689/metrics/build-info
Browse files Browse the repository at this point in the history
metrics: add build info into metrics server
  • Loading branch information
j75689 authored Nov 29, 2022
2 parents 807d52e + fe5682c commit ef16f9e
Show file tree
Hide file tree
Showing 10 changed files with 173 additions and 25 deletions.
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

0 comments on commit ef16f9e

Please sign in to comment.