add hotspot activity and rewards metrics
This commit is contained in:
parent
cc251b1041
commit
7f8b73055e
|
@ -27,15 +27,14 @@ type Exporter struct {
|
||||||
|
|
||||||
// Account represents a helium account
|
// Account represents a helium account
|
||||||
type Account struct {
|
type Account struct {
|
||||||
hotspots []Hotspot
|
hotspots []Hotspot
|
||||||
hash string
|
hash string
|
||||||
lastRewardsUpdate time.Time
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hotspot represent a helium hotspot
|
// Hotspot represent a helium hotspot
|
||||||
type Hotspot struct {
|
type Hotspot struct {
|
||||||
hash string
|
name string
|
||||||
lastRewardsUpdate time.Time
|
hash string
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -160,11 +159,11 @@ var (
|
||||||
}
|
}
|
||||||
accountRewardsHnt = metricInfo{
|
accountRewardsHnt = metricInfo{
|
||||||
prometheus.NewDesc(
|
prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(namespace, "account", "rewards_hnt"),
|
prometheus.BuildFQName(namespace, "account", "rewards_hnt_total"),
|
||||||
"The number of HNT token rewarded to an account.",
|
"The number of HNT token rewarded to an account.",
|
||||||
commonAccountLabels, nil,
|
commonAccountLabels, nil,
|
||||||
),
|
),
|
||||||
prometheus.GaugeValue,
|
prometheus.CounterValue,
|
||||||
}
|
}
|
||||||
// accountDepositsHnt = metricInfo{
|
// accountDepositsHnt = metricInfo{
|
||||||
// prometheus.NewDesc(
|
// prometheus.NewDesc(
|
||||||
|
@ -192,25 +191,25 @@ var (
|
||||||
),
|
),
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
}
|
}
|
||||||
hotspotListening = metricInfo{
|
hotspotRelayed = metricInfo{
|
||||||
prometheus.NewDesc(
|
prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(namespace, "hotspot", "listening"),
|
prometheus.BuildFQName(namespace, "hotspot", "relayed"),
|
||||||
"Whether a hotspot is listening (not relayed).",
|
"Whether a hotspot is relayed.",
|
||||||
commonHotspotLabels, nil,
|
commonHotspotLabels, nil,
|
||||||
),
|
),
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
}
|
}
|
||||||
hotspotBlockHeight = metricInfo{
|
hotspotBlocks = metricInfo{
|
||||||
prometheus.NewDesc(
|
prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(namespace, "hotspot", "block_height"),
|
prometheus.BuildFQName(namespace, "hotspot", "blocks_total"),
|
||||||
"The block height of a Hotspot. Check on the hotspot itself for the most recent data.",
|
"The block height of a hotspot. Check on the hotspot itself for the most recent data.",
|
||||||
commonHotspotLabels, nil,
|
commonHotspotLabels, nil,
|
||||||
),
|
),
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
}
|
}
|
||||||
hotspotRewardScale = metricInfo{
|
hotspotRewardsScale = metricInfo{
|
||||||
prometheus.NewDesc(
|
prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(namespace, "hotspot", "reward_scale"),
|
prometheus.BuildFQName(namespace, "hotspot", "rewards_scale"),
|
||||||
"The reward scale of a hotspot.",
|
"The reward scale of a hotspot.",
|
||||||
commonHotspotLabels, nil,
|
commonHotspotLabels, nil,
|
||||||
),
|
),
|
||||||
|
@ -227,7 +226,7 @@ var (
|
||||||
hotspotAntennaInfo = metricInfo{
|
hotspotAntennaInfo = metricInfo{
|
||||||
prometheus.NewDesc(
|
prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(namespace, "hotspot", "antenna_info"),
|
prometheus.BuildFQName(namespace, "hotspot", "antenna_info"),
|
||||||
"Information on the location of a hotspot.",
|
"Information on the antenna of a hotspot.",
|
||||||
append(commonHotspotLabels, "gain", "elevation"), nil,
|
append(commonHotspotLabels, "gain", "elevation"), nil,
|
||||||
),
|
),
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
|
@ -242,11 +241,11 @@ var (
|
||||||
}
|
}
|
||||||
hotspotRewardsHnt = metricInfo{
|
hotspotRewardsHnt = metricInfo{
|
||||||
prometheus.NewDesc(
|
prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(namespace, "hotspot", "rewards_hnt"),
|
prometheus.BuildFQName(namespace, "hotspot", "rewards_hnt_total"),
|
||||||
"The number of HNT token rewarded to a hotspot.",
|
"The number of HNT token rewarded to a hotspot.",
|
||||||
commonHotspotLabels, nil,
|
commonHotspotLabels, nil,
|
||||||
),
|
),
|
||||||
prometheus.GaugeValue,
|
prometheus.CounterValue,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -280,9 +279,9 @@ func (e *Exporter) Describe(ch chan<- *prometheus.Desc) {
|
||||||
// ch <- accountWithdrawalsHnt.Desc
|
// ch <- accountWithdrawalsHnt.Desc
|
||||||
|
|
||||||
ch <- hotspotUp.Desc
|
ch <- hotspotUp.Desc
|
||||||
ch <- hotspotListening.Desc
|
ch <- hotspotRelayed.Desc
|
||||||
ch <- hotspotBlockHeight.Desc
|
ch <- hotspotBlocks.Desc
|
||||||
ch <- hotspotRewardScale.Desc
|
ch <- hotspotRewardsScale.Desc
|
||||||
ch <- hotspotGeocodeInfo.Desc
|
ch <- hotspotGeocodeInfo.Desc
|
||||||
ch <- hotspotAntennaInfo.Desc
|
ch <- hotspotAntennaInfo.Desc
|
||||||
ch <- hotspotActivity.Desc
|
ch <- hotspotActivity.Desc
|
||||||
|
@ -294,9 +293,9 @@ func (e *Exporter) Describe(ch chan<- *prometheus.Desc) {
|
||||||
func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
|
func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
|
||||||
e.collectOracleMetrics(ch)
|
e.collectOracleMetrics(ch)
|
||||||
e.collectStatsMetrics(ch)
|
e.collectStatsMetrics(ch)
|
||||||
for _, account := range e.Accounts {
|
for i := range e.Accounts {
|
||||||
e.collectAccountMetrics(ch, &account)
|
e.collectAccountMetrics(ch, &e.Accounts[i])
|
||||||
e.collectHotspotMetrics(ch, &account)
|
e.collectHotspotMetrics(ch, &e.Accounts[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,7 +366,7 @@ func (e *Exporter) collectAccountMetrics(ch chan<- prometheus.Metric, account *A
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
accountRewardTotalsForAddress, err := heliumapi.GetRewardTotalsForAccount(account.hash, &account.lastRewardsUpdate, nil)
|
accountRewardTotalsForAddress, err := heliumapi.GetRewardTotalsForAccount(account.hash, &time.Time{}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return
|
return
|
||||||
|
@ -387,10 +386,6 @@ func (e *Exporter) collectAccountMetrics(ch chan<- prometheus.Metric, account *A
|
||||||
accountRewardsHnt.Desc, accountRewardsHnt.Type, accountRewardTotalsForAddress.Data.Sum,
|
accountRewardsHnt.Desc, accountRewardsHnt.Type, accountRewardTotalsForAddress.Data.Sum,
|
||||||
account.hash,
|
account.hash,
|
||||||
)
|
)
|
||||||
account.lastRewardsUpdate, err = time.Parse(time.RFC3339, accountRewardTotalsForAddress.Meta.MaxTime)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("failed to parse time \"%v\", value of %v will be bad: %v\n", accountRewardTotalsForAddress.Meta.MaxTime, accountRewardsHnt.Desc.String(), err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// collectStatsMetrics collect metrics in the hotspot group from the helium api
|
// collectStatsMetrics collect metrics in the hotspot group from the helium api
|
||||||
|
@ -402,20 +397,32 @@ func (e *Exporter) collectHotspotMetrics(ch chan<- prometheus.Metric, account *A
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, hotspotData := range hotspotsForAddress.Data {
|
for _, hotspotData := range hotspotsForAddress.Data {
|
||||||
|
hotspotActivityForAddress, err := heliumapi.GetHotspotActivityCount(hotspotData.Address)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
hotspotRewardTotalsForAddress, err := heliumapi.GetRewardsTotalForHotspot(hotspotData.Address, &time.Time{}, nil)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
hotspotUp.Desc, hotspotUp.Type, bool2Float64(hotspotData.Status.Online == "online"),
|
hotspotUp.Desc, hotspotUp.Type, bool2Float64(hotspotData.Status.Online == "online"),
|
||||||
account.hash, hotspotData.Address, hotspotData.Name,
|
account.hash, hotspotData.Address, hotspotData.Name,
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
hotspotListening.Desc, hotspotListening.Type, bool2Float64(len(hotspotData.Status.ListenAddrs) != 0),
|
hotspotRelayed.Desc, hotspotRelayed.Type, bool2Float64(len(hotspotData.Status.ListenAddrs) > 0 && strings.HasPrefix(hotspotData.Status.ListenAddrs[0], "/p2p")),
|
||||||
account.hash, hotspotData.Address, hotspotData.Name,
|
account.hash, hotspotData.Address, hotspotData.Name,
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
hotspotBlockHeight.Desc, hotspotBlockHeight.Type, float64(hotspotData.Status.Height),
|
hotspotBlocks.Desc, hotspotBlocks.Type, float64(hotspotData.Status.Height),
|
||||||
account.hash, hotspotData.Address, hotspotData.Name,
|
account.hash, hotspotData.Address, hotspotData.Name,
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
hotspotRewardScale.Desc, hotspotRewardScale.Type, float64(hotspotData.RewardScale),
|
hotspotRewardsScale.Desc, hotspotRewardsScale.Type, float64(hotspotData.RewardScale),
|
||||||
account.hash, hotspotData.Address, hotspotData.Name,
|
account.hash, hotspotData.Address, hotspotData.Name,
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
@ -426,6 +433,16 @@ func (e *Exporter) collectHotspotMetrics(ch chan<- prometheus.Metric, account *A
|
||||||
hotspotAntennaInfo.Desc, hotspotAntennaInfo.Type, 1.0,
|
hotspotAntennaInfo.Desc, hotspotAntennaInfo.Type, 1.0,
|
||||||
account.hash, hotspotData.Address, hotspotData.Name, strconv.Itoa(hotspotData.Gain), strconv.Itoa(hotspotData.Elevation),
|
account.hash, hotspotData.Address, hotspotData.Name, strconv.Itoa(hotspotData.Gain), strconv.Itoa(hotspotData.Elevation),
|
||||||
)
|
)
|
||||||
|
for accType, count := range hotspotActivityForAddress.Data {
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
hotspotActivity.Desc, hotspotActivity.Type, float64(count),
|
||||||
|
account.hash, hotspotData.Address, hotspotData.Name, accType,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
hotspotRewardsHnt.Desc, hotspotRewardsHnt.Type, hotspotRewardTotalsForAddress.Data.Sum,
|
||||||
|
account.hash, hotspotData.Address, hotspotData.Name,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,8 +461,7 @@ func NewExporter(accountHashs []string) (*Exporter, error) {
|
||||||
|
|
||||||
func NewAccount(hash string) Account {
|
func NewAccount(hash string) Account {
|
||||||
return Account{
|
return Account{
|
||||||
hash: hash,
|
hash: hash,
|
||||||
lastRewardsUpdate: time.Now(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,37 +19,16 @@ type Account struct {
|
||||||
} `json:"data"`
|
} `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ActivityCounts struct {
|
|
||||||
Data map[string]int
|
|
||||||
}
|
|
||||||
|
|
||||||
type RewardTotal struct {
|
|
||||||
Meta struct {
|
|
||||||
MinTime string `json:"min_time"`
|
|
||||||
MaxTime string `json:"max_time"`
|
|
||||||
} `json:"meta"`
|
|
||||||
|
|
||||||
Data struct {
|
|
||||||
Total float64 `json:"total"`
|
|
||||||
Sum float64 `json:"sum"`
|
|
||||||
Stddev float64 `json:"stddev"`
|
|
||||||
Min float64 `json:"min"`
|
|
||||||
Median float64 `json:"median"`
|
|
||||||
Max float64 `json:"max"`
|
|
||||||
Avg float64 `json:"avg"`
|
|
||||||
} `json:"data"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type AccountHotspots struct {
|
type AccountHotspots struct {
|
||||||
Data []struct {
|
Data []struct {
|
||||||
Lng float64 `json:"lng"`
|
Lng float64 `json:"lng"`
|
||||||
Lat float64 `json:"lat"`
|
Lat float64 `json:"lat"`
|
||||||
TimestampAdded string `json:"timestamp_added"`
|
TimestampAdded string `json:"timestamp_added"`
|
||||||
Status struct {
|
Status struct {
|
||||||
Timestamp string `json:"timestamp"`
|
Timestamp string `json:"timestamp"`
|
||||||
Online string `json:"online"`
|
Online string `json:"online"`
|
||||||
ListenAddrs []string
|
ListenAddrs []string `json:"listen_addrs"`
|
||||||
Height int
|
Height int `json:"height"`
|
||||||
} `json:"status"`
|
} `json:"status"`
|
||||||
RewardScale float64 `json:"reward_scale"`
|
RewardScale float64 `json:"reward_scale"`
|
||||||
Payer string `json:"payer"`
|
Payer string `json:"payer"`
|
||||||
|
@ -125,7 +104,7 @@ func GetRewardTotalsForAccount(account string, minTime *time.Time, maxTime *time
|
||||||
params["min_time"] = minTime.UTC().Format("2006-01-02T15:04:05Z")
|
params["min_time"] = minTime.UTC().Format("2006-01-02T15:04:05Z")
|
||||||
}
|
}
|
||||||
if maxTime != nil {
|
if maxTime != nil {
|
||||||
params["max_time"] = minTime.UTC().Format("2006-01-02T15:04:05Z")
|
params["max_time"] = maxTime.UTC().Format("2006-01-02T15:04:05Z")
|
||||||
}
|
}
|
||||||
|
|
||||||
// query the api
|
// query the api
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
package heliumapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ActivityCounts struct {
|
||||||
|
Data map[string]int
|
||||||
|
}
|
||||||
|
|
||||||
|
type RewardTotal struct {
|
||||||
|
Meta struct {
|
||||||
|
MinTime string `json:"min_time"`
|
||||||
|
MaxTime string `json:"max_time"`
|
||||||
|
} `json:"meta"`
|
||||||
|
|
||||||
|
Data struct {
|
||||||
|
Total float64 `json:"total"`
|
||||||
|
Sum float64 `json:"sum"`
|
||||||
|
Stddev float64 `json:"stddev"`
|
||||||
|
Min float64 `json:"min"`
|
||||||
|
Median float64 `json:"median"`
|
||||||
|
Max float64 `json:"max"`
|
||||||
|
Avg float64 `json:"avg"`
|
||||||
|
} `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetHotspotActivityCount(hotspot string) (*ActivityCounts, error) {
|
||||||
|
path := "/v1/hotspots/" + hotspot + "/activity/count"
|
||||||
|
|
||||||
|
// query the api
|
||||||
|
respBody, err := getHeliumApi(path, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// unmarshal the response
|
||||||
|
respobject := ActivityCounts{}
|
||||||
|
err = json.Unmarshal(respBody, &respobject)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to unmarshal response from path %v: %v", path, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &respobject, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetRewardsTotalForHotspot(hotspot string, minTime *time.Time, maxTime *time.Time) (*RewardTotal, error) {
|
||||||
|
path := "/v1/hotspots/" + hotspot + "/rewards/sum"
|
||||||
|
params := map[string]string{}
|
||||||
|
if minTime != nil {
|
||||||
|
params["min_time"] = minTime.UTC().Format("2006-01-02T15:04:05Z")
|
||||||
|
}
|
||||||
|
if maxTime != nil {
|
||||||
|
params["max_time"] = maxTime.UTC().Format("2006-01-02T15:04:05Z")
|
||||||
|
}
|
||||||
|
|
||||||
|
// query the api
|
||||||
|
respBody, err := getHeliumApi(path, ¶ms)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// unmarshal the response
|
||||||
|
respobject := RewardTotal{}
|
||||||
|
err = json.Unmarshal(respBody, &respobject)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to unmarshal response from path %v: %v", path, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &respobject, nil
|
||||||
|
}
|
Reference in New Issue