Skip to content

Commit 1990c9e

Browse files
nonsensekaralabe
authored andcommitted
cmd/geth: export metrics to InfluxDB (#16979)
* cmd/geth: add flags for metrics export * cmd/geth: update usage fields for metrics flags * metrics/influxdb: update reporter logger to adhere to geth logging convention
1 parent 223d943 commit 1990c9e

File tree

4 files changed

+93
-11
lines changed

4 files changed

+93
-11
lines changed

cmd/geth/main.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,15 @@ var (
144144
utils.WhisperMaxMessageSizeFlag,
145145
utils.WhisperMinPOWFlag,
146146
}
147+
148+
metricsFlags = []cli.Flag{
149+
utils.MetricsEnableInfluxDBFlag,
150+
utils.MetricsInfluxDBEndpointFlag,
151+
utils.MetricsInfluxDBDatabaseFlag,
152+
utils.MetricsInfluxDBUsernameFlag,
153+
utils.MetricsInfluxDBPasswordFlag,
154+
utils.MetricsInfluxDBHostTagFlag,
155+
}
147156
)
148157

149158
func init() {
@@ -186,6 +195,7 @@ func init() {
186195
app.Flags = append(app.Flags, consoleFlags...)
187196
app.Flags = append(app.Flags, debug.Flags...)
188197
app.Flags = append(app.Flags, whisperFlags...)
198+
app.Flags = append(app.Flags, metricsFlags...)
189199

190200
app.Before = func(ctx *cli.Context) error {
191201
runtime.GOMAXPROCS(runtime.NumCPU())
@@ -208,6 +218,9 @@ func init() {
208218
log.Debug("Sanitizing Go's GC trigger", "percent", int(gogc))
209219
godebug.SetGCPercent(int(gogc))
210220

221+
// Start metrics export if enabled
222+
utils.SetupMetrics(ctx)
223+
211224
// Start system runtime metrics collection
212225
go metrics.CollectProcessMetrics(3 * time.Second)
213226

cmd/geth/usage.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,22 @@ var AppHelpFlagGroups = []flagGroup{
206206
{
207207
Name: "LOGGING AND DEBUGGING",
208208
Flags: append([]cli.Flag{
209-
utils.MetricsEnabledFlag,
210209
utils.FakePoWFlag,
211210
utils.NoCompactionFlag,
212211
}, debug.Flags...),
213212
},
213+
{
214+
Name: "METRICS AND STATS",
215+
Flags: []cli.Flag{
216+
utils.MetricsEnabledFlag,
217+
utils.MetricsEnableInfluxDBFlag,
218+
utils.MetricsInfluxDBEndpointFlag,
219+
utils.MetricsInfluxDBDatabaseFlag,
220+
utils.MetricsInfluxDBUsernameFlag,
221+
utils.MetricsInfluxDBPasswordFlag,
222+
utils.MetricsInfluxDBHostTagFlag,
223+
},
224+
},
214225
{
215226
Name: "WHISPER (EXPERIMENTAL)",
216227
Flags: whisperFlags,

cmd/utils/flags.go

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"runtime"
2828
"strconv"
2929
"strings"
30+
"time"
3031

3132
"github.com/ethereum/go-ethereum/accounts"
3233
"github.com/ethereum/go-ethereum/accounts/keystore"
@@ -48,6 +49,7 @@ import (
4849
"github.com/ethereum/go-ethereum/les"
4950
"github.com/ethereum/go-ethereum/log"
5051
"github.com/ethereum/go-ethereum/metrics"
52+
"github.com/ethereum/go-ethereum/metrics/influxdb"
5153
"github.com/ethereum/go-ethereum/node"
5254
"github.com/ethereum/go-ethereum/p2p"
5355
"github.com/ethereum/go-ethereum/p2p/discover"
@@ -360,10 +362,6 @@ var (
360362
Name: "ethstats",
361363
Usage: "Reporting URL of a ethstats service (nodename:secret@host:port)",
362364
}
363-
MetricsEnabledFlag = cli.BoolFlag{
364-
Name: metrics.MetricsEnabledFlag,
365-
Usage: "Enable metrics collection and reporting",
366-
}
367365
FakePoWFlag = cli.BoolFlag{
368366
Name: "fakepow",
369367
Usage: "Disables proof-of-work verification",
@@ -532,6 +530,45 @@ var (
532530
Usage: "Minimum POW accepted",
533531
Value: whisper.DefaultMinimumPoW,
534532
}
533+
534+
// Metrics flags
535+
MetricsEnabledFlag = cli.BoolFlag{
536+
Name: metrics.MetricsEnabledFlag,
537+
Usage: "Enable metrics collection and reporting",
538+
}
539+
MetricsEnableInfluxDBFlag = cli.BoolFlag{
540+
Name: "metrics.influxdb",
541+
Usage: "Enable metrics export/push to an external InfluxDB database",
542+
}
543+
MetricsInfluxDBEndpointFlag = cli.StringFlag{
544+
Name: "metrics.influxdb.endpoint",
545+
Usage: "InfluxDB API endpoint to report metrics to",
546+
Value: "http://localhost:8086",
547+
}
548+
MetricsInfluxDBDatabaseFlag = cli.StringFlag{
549+
Name: "metrics.influxdb.database",
550+
Usage: "InfluxDB database name to push reported metrics to",
551+
Value: "geth",
552+
}
553+
MetricsInfluxDBUsernameFlag = cli.StringFlag{
554+
Name: "metrics.influxdb.username",
555+
Usage: "Username to authorize access to the database",
556+
Value: "test",
557+
}
558+
MetricsInfluxDBPasswordFlag = cli.StringFlag{
559+
Name: "metrics.influxdb.password",
560+
Usage: "Password to authorize access to the database",
561+
Value: "test",
562+
}
563+
// The `host` tag is part of every measurement sent to InfluxDB. Queries on tags are faster in InfluxDB.
564+
// It is used so that we can group all nodes and average a measurement across all of them, but also so
565+
// that we can select a specific node and inspect its measurements.
566+
// https://docs.influxdata.com/influxdb/v1.4/concepts/key_concepts/#tag-key
567+
MetricsInfluxDBHostTagFlag = cli.StringFlag{
568+
Name: "metrics.influxdb.host.tag",
569+
Usage: "InfluxDB `host` tag attached to all measurements",
570+
Value: "localhost",
571+
}
535572
)
536573

537574
// MakeDataDir retrieves the currently requested data directory, terminating
@@ -1184,6 +1221,27 @@ func SetupNetwork(ctx *cli.Context) {
11841221
params.TargetGasLimit = ctx.GlobalUint64(TargetGasLimitFlag.Name)
11851222
}
11861223

1224+
func SetupMetrics(ctx *cli.Context) {
1225+
if metrics.Enabled {
1226+
log.Info("Enabling metrics collection")
1227+
var (
1228+
enableExport = ctx.GlobalBool(MetricsEnableInfluxDBFlag.Name)
1229+
endpoint = ctx.GlobalString(MetricsInfluxDBEndpointFlag.Name)
1230+
database = ctx.GlobalString(MetricsInfluxDBDatabaseFlag.Name)
1231+
username = ctx.GlobalString(MetricsInfluxDBUsernameFlag.Name)
1232+
password = ctx.GlobalString(MetricsInfluxDBPasswordFlag.Name)
1233+
hosttag = ctx.GlobalString(MetricsInfluxDBHostTagFlag.Name)
1234+
)
1235+
1236+
if enableExport {
1237+
log.Info("Enabling metrics export to InfluxDB")
1238+
go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, database, username, password, "geth.", map[string]string{
1239+
"host": hosttag,
1240+
})
1241+
}
1242+
}
1243+
}
1244+
11871245
// MakeChainDatabase open an LevelDB using the flags passed to the client and will hard crash if it fails.
11881246
func MakeChainDatabase(ctx *cli.Context, stack *node.Node) ethdb.Database {
11891247
var (

metrics/influxdb/influxdb.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ package influxdb
22

33
import (
44
"fmt"
5-
"log"
65
uurl "net/url"
76
"time"
87

8+
"github.com/ethereum/go-ethereum/log"
99
"github.com/ethereum/go-ethereum/metrics"
1010
"github.com/influxdata/influxdb/client"
1111
)
@@ -35,7 +35,7 @@ func InfluxDB(r metrics.Registry, d time.Duration, url, database, username, pass
3535
func InfluxDBWithTags(r metrics.Registry, d time.Duration, url, database, username, password, namespace string, tags map[string]string) {
3636
u, err := uurl.Parse(url)
3737
if err != nil {
38-
log.Printf("unable to parse InfluxDB url %s. err=%v", url, err)
38+
log.Warn("Unable to parse InfluxDB", "url", url, "err", err)
3939
return
4040
}
4141

@@ -51,7 +51,7 @@ func InfluxDBWithTags(r metrics.Registry, d time.Duration, url, database, userna
5151
cache: make(map[string]int64),
5252
}
5353
if err := rep.makeClient(); err != nil {
54-
log.Printf("unable to make InfluxDB client. err=%v", err)
54+
log.Warn("Unable to make InfluxDB client", "err", err)
5555
return
5656
}
5757

@@ -76,15 +76,15 @@ func (r *reporter) run() {
7676
select {
7777
case <-intervalTicker:
7878
if err := r.send(); err != nil {
79-
log.Printf("unable to send to InfluxDB. err=%v", err)
79+
log.Warn("Unable to send to InfluxDB", "err", err)
8080
}
8181
case <-pingTicker:
8282
_, _, err := r.client.Ping()
8383
if err != nil {
84-
log.Printf("got error while sending a ping to InfluxDB, trying to recreate client. err=%v", err)
84+
log.Warn("Got error while sending a ping to InfluxDB, trying to recreate client", "err", err)
8585

8686
if err = r.makeClient(); err != nil {
87-
log.Printf("unable to make InfluxDB client. err=%v", err)
87+
log.Warn("Unable to make InfluxDB client", "err", err)
8888
}
8989
}
9090
}

0 commit comments

Comments
 (0)