Skip to content

Commit

Permalink
add metrics from etherpad api, adjust logging
Browse files Browse the repository at this point in the history
  • Loading branch information
0x46616c6b committed Mar 21, 2021
1 parent 96b546d commit fa33b19
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 18 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ go install github.com/systemli/prometheus-etherpad-exporter
$GOPATH/bin/prometheus-etherpad-exporter
```

### Commandline options

```
-web.listen-address ":9011" # Address on which to expose metrics and web interface.
-etherpad.url "http://localhost:9001" # URL to connect with Etherpad
-etherpad.api-token "" # "API Token for Etherpad"
```

With configured API Token the metrics `etherpad_total_pads`, `etherpad_total_sessions` and `etherpad_total_active_pads` will appended to the metrics

### Docker

```
Expand All @@ -21,6 +31,15 @@ docker run -p 9011:9011 systemli/prometheus-etherpad-exporter:latest -etherpad.u
## Metrics

```
# HELP etherpad_total_pads
# TYPE etherpad_total_pads gauge
etherpad_total_pads 8
# HELP etherpad_total_sessions
# TYPE etherpad_total_sessions gauge
etherpad_total_sessions 0
# HELP etherpad_total_active_pads
# TYPE etherpad_total_active_pads gauge
etherpad_total_active_pads 0
# HELP etherpad_memory_usage
# TYPE etherpad_memory_usage gauge
etherpad_memory_usage{type="total"} 102801408
Expand Down
6 changes: 5 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@ module github.com/systemli/prometheus-etherpad-exporter

go 1.16

require github.com/google/go-cmp v0.5.5 // indirect
require (
github.com/google/go-cmp v0.5.5 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4 // indirect
)
9 changes: 9 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4 h1:EZ2mChiOa8udjfp6rRmswTbtZN/QzUQp4ptM4rnjHvc=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
81 changes: 64 additions & 17 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@ package main
import (
"encoding/json"
"flag"
"log"
"fmt"
"net/http"
"os"
"text/template"

log "github.com/sirupsen/logrus"
)

var (
addr = flag.String("web.listen-address", ":9011", "Address on which to expose metrics and web interface.")
etherpadURL = flag.String("etherpad.url", "http://localhost:9001", "URL to connect with Etherpad")
addr = flag.String("web.listen-address", ":9011", "Address on which to expose metrics and web interface.")
etherpadURL = flag.String("etherpad.url", "http://localhost:9001", "URL to connect with Etherpad")
etherpadAPIToken = flag.String("etherpad.api-token", "", "API Token for Etherpad")
)

type etherpadStats struct {
Expand All @@ -24,6 +28,16 @@ type etherpadStats struct {
Edits edits `json:"edits"`
}

type etherpadAPIStats struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
TotalPads int `json:"totalPads"`
TotalSessions int `json:"totalSessions"`
TotalActivePads int `json:"totalActivePads"`
} `json:"data"`
}

type httpRequests struct {
Meter meter `json:"meter"`
Histogram histogram `json:"histogram"`
Expand Down Expand Up @@ -58,7 +72,7 @@ type histogram struct {
P999 float64 `json:"p999"`
}

var tpl = template.Must(template.New("stats").Parse(`# HELP etherpad_memory_usage
var statsTpl = template.Must(template.New("stats").Parse(`# HELP etherpad_memory_usage
# TYPE etherpad_memory_usage gauge
etherpad_memory_usage{type="total"} {{.MemoryUsage}}
etherpad_memory_usage{type="heap"} {{.MemoryUsageHeap}}
Expand All @@ -79,43 +93,76 @@ etherpad_connects {{.Connects.Count}}
etherpad_connects {{.Edits.Meter.Count}}
`))

var apiStatsTpl = template.Must(template.New("apiStats").Parse(`# HELP etherpad_total_pads
# TYPE etherpad_total_pads gauge
etherpad_total_pads {{.Data.TotalPads}}
# HELP etherpad_total_sessions
# TYPE etherpad_total_sessions gauge
etherpad_total_sessions {{.Data.TotalSessions}}
# HELP etherpad_total_active_pads
# TYPE etherpad_total_active_pads gauge
etherpad_total_active_pads {{.Data.TotalActivePads}}
`))

type handler struct {
etherpadURL string
etherpadURL string
etherpadAPIToken string
}

func (h handler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
resp, err := http.Get(h.etherpadURL + "/stats")
res, err := http.Get(h.etherpadURL + "/stats")
if err != nil {
log.Printf("scrape error: %v", err)
log.WithError(err).Error("error while fetching /stats from etherpad")
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer resp.Body.Close()
defer res.Body.Close()

var stats etherpadStats
if err := json.NewDecoder(resp.Body).Decode(&stats); err != nil {
log.Printf("json decoding error: %v", err)
if err := json.NewDecoder(res.Body).Decode(&stats); err != nil {
log.WithError(err).Error("error while decoding json")
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

if h.etherpadAPIToken != "" {
res, err := http.Get(h.etherpadURL + fmt.Sprintf("/api/1.2.14/getStats?apikey=%s", h.etherpadAPIToken))
if err != nil {
log.WithError(err).Error("error while fetching /getStats from etherpad api")
}
defer res.Body.Close()

var apiStats etherpadAPIStats
if err := json.NewDecoder(res.Body).Decode(&apiStats); err != nil {
log.WithError(err).Error("error while decoding json")
}

err = apiStatsTpl.Execute(w, &apiStats)
if err != nil {
log.WithError(err).Error("error while executing template for apiStats")
}
}

w.Header().Set("Content-Type", "text/plain")
err = tpl.Execute(w, &stats)
err = statsTpl.Execute(w, &stats)
if err != nil {
log.Printf("template error: %v", err)
log.WithError(err).Error("error while executing template for stats")
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}

func init() {
log.SetFormatter(&log.JSONFormatter{})
log.SetOutput(os.Stdout)
}

func main() {
log.SetFlags(0)
flag.Parse()

http.Handle("/metrics", handler{etherpadURL: *etherpadURL})
log.Info("Started Etherpad Metrics Exporter")
http.Handle("/metrics", handler{etherpadURL: *etherpadURL, etherpadAPIToken: *etherpadAPIToken})
if err := http.ListenAndServe(*addr, nil); err != nil {
log.Fatal(err)
log.WithError(err).Error("error while try to start exporter")
}

log.Println("Started Etherpad Metrics Exporter")
}

0 comments on commit fa33b19

Please sign in to comment.