Created
June 17, 2023 07:09
-
-
Save zekroTJA/ae40a1b702cc099eb8e22e601ec43a09 to your computer and use it in GitHub Desktop.
A simple exporter accumulating Redis Keys and exposing a Prometheus metrics exporter endpoint.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module exporter | |
go 1.20 | |
require ( | |
github.com/cespare/xxhash/v2 v2.1.2 // indirect | |
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect | |
github.com/go-redis/redis/v8 v8.11.5 // indirect | |
github.com/joho/godotenv v1.5.1 | |
github.com/kelseyhightower/envconfig v1.4.0 // indirect | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"fmt" | |
"log" | |
"net/http" | |
"strings" | |
"github.com/go-redis/redis/v8" | |
"github.com/joho/godotenv" | |
"github.com/kelseyhightower/envconfig" | |
) | |
type Config struct { | |
RedisAddr string | |
RedisDb int | |
Addr string `default:"0.0.0.0:9091"` | |
} | |
func getCounts(c *redis.Client) (map[string]int, error) { | |
keys, err := c.Keys(context.Background(), "dgrs:message:*").Result() | |
if err != nil { | |
return nil, err | |
} | |
m := map[string]int{} | |
for _, key := range keys { | |
key = key[13:] | |
i := strings.IndexRune(key, ':') | |
key = key[:i] | |
m[key] += 1 | |
} | |
return m, nil | |
} | |
func metricsHandler(c *redis.Client) http.HandlerFunc { | |
return func(w http.ResponseWriter, r *http.Request) { | |
m, err := getCounts(c) | |
if err != nil { | |
w.WriteHeader(http.StatusInternalServerError) | |
w.Write([]byte(err.Error())) | |
return | |
} | |
w.WriteHeader(http.StatusOK) | |
for guildId, count := range m { | |
fmt.Fprintf(w, | |
"msgstats_messages_total{guild=\"%s\"} %d\n", | |
guildId, count) | |
} | |
} | |
} | |
func main() { | |
godotenv.Load() | |
var cfg Config | |
err := envconfig.Process("exp", &cfg) | |
if err != nil { | |
log.Fatal("Failed parsing config:", err) | |
} | |
fmt.Printf("cfg: %+v\n", cfg) | |
c := redis.NewClient(&redis.Options{ | |
Addr: cfg.RedisAddr, | |
DB: cfg.RedisDb, | |
}) | |
_, err = c.Ping(context.Background()).Result() | |
if err != nil { | |
log.Fatal("Redis connection failed:", err) | |
} | |
mux := http.NewServeMux() | |
mux.HandleFunc("/metrics", metricsHandler(c)) | |
log.Printf("Starting web server on %s ...", cfg.Addr) | |
err = http.ListenAndServe(cfg.Addr, mux) | |
if err != nil { | |
log.Fatal("Failed starting web server:", err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment