Skip to content

Commit

Permalink
feat: add discord labels to metrics (#26)
Browse files Browse the repository at this point in the history
* feat: add discord labels to metrics

* feat: only accept digits in discord ids

* feat: add testcases for getDiscordIDs

* fix: linting error

* feat: add more descriptive test case
  • Loading branch information
jlehtimaki authored Nov 14, 2023
1 parent b9d57c9 commit 1442748
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 16 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.21
require (
cosmossdk.io/math v1.0.1
github.com/caarlos0/env/v9 v9.0.0
github.com/cosmos/ibc-go/v7 v7.2.0
github.com/cosmos/relayer/v2 v2.4.1
github.com/google/go-github/v55 v55.0.0
github.com/prometheus/client_golang v1.15.0
Expand Down Expand Up @@ -56,7 +57,6 @@ require (
github.com/cosmos/gogogateway v1.2.0 // indirect
github.com/cosmos/gogoproto v1.4.10 // indirect
github.com/cosmos/iavl v0.20.0 // indirect
github.com/cosmos/ibc-go/v7 v7.2.0 // indirect
github.com/cosmos/ics23/go v0.10.0 // indirect
github.com/cosmos/ledger-cosmos-go v0.12.2 // indirect
github.com/cosmos/rosetta-sdk-go v0.10.0 // indirect
Expand Down
51 changes: 45 additions & 6 deletions pkg/collector/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import (
"fmt"
"math/big"
"reflect"
"regexp"
"strings"
"sync"

"github.com/cosmos/relayer/v2/relayer"
"github.com/prometheus/client_golang/prometheus"
"go.uber.org/zap"

Expand All @@ -27,7 +28,14 @@ var (
clientExpiry = prometheus.NewDesc(
clientExpiryMetricName,
"Returns light client expiry in unixtime.",
[]string{"host_chain_id", "client_id", "target_chain_id", "status"}, nil,
[]string{
"host_chain_id",
"client_id",
"target_chain_id",
"discord_ids",
"status",
},
nil,
)
channelStuckPackets = prometheus.NewDesc(
channelStuckPacketsMetricName,
Expand All @@ -37,6 +45,7 @@ var (
"dst_channel_id",
"src_chain_id",
"dst_chain_id",
"discord_ids",
"status",
},
nil,
Expand All @@ -50,7 +59,7 @@ var (

type IBCCollector struct {
RPCs *map[string]config.RPC
Paths []*relayer.IBCdata
Paths []*config.IBCData
}

type WalletBalanceCollector struct {
Expand All @@ -77,9 +86,11 @@ func (cc IBCCollector) Collect(ch chan<- prometheus.Metric) {
for _, p := range cc.Paths {
wg.Add(1)

go func(path *relayer.IBCdata) {
go func(path *config.IBCData) {
defer wg.Done()

discordIDs := getDiscordIDs(path.Operators)

// Client info
ci, err := ibc.GetClientsInfo(path, cc.RPCs)
status := successStatus
Expand All @@ -94,14 +105,26 @@ func (cc IBCCollector) Collect(ch chan<- prometheus.Metric) {
clientExpiry,
prometheus.GaugeValue,
float64(ci.ChainAClientExpiration.Unix()),
[]string{(*cc.RPCs)[path.Chain1.ChainName].ChainID, path.Chain1.ClientID, (*cc.RPCs)[path.Chain2.ChainName].ChainID, status}...,
[]string{
(*cc.RPCs)[path.Chain1.ChainName].ChainID,
path.Chain1.ClientID,
(*cc.RPCs)[path.Chain2.ChainName].ChainID,
discordIDs,
status,
}...,
)

ch <- prometheus.MustNewConstMetric(
clientExpiry,
prometheus.GaugeValue,
float64(ci.ChainBClientExpiration.Unix()),
[]string{(*cc.RPCs)[path.Chain2.ChainName].ChainID, path.Chain2.ClientID, (*cc.RPCs)[path.Chain1.ChainName].ChainID, status}...,
[]string{
(*cc.RPCs)[path.Chain2.ChainName].ChainID,
path.Chain2.ClientID,
(*cc.RPCs)[path.Chain1.ChainName].ChainID,
discordIDs,
status,
}...,
)

// Stuck packets
Expand All @@ -125,6 +148,7 @@ func (cc IBCCollector) Collect(ch chan<- prometheus.Metric) {
sp.Destination,
(*cc.RPCs)[path.Chain1.ChainName].ChainID,
(*cc.RPCs)[path.Chain2.ChainName].ChainID,
discordIDs,
status,
}...,
)
Expand All @@ -138,6 +162,7 @@ func (cc IBCCollector) Collect(ch chan<- prometheus.Metric) {
sp.Source,
(*cc.RPCs)[path.Chain2.ChainName].ChainID,
(*cc.RPCs)[path.Chain1.ChainName].ChainID,
discordIDs,
status,
}...,
)
Expand Down Expand Up @@ -192,3 +217,17 @@ func (wb WalletBalanceCollector) Collect(ch chan<- prometheus.Metric) {

log.Debug("Stop collecting", zap.String("metric", walletBalanceMetricName))
}

func getDiscordIDs(ops []config.Operator) string {
var ids []string

pattern := regexp.MustCompile(`^\d+$`)

for _, op := range ops {
if pattern.MatchString(op.Discord.ID) {
ids = append(ids, op.Discord.ID)
}
}

return strings.Join(ids, ",")
}
64 changes: 64 additions & 0 deletions pkg/collector/collector_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package collector

import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/archway-network/relayer_exporter/pkg/config"
)

func TestDiscordIDs(t *testing.T) {
testCases := []struct {
name string
ops []config.Operator
expected string
}{
{
name: "All Valid IDs",
ops: []config.Operator{
{
Discord: config.Discord{ID: "123456"},
},
{
Discord: config.Discord{ID: "12312387"},
},
},
expected: "123456,12312387",
},
{
name: "Some Invalid IDs",
ops: []config.Operator{
{
Discord: config.Discord{ID: "123456"},
},
{
Discord: config.Discord{ID: "ABCDEF"},
},
{
Discord: config.Discord{ID: "789012"},
},
},
expected: "123456,789012",
},
{
name: "No Valid IDs",
ops: []config.Operator{
{Discord: config.Discord{ID: "ABCDEF"}},
{Discord: config.Discord{ID: "GHIJKL"}},
},
expected: "",
},
{
name: "Empty Input",
ops: []config.Operator{{}, {}, {}},
expected: "",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
res := getDiscordIDs(tc.ops)
assert.Equal(t, tc.expected, res)
})
}
}
69 changes: 62 additions & 7 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (

"cosmossdk.io/math"
"github.com/caarlos0/env/v9"
"github.com/cosmos/relayer/v2/relayer"
"github.com/google/go-github/v55/github"
"gopkg.in/yaml.v3"

Expand Down Expand Up @@ -46,6 +45,56 @@ type Config struct {
} `yaml:"github"`
}

type IBCData struct {
Schema string `json:"$schema"`
Chain1 struct {
ChainName string `json:"chain_name"`
ClientID string `json:"client_id"`
ConnectionID string `json:"connection_id"`
} `json:"chain_1"`
Chain2 struct {
ChainName string `json:"chain_name"`
ClientID string `json:"client_id"`
ConnectionID string `json:"connection_id"`
} `json:"chain_2"`
Channels []struct {
Chain1 struct {
ChannelID string `json:"channel_id"`
PortID string `json:"port_id"`
} `json:"chain_1"`
Chain2 struct {
ChannelID string `json:"channel_id"`
PortID string `json:"port_id"`
} `json:"chain_2"`
Ordering string `json:"ordering"`
Version string `json:"version"`
Tags struct {
Status string `json:"status"`
Preferred bool `json:"preferred"`
Dex string `json:"dex"`
Properties string `json:"properties"`
} `json:"tags,omitempty"`
} `json:"channels"`
Operators []Operator `json:"operators"`
}

type Operator struct {
Chain1 struct {
Address string `json:"address"`
} `json:"chain_1"`
Chain2 struct {
Address string `json:"address"`
} `json:"chain_2"`
Memo string `json:"memo"`
Name string `json:"name"`
Discord Discord `json:"discord"`
}

type Discord struct {
Handle string `json:"handle"`
ID string `json:"id"`
}

func (a *Account) GetBalance(rpcs *map[string]RPC) error {
chain, err := chain.PrepChain(chain.Info{
ChainID: (*rpcs)[a.ChainName].ChainID,
Expand Down Expand Up @@ -77,7 +126,7 @@ func (c *Config) GetRPCsMap() *map[string]RPC {
return &rpcs
}

func (c *Config) IBCPaths() ([]*relayer.IBCdata, error) {
func (c *Config) IBCPaths() ([]*IBCData, error) {
client := github.NewClient(nil)

if c.GitHub.Token != "" {
Expand All @@ -91,7 +140,7 @@ func (c *Config) IBCPaths() ([]*relayer.IBCdata, error) {
return nil, err
}

testnetsPaths := []*relayer.IBCdata{}
testnetsPaths := []*IBCData{}
if c.GitHub.TestnetsIBCDir != "" {
testnetsPaths, err = c.getPaths(c.GitHub.TestnetsIBCDir, client)
if err != nil {
Expand All @@ -104,7 +153,7 @@ func (c *Config) IBCPaths() ([]*relayer.IBCdata, error) {
return paths, nil
}

func (c *Config) getPaths(dir string, client *github.Client) ([]*relayer.IBCdata, error) {
func (c *Config) getPaths(dir string, client *github.Client) ([]*IBCData, error) {
if client == nil {
return nil, ErrGitHubClient
}
Expand All @@ -116,16 +165,22 @@ func (c *Config) getPaths(dir string, client *github.Client) ([]*relayer.IBCdata
return nil, err
}

ibcs := []*relayer.IBCdata{}
ibcs := []*IBCData{}

for _, file := range ibcDir {
if strings.HasSuffix(*file.Path, ibcPathSuffix) {
content, _, _, err := client.Repositories.GetContents(ctx, c.GitHub.Org, c.GitHub.Repo, *file.Path, nil)
content, _, _, err := client.Repositories.GetContents(
ctx,
c.GitHub.Org,
c.GitHub.Repo,
*file.Path,
nil,
)
if err != nil {
return nil, err
}

ibc := &relayer.IBCdata{}
ibc := &IBCData{}

c, err := content.GetContent()
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions pkg/ibc/ibc.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ type Channel struct {
}
}

func GetClientsInfo(ibc *relayer.IBCdata, rpcs *map[string]config.RPC) (ClientsInfo, error) {
func GetClientsInfo(ibc *config.IBCData, rpcs *map[string]config.RPC) (ClientsInfo, error) {
clientsInfo := ClientsInfo{}

cdA := chain.Info{
Expand Down Expand Up @@ -91,7 +91,7 @@ func GetClientsInfo(ibc *relayer.IBCdata, rpcs *map[string]config.RPC) (ClientsI
return clientsInfo, nil
}

func GetChannelsInfo(ibc *relayer.IBCdata, rpcs *map[string]config.RPC) (ChannelsInfo, error) {
func GetChannelsInfo(ibc *config.IBCData, rpcs *map[string]config.RPC) (ChannelsInfo, error) {
ctx := context.Background()
channelInfo := ChannelsInfo{}

Expand Down

0 comments on commit 1442748

Please sign in to comment.