Skip to content

Commit

Permalink
feat. support labels
Browse files Browse the repository at this point in the history
  • Loading branch information
rootwarp committed Nov 1, 2024
1 parent bcd5374 commit 55f45e6
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 11 deletions.
25 changes: 17 additions & 8 deletions cmd/prom-proxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import (
"github.com/dsrvlabs/prometheus-proxy/config"
"github.com/dsrvlabs/prometheus-proxy/converter"
"github.com/dsrvlabs/prometheus-proxy/jsonselector"
"github.com/dsrvlabs/prometheus-proxy/types"
"github.com/dsrvlabs/prometheus-proxy/log"
"github.com/dsrvlabs/prometheus-proxy/types"
)

const (
Expand All @@ -26,21 +26,25 @@ const (
type App struct {
config *types.Config
converter converter.Converter
gauges map[string]prometheus.Gauge
gauges map[string]*prometheus.GaugeVec
}

// Prepare prepares prometheus metrics.
func (a *App) Prepare() (*http.ServeMux, error) {
a.gauges = make(map[string]prometheus.Gauge)
a.gauges = make(map[string]*prometheus.GaugeVec)

rpcs := a.config.RPCFetch
for _, rpc := range rpcs {
fields := rpc.Fields
labels := make([]string, len(rpc.Labels))
for i, label := range rpc.Labels {
labels[i] = label.Key
}

for _, field := range fields {
gauge := prometheus.NewGauge(
prometheus.GaugeOpts{
Name: field.MetricName,
},
gauge := prometheus.NewGaugeVec(
prometheus.GaugeOpts{Name: field.MetricName},
labels,
)

a.gauges[field.MetricName] = gauge
Expand Down Expand Up @@ -84,7 +88,12 @@ func (a *App) updateMetrics() {
continue
}

gauge.Set(result.Value)
labels := make([]string, len(rpc.Labels))
for i, label := range rpc.Labels {
labels[i] = label.Value
}

gauge.WithLabelValues(labels...).Set(result.Value)
}
}
}
Expand Down
16 changes: 16 additions & 0 deletions cmd/prom-proxy/prom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ func Test_Prom(t *testing.T) {
MetricName: "voting_power",
},
},
Labels: []types.Label{
{
Key: "hostname",
Value: "cosmos-mainnet",
},
},
},
},
}
Expand All @@ -35,6 +41,11 @@ func Test_Prom(t *testing.T) {
router, err := app.Prepare()
assert.Nil(t, err)

// Add dummy
app.gauges["latest_block_height"].WithLabelValues("cosmos-mainnet").Set(100)
app.gauges["voting_power"].WithLabelValues("cosmos-mainnet").Set(100)

// Test
server := httptest.NewServer(router)
defer server.Close()

Expand All @@ -44,9 +55,14 @@ func Test_Prom(t *testing.T) {
d, err := io.ReadAll(resp.Body)
assert.Nil(t, err)

// Asserts
for _, rpc := range config.RPCFetch {
for _, field := range rpc.Fields {
assert.Contains(t, string(d), field.MetricName)
}

for _, label := range rpc.Labels {
assert.Contains(t, string(d), label.Key)
}
}
}
17 changes: 17 additions & 0 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ func TestConfig_Load(t *testing.T) {
MetricName: "catch_up",
},
},
Labels: []types.Label{
{
Key: "hostname",
Value: "cosmos-mainnet",
},
},
},
{
Method: "POST",
Expand All @@ -45,6 +51,12 @@ func TestConfig_Load(t *testing.T) {
MetricName: "is_syncing",
},
},
Labels: []types.Label{
{
Key: "hostname",
Value: "ethereum-holesky",
},
},
},
},
},
Expand All @@ -66,6 +78,11 @@ func TestConfig_Load(t *testing.T) {
assert.Equal(t, tt.ExpectConfig.RPCFetch[i].Fields[j].Selector, field.Selector)
assert.Equal(t, tt.ExpectConfig.RPCFetch[i].Fields[j].MetricName, field.MetricName)
}

for j, label := range rpc.Labels {
assert.Equal(t, tt.ExpectConfig.RPCFetch[i].Labels[j].Key, label.Key)
assert.Equal(t, tt.ExpectConfig.RPCFetch[i].Labels[j].Value, label.Value)
}
}

})
Expand Down
6 changes: 6 additions & 0 deletions config/fixtures/rpc_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@ rpc_fetch:
metric_name: "block_height"
- selector: ".result.sync_info.catch_up"
metric_name: "catch_up"
labels:
- key: "hostname"
value: "cosmos-mainnet"

- method: POST
url: http://localhost:8545
body: '{"jsonrpc":"2.0","id":83,"result":false}'
fields:
- selector: ".result"
metric_name: "is_syncing"
labels:
- key: "hostname"
value: "ethereum-holesky"
6 changes: 6 additions & 0 deletions samples/ethereum.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,16 @@ rpc_fetch:
fields:
- selector: ".result"
metric_name: "is_syncing"
labels:
- key: "hostname"
value: "ethereum-holesky"

- method: POST
url: https://rpc.flashbots.net
body: '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":83}'
fields:
- selector: ".result"
metric_name: "block_number"
labels:
- key: "hostname"
value: "ethereum-holesky"
13 changes: 10 additions & 3 deletions types/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,21 @@ type Config struct {

// RPCFetchConfig is a struct that holds conversion configuration for RPC response into Prometheus.
type RPCFetchConfig struct {
Method string `yaml:"method,omitempty"`
URL string `yaml:"url,omitempty"`
Body string `yaml:"body,omitempty"`
Method string `yaml:"method,omitempty"`
URL string `yaml:"url,omitempty"`
Body string `yaml:"body,omitempty"`
Fields []Field `yaml:"fields,omitempty"`
Labels []Label `yaml:"labels,omitempty"`
}

// Field is a struct that holds the configuration for a field in the response.
type Field struct {
Selector string `yaml:"selector,omitempty"`
MetricName string `yaml:"metric_name,omitempty"`
}

// Label is a struct that holds the configuration for a label in the response.
type Label struct {
Key string `yaml:"key,omitempty"`
Value string `yaml:"value,omitempty"`
}

0 comments on commit 55f45e6

Please sign in to comment.