mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-13 21:31:23 +00:00
separate http server for metrics
This commit is contained in:
@ -45,34 +45,37 @@ type Config struct {
|
|||||||
BaseConfig `mapstructure:",squash"`
|
BaseConfig `mapstructure:",squash"`
|
||||||
|
|
||||||
// Options for services
|
// Options for services
|
||||||
RPC *RPCConfig `mapstructure:"rpc"`
|
RPC *RPCConfig `mapstructure:"rpc"`
|
||||||
P2P *P2PConfig `mapstructure:"p2p"`
|
P2P *P2PConfig `mapstructure:"p2p"`
|
||||||
Mempool *MempoolConfig `mapstructure:"mempool"`
|
Mempool *MempoolConfig `mapstructure:"mempool"`
|
||||||
Consensus *ConsensusConfig `mapstructure:"consensus"`
|
Consensus *ConsensusConfig `mapstructure:"consensus"`
|
||||||
TxIndex *TxIndexConfig `mapstructure:"tx_index"`
|
TxIndex *TxIndexConfig `mapstructure:"tx_index"`
|
||||||
|
Instrumentation *InstrumentationConfig `mapstructure:"instrumentation"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultConfig returns a default configuration for a Tendermint node
|
// DefaultConfig returns a default configuration for a Tendermint node
|
||||||
func DefaultConfig() *Config {
|
func DefaultConfig() *Config {
|
||||||
return &Config{
|
return &Config{
|
||||||
BaseConfig: DefaultBaseConfig(),
|
BaseConfig: DefaultBaseConfig(),
|
||||||
RPC: DefaultRPCConfig(),
|
RPC: DefaultRPCConfig(),
|
||||||
P2P: DefaultP2PConfig(),
|
P2P: DefaultP2PConfig(),
|
||||||
Mempool: DefaultMempoolConfig(),
|
Mempool: DefaultMempoolConfig(),
|
||||||
Consensus: DefaultConsensusConfig(),
|
Consensus: DefaultConsensusConfig(),
|
||||||
TxIndex: DefaultTxIndexConfig(),
|
TxIndex: DefaultTxIndexConfig(),
|
||||||
|
Instrumentation: DefaultInstrumentationConfig(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestConfig returns a configuration that can be used for testing
|
// TestConfig returns a configuration that can be used for testing
|
||||||
func TestConfig() *Config {
|
func TestConfig() *Config {
|
||||||
return &Config{
|
return &Config{
|
||||||
BaseConfig: TestBaseConfig(),
|
BaseConfig: TestBaseConfig(),
|
||||||
RPC: TestRPCConfig(),
|
RPC: TestRPCConfig(),
|
||||||
P2P: TestP2PConfig(),
|
P2P: TestP2PConfig(),
|
||||||
Mempool: TestMempoolConfig(),
|
Mempool: TestMempoolConfig(),
|
||||||
Consensus: TestConsensusConfig(),
|
Consensus: TestConsensusConfig(),
|
||||||
TxIndex: TestTxIndexConfig(),
|
TxIndex: TestTxIndexConfig(),
|
||||||
|
Instrumentation: TestInstrumentationConfig(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,10 +145,6 @@ type BaseConfig struct {
|
|||||||
|
|
||||||
// Database directory
|
// Database directory
|
||||||
DBPath string `mapstructure:"db_dir"`
|
DBPath string `mapstructure:"db_dir"`
|
||||||
|
|
||||||
// When true, metrics are served under `/metrics` using a Prometheus client
|
|
||||||
// Check out the documentation for the list of available metrics.
|
|
||||||
Monitoring bool `mapstructure:"monitoring"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultBaseConfig returns a default base configuration for a Tendermint node
|
// DefaultBaseConfig returns a default base configuration for a Tendermint node
|
||||||
@ -163,7 +162,6 @@ func DefaultBaseConfig() BaseConfig {
|
|||||||
FilterPeers: false,
|
FilterPeers: false,
|
||||||
DBBackend: "leveldb",
|
DBBackend: "leveldb",
|
||||||
DBPath: "data",
|
DBPath: "data",
|
||||||
Monitoring: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -578,6 +576,35 @@ func TestTxIndexConfig() *TxIndexConfig {
|
|||||||
return DefaultTxIndexConfig()
|
return DefaultTxIndexConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// InstrumentationConfig
|
||||||
|
|
||||||
|
// InstrumentationConfig defines the configuration for metrics reporting.
|
||||||
|
type InstrumentationConfig struct {
|
||||||
|
// When true, Prometheus metrics are served under /metrics on
|
||||||
|
// PrometheusListenAddr.
|
||||||
|
// Check out the documentation for the list of available metrics.
|
||||||
|
Prometheus bool `mapstructure:"prometheus"`
|
||||||
|
|
||||||
|
// Address to listen for Prometheus collector(s) connections.
|
||||||
|
PrometheusListenAddr string `mapstructure:"prometheus_listen_addr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultInstrumentationConfig returns a default configuration for metrics
|
||||||
|
// reporting.
|
||||||
|
func DefaultInstrumentationConfig() *InstrumentationConfig {
|
||||||
|
return &InstrumentationConfig{
|
||||||
|
Prometheus: false,
|
||||||
|
PrometheusListenAddr: ":26660",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestInstrumentationConfig returns a default configuration for metrics
|
||||||
|
// reporting.
|
||||||
|
func TestInstrumentationConfig() *InstrumentationConfig {
|
||||||
|
return DefaultInstrumentationConfig()
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Utils
|
// Utils
|
||||||
|
|
||||||
|
@ -107,10 +107,6 @@ prof_laddr = "{{ .BaseConfig.ProfListenAddress }}"
|
|||||||
# so the app can decide if we should keep the connection or not
|
# so the app can decide if we should keep the connection or not
|
||||||
filter_peers = {{ .BaseConfig.FilterPeers }}
|
filter_peers = {{ .BaseConfig.FilterPeers }}
|
||||||
|
|
||||||
# When true, metrics are served under /metrics using a Prometheus client
|
|
||||||
# Check out the documentation for the list of available metrics.
|
|
||||||
monitoring = {{ .BaseConfig.Monitoring }}
|
|
||||||
|
|
||||||
##### advanced configuration options #####
|
##### advanced configuration options #####
|
||||||
|
|
||||||
##### rpc server configuration options #####
|
##### rpc server configuration options #####
|
||||||
@ -236,6 +232,17 @@ index_tags = "{{ .TxIndex.IndexTags }}"
|
|||||||
# desirable (see the comment above). IndexTags has a precedence over
|
# desirable (see the comment above). IndexTags has a precedence over
|
||||||
# IndexAllTags (i.e. when given both, IndexTags will be indexed).
|
# IndexAllTags (i.e. when given both, IndexTags will be indexed).
|
||||||
index_all_tags = {{ .TxIndex.IndexAllTags }}
|
index_all_tags = {{ .TxIndex.IndexAllTags }}
|
||||||
|
|
||||||
|
##### instrumentation configuration options #####
|
||||||
|
[instrumentation]
|
||||||
|
|
||||||
|
# When true, Prometheus metrics are served under /metrics on
|
||||||
|
# PrometheusListenAddr.
|
||||||
|
# Check out the documentation for the list of available metrics.
|
||||||
|
prometheus = {{ .Instrumentation.Prometheus }}
|
||||||
|
|
||||||
|
# Address to listen for Prometheus collector(s) connections
|
||||||
|
prometheus_listen_addr = "{{ .Instrumentation.PrometheusListenAddr }}"
|
||||||
`
|
`
|
||||||
|
|
||||||
/****** these are for test settings ***********/
|
/****** these are for test settings ***********/
|
||||||
|
34
node/node.go
34
node/node.go
@ -2,6 +2,7 @@ package node
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
@ -210,6 +211,7 @@ type Node struct {
|
|||||||
rpcListeners []net.Listener // rpc servers
|
rpcListeners []net.Listener // rpc servers
|
||||||
txIndexer txindex.TxIndexer
|
txIndexer txindex.TxIndexer
|
||||||
indexerService *txindex.IndexerService
|
indexerService *txindex.IndexerService
|
||||||
|
prometheusSrv *http.Server
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNode returns a new, ready to go, Tendermint Node.
|
// NewNode returns a new, ready to go, Tendermint Node.
|
||||||
@ -311,7 +313,7 @@ func NewNode(config *cfg.Config,
|
|||||||
p2pMetrics *p2p.Metrics
|
p2pMetrics *p2p.Metrics
|
||||||
memplMetrics *mempl.Metrics
|
memplMetrics *mempl.Metrics
|
||||||
)
|
)
|
||||||
if config.BaseConfig.Monitoring {
|
if config.Instrumentation.Prometheus {
|
||||||
csMetrics, p2pMetrics, memplMetrics = metricsProvider()
|
csMetrics, p2pMetrics, memplMetrics = metricsProvider()
|
||||||
} else {
|
} else {
|
||||||
csMetrics, p2pMetrics, memplMetrics = NopMetricsProvider()
|
csMetrics, p2pMetrics, memplMetrics = NopMetricsProvider()
|
||||||
@ -520,6 +522,10 @@ func (n *Node) OnStart() error {
|
|||||||
n.rpcListeners = listeners
|
n.rpcListeners = listeners
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if n.config.Instrumentation.Prometheus {
|
||||||
|
n.prometheusSrv = n.StartPrometheusServer(n.config.Instrumentation.PrometheusListenAddr)
|
||||||
|
}
|
||||||
|
|
||||||
// Start the switch (the P2P server).
|
// Start the switch (the P2P server).
|
||||||
err = n.sw.Start()
|
err = n.sw.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -561,6 +567,13 @@ func (n *Node) OnStop() {
|
|||||||
n.Logger.Error("Error stopping priv validator socket client", "err", err)
|
n.Logger.Error("Error stopping priv validator socket client", "err", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if n.prometheusSrv != nil {
|
||||||
|
if err := n.prometheusSrv.Shutdown(context.Background()); err != nil {
|
||||||
|
// Error from closing listeners, or context timeout:
|
||||||
|
n.Logger.Error("Prometheus HTTP server Shutdown", "err", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunForever waits for an interrupt signal and stops the node.
|
// RunForever waits for an interrupt signal and stops the node.
|
||||||
@ -615,9 +628,6 @@ func (n *Node) startRPC() ([]net.Listener, error) {
|
|||||||
wm := rpcserver.NewWebsocketManager(rpccore.Routes, coreCodec, rpcserver.EventSubscriber(n.eventBus))
|
wm := rpcserver.NewWebsocketManager(rpccore.Routes, coreCodec, rpcserver.EventSubscriber(n.eventBus))
|
||||||
wm.SetLogger(rpcLogger.With("protocol", "websocket"))
|
wm.SetLogger(rpcLogger.With("protocol", "websocket"))
|
||||||
mux.HandleFunc("/websocket", wm.WebsocketHandler)
|
mux.HandleFunc("/websocket", wm.WebsocketHandler)
|
||||||
if n.config.BaseConfig.Monitoring {
|
|
||||||
mux.Handle("/metrics", promhttp.Handler())
|
|
||||||
}
|
|
||||||
rpcserver.RegisterRPCFuncs(mux, rpccore.Routes, coreCodec, rpcLogger)
|
rpcserver.RegisterRPCFuncs(mux, rpccore.Routes, coreCodec, rpcLogger)
|
||||||
listener, err := rpcserver.StartHTTPServer(listenAddr, mux, rpcLogger)
|
listener, err := rpcserver.StartHTTPServer(listenAddr, mux, rpcLogger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -639,6 +649,22 @@ func (n *Node) startRPC() ([]net.Listener, error) {
|
|||||||
return listeners, nil
|
return listeners, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StartPrometheusServer starts a Prometheus HTTP server, listening for metrics
|
||||||
|
// collectors on addr.
|
||||||
|
func (n *Node) StartPrometheusServer(addr string) *http.Server {
|
||||||
|
srv := &http.Server{
|
||||||
|
Addr: addr,
|
||||||
|
Handler: promhttp.Handler(),
|
||||||
|
}
|
||||||
|
go func(s *http.Server, logger log.Logger) {
|
||||||
|
if err := s.ListenAndServe(); err != http.ErrServerClosed {
|
||||||
|
// Error starting or closing listener:
|
||||||
|
logger.Error("Prometheus HTTP server ListenAndServe", "err", err)
|
||||||
|
}
|
||||||
|
}(srv, n.Logger)
|
||||||
|
return srv
|
||||||
|
}
|
||||||
|
|
||||||
// Switch returns the Node's Switch.
|
// Switch returns the Node's Switch.
|
||||||
func (n *Node) Switch() *p2p.Switch {
|
func (n *Node) Switch() *p2p.Switch {
|
||||||
return n.sw
|
return n.sw
|
||||||
|
Reference in New Issue
Block a user