From 29f6f511fea3bfd5a3de38a33726983aded3fe72 Mon Sep 17 00:00:00 2001 From: Pablo Castellano Date: Mon, 3 Jun 2024 00:40:45 +0200 Subject: [PATCH] Add docker support --- Dockerfile | 11 ++++ Makefile | 5 +- README.md | 11 +++- main.go | 182 ++++++++++++++++++++++++++--------------------------- 4 files changed, 115 insertions(+), 94 deletions(-) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f15b559 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +FROM golang:1.22 as builder +WORKDIR /app +COPY go.mod go.sum ./ +RUN go mod download +COPY . . +RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o swarm-batch-exporter . + +FROM scratch +COPY --from=builder /app/swarm-batch-exporter /swarm-batch-exporter +EXPOSE 1640 +ENTRYPOINT ["/swarm-batch-exporter"] diff --git a/Makefile b/Makefile index 6945e37..b99609c 100644 --- a/Makefile +++ b/Makefile @@ -1,2 +1,5 @@ build: - go build -o swarm-exporter + go build -o swarm-batch-exporter + +docker: + docker build . -t swarm-batch-exporter diff --git a/README.md b/README.md index ef87d3a..f207634 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Swarm batch prometheus exporter -This is a simple prometheus exporter to expose Stamp batch metrics for Ethereum Swarm. +This is a simple [Prometheus](https://prometheus.io/) exporter to expose stamp batch metrics for [Ethereum Swarm](https://www.ethswarm.org/). ## Usage @@ -13,7 +13,7 @@ make build 2. Run ``` -./swarm-exporter +./swarm-batch-exporter ``` 3. Scrape @@ -22,6 +22,13 @@ make build curl http://localhost:1640 ``` +### Docker + +``` +make docker +docker run --rm --network host swarm-batch-exporter +``` + ## Metrics * `swarm_stamp_batch_available_bytes` (gauge) diff --git a/main.go b/main.go index bd29794..2aaf66f 100644 --- a/main.go +++ b/main.go @@ -1,126 +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" + "encoding/json" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" + "log" + "math" + "net/http" + "os" + "time" ) type APIResponse struct { - Stamps []Stamp `json:"stamps"` + 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"` + 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"}) + 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) + 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 + return math.Pow(2, float64(depth)) * 4096 } func GetStampUsage(utilization, depth, bucketDepth int) float64 { - return float64(utilization) / math.Pow(2, float64(depth-bucketDepth)) + 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)) + url := os.Getenv("BEE_ENDPOINT") + if url == "" { + url = "http://localhost:1633/stamps" + } + resp, err := http.Get(url) + 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 + } + + 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) + 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) + 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)) - } + 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)) + go func() { + for { + fetchMetrics() + time.Sleep(5 * time.Minute) + } + }() + http.Handle("/metrics", promhttp.Handler()) + log.Fatal(http.ListenAndServe(":1640", nil)) }