Skip to content

Commit

Permalink
Swarm batch prometheus exporter
Browse files Browse the repository at this point in the history
  • Loading branch information
PabloCastellano committed Jun 2, 2024
0 parents commit f5fe721
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
swarm-exporter
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build:
go build -o swarm-exporter
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Swarm batch prometheus exporter

This is a simple prometheus exporter to expose Stamp batch metrics for Ethereum Swarm.

## Usage

1. Compile

```
make build
```

2. Run

```
./swarm-exporter
```

3. Scrape

```
curl http://localhost:1640
```
14 changes: 14 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module swarm-batch-exporter

go 1.21.4

require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/prometheus/client_golang v1.19.1 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.48.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
golang.org/x/sys v0.17.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
)
16 changes: 16 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE=
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
126 changes: 126 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package main

import (
"encoding/json"
"net/http"
"log"
"math"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)

type APIResponse struct {
Stamps []Stamp `json:"stamps"`
}

type Stamp struct {
BatchID string `json:"batchID"`
Utilization int `json:"utilization"`
Usable bool `json:"usable"`
Label string `json:"label"`
Depth int `json:"depth"`
Amount string `json:"amount"`
BucketDepth int `json:"bucketDepth"`
BlockNumber int `json:"blockNumber"`
ImmutableFlag bool `json:"immutableFlag"`
Exists bool `json:"exists"`
BatchTTL int `json:"batchTTL"`
}

// Declare the metrics
var (
utilizationMetric = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "swarm_stamp_batch_utilization",
Help: "Stamp batch utilization.",
}, []string{"batchID", "label"})
ttlMetric = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "swarm_stamp_batch_ttl",
Help: "Stamp batch TTL.",
}, []string{"batchID", "label"})
depthMetric = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "swarm_stamp_batch_depth",
Help: "Stamp batch depth.",
}, []string{"batchID", "label"})
amountMetric = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "swarm_stamp_batch_amount",
Help: "Stamp batch amount.",
}, []string{"batchID", "label"})
capacityMetric = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "swarm_stamp_batch_capacity_bytes",
Help: "Stamp batch total capacity in bytes.",
}, []string{"batchID", "label"})
availabilityMetric = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "swarm_stamp_batch_available_bytes",
Help: "Stamp batch available capacity in bytes.",
}, []string{"batchID", "label"})
usageMetric = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "swarm_stamp_batch_usage_percentage",
Help: "Stamp batch usage percentage.",
}, []string{"batchID", "label"})
)

func init() {
prometheus.MustRegister(utilizationMetric)
prometheus.MustRegister(ttlMetric)
prometheus.MustRegister(depthMetric)
prometheus.MustRegister(amountMetric)
prometheus.MustRegister(capacityMetric)
prometheus.MustRegister(availabilityMetric)
prometheus.MustRegister(usageMetric)
}

func GetStampMaximumCapacityBytes(depth int) float64 {
return math.Pow(2, float64(depth)) * 4096
}

func GetStampUsage(utilization, depth, bucketDepth int) float64 {
return float64(utilization) / math.Pow(2, float64(depth-bucketDepth))

}

func fetchMetrics() {
resp, err := http.Get("http://localhost:1633/stamps")
if err != nil {
log.Println("Error fetching data:", err)
return
}
defer resp.Body.Close()

var apiResponse APIResponse
if err := json.NewDecoder(resp.Body).Decode(&apiResponse); err != nil {
log.Println("Error decoding JSON data:", err)
return
}

// Update Prometheus metrics
for _, stamp := range apiResponse.Stamps {
utilizationMetric.With(prometheus.Labels{"batchID": stamp.BatchID, "label": stamp.Label}).Set(float64(stamp.Utilization))
ttlMetric.With(prometheus.Labels{"batchID": stamp.BatchID, "label": stamp.Label}).Set(float64(stamp.BatchTTL))
depthMetric.With(prometheus.Labels{"batchID": stamp.BatchID, "label": stamp.Label}).Set(float64(stamp.Depth))
//amountMetric.With(prometheus.Labels{"batchID": stamp.BatchID, "label": stamp.Label}).Set(float64(stamp.Amount))

capacity := GetStampMaximumCapacityBytes(stamp.Depth)
capacityMetric.With(prometheus.Labels{"batchID": stamp.BatchID, "label": stamp.Label}).Set(capacity)

stampUsage := GetStampUsage(stamp.Utilization, stamp.Depth, stamp.BucketDepth)
usageMetric.With(prometheus.Labels{"batchID": stamp.BatchID, "label": stamp.Label}).Set(stampUsage)

available := int(stampUsage * capacity)
availabilityMetric.With(prometheus.Labels{"batchID": stamp.BatchID, "label": stamp.Label}).Set(float64(available))
}
}

func main() {
// Setup fetchMetrics to run periodically
go func() {
for {
fetchMetrics()
time.Sleep(5 * time.Minute) // Adjust fetch interval as needed
}
}()

// Setup HTTP server
http.Handle("/metrics", promhttp.Handler())
log.Fatal(http.ListenAndServe(":1640", nil))
}

0 comments on commit f5fe721

Please sign in to comment.