diff --git a/.gitignore b/.gitignore index 5b90e79..d87f9fa 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ go.work.sum # env file .env +config.yaml \ No newline at end of file diff --git a/config.yaml.example b/config.yaml.example new file mode 100644 index 0000000..6665d4d --- /dev/null +++ b/config.yaml.example @@ -0,0 +1,6 @@ +target: + instance: + userID: +exporter: + listen: 0.0.0.0 + port: 9666 \ No newline at end of file diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000..f59119d --- /dev/null +++ b/config/config.go @@ -0,0 +1,42 @@ +package config + +import ( + "log" + "os" + + "gopkg.in/yaml.v3" +) + +type target struct { + Instance string `yaml:"instance"` + UserID string `yaml:"userID"` +} + +type exporter struct { + Listen string `yaml:"listen"` + Port string `yaml:"port"` +} + +type InstanceVars struct { + Target target `yaml:"target"` + Exporter exporter `yaml:"exporter"` +} + +func OpenFile(path string) []byte { + file, err := os.ReadFile(path) + if err != nil { + log.Println(err) + } + return file +} + +func UnmYamlConfig(path string) InstanceVars { + fileContent := OpenFile(path) + var config InstanceVars + + err := yaml.Unmarshal(fileContent, &config) + if err != nil { + log.Println(err) + } + return config +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..5ce2018 --- /dev/null +++ b/go.mod @@ -0,0 +1,20 @@ +module pleroma_stats_exporter + +go 1.21 + +toolchain go1.23.4 + +require github.com/prometheus/client_golang v1.20.5 + +require gopkg.in/yaml.v3 v3.0.1 + +require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.62.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect + golang.org/x/sys v0.29.0 // indirect + google.golang.org/protobuf v1.36.4 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..b2b5d19 --- /dev/null +++ b/go.sum @@ -0,0 +1,31 @@ +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.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= +github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM= +google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index f1b2e21..af68edd 100644 --- a/main.go +++ b/main.go @@ -2,13 +2,39 @@ package main import ( "encoding/json" - "fmt" "io" "log" "net/http" + "pleroma_stats_exporter/config" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" ) -type JsonInterface interface{} +type metrics struct { + InstancesCount prometheus.Gauge + FollowersCount prometheus.Gauge +} + +func SetMetricsOpts(reg prometheus.Registerer) *metrics { + metricsOpts := &metrics{ + InstancesCount: prometheus.NewGauge( + prometheus.GaugeOpts{ + Name: "pleroma_instances_count", + Help: "Количество инстансов", + }, + ), + FollowersCount: prometheus.NewGauge( + prometheus.GaugeOpts{ + Name: "pleroma_user_followers", + Help: "Количество подписчиков", + }, + ), + } + reg.MustRegister(metricsOpts.InstancesCount) + reg.MustRegister(metricsOpts.FollowersCount) + return metricsOpts +} func getJson(url string) string { resp, err := http.Get(url) @@ -17,11 +43,14 @@ func getJson(url string) string { } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) + if err != nil { + log.Println(err) + } return string(body) } -func unmJson(jsonString string) JsonInterface { - var decodedJson JsonInterface +func unmJson(jsonString string) map[string]any { + decodedJson := map[string]any{} err := json.Unmarshal([]byte(jsonString), &decodedJson) if err != nil { log.Println(err) @@ -30,6 +59,16 @@ func unmJson(jsonString string) JsonInterface { } func main() { - fmt.Println(unmJson(getJson("https://pleroma.catgirls.asia/api/v1/instance"))) + confFile := config.UnmYamlConfig("config.yaml") + reg := prometheus.NewRegistry() + instanceMetrics := SetMetricsOpts(reg) + instanceStat := unmJson(getJson("https://" + confFile.Target.Instance + "/api/v1/instance"))["stats"] + instanceCount := instanceStat.(map[string]interface{}) + userFollowers := unmJson(getJson("https://" + confFile.Target.Instance + "/api/v1/accounts/" + confFile.Target.UserID))["followers_count"] + instanceMetrics.InstancesCount.Set(instanceCount["domain_count"].(float64)) + instanceMetrics.FollowersCount.Set(userFollowers.(float64)) + + http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{Registry: reg})) + log.Fatal(http.ListenAndServe(confFile.Exporter.Listen+":"+confFile.Exporter.Port, nil)) }