100 lines
2.0 KiB
Go
100 lines
2.0 KiB
Go
package woodpecker
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"git.stinnesbeck.com/go/log"
|
|
)
|
|
|
|
type Server struct {
|
|
Host string `json:"host"`
|
|
Token string `json:"token"`
|
|
}
|
|
|
|
type Stats struct {
|
|
PendingJobs int `json:"woodpecker_pending_jobs"`
|
|
RunningJobs int `json:"woodpecker_running_jobs"`
|
|
IdlingWorkers int `json:"woodpecker_worker_count"`
|
|
}
|
|
|
|
// NewServer returns a Server object for host
|
|
func NewServer(host string, token string) Server {
|
|
switch {
|
|
case strings.HasPrefix(host, "http://"), strings.HasPrefix(host, "https://"):
|
|
return Server{
|
|
Host: host,
|
|
Token: token,
|
|
}
|
|
default:
|
|
log.PrintError("host needs to start with 'http://' or 'https://'")
|
|
os.Exit(1)
|
|
return Server{}
|
|
}
|
|
}
|
|
|
|
func (s Server) GetStats() (*Stats, error) {
|
|
// prepare request
|
|
req, err := http.NewRequest(http.MethodGet, s.Host+"/metrics/", nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// add authorization header
|
|
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", s.Token))
|
|
|
|
c := http.DefaultClient
|
|
response, err := c.Do(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
b, err := io.ReadAll(response.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
lines := strings.Split(string(b), "\n")
|
|
|
|
r := regexp.MustCompile(`^((woodpecker_)(worker_count|pending_jobs|running_jobs)) (\d+)`)
|
|
|
|
var stats Stats
|
|
|
|
for i := range lines {
|
|
// skip rest of loop if this line doesn't match regex
|
|
if !r.MatchString(lines[i]) {
|
|
continue
|
|
}
|
|
|
|
// line matches regex
|
|
matches := r.FindStringSubmatch(lines[i])
|
|
|
|
// assign stats to struct
|
|
switch matches[3] {
|
|
case "pending_jobs":
|
|
stats.PendingJobs = parseStringToInt(matches[4])
|
|
case "running_jobs":
|
|
stats.RunningJobs = parseStringToInt(matches[4])
|
|
case "worker_count":
|
|
stats.IdlingWorkers = parseStringToInt(matches[4])
|
|
}
|
|
}
|
|
|
|
return &stats, nil
|
|
}
|
|
|
|
// parseStringToInt parses a string and returns the resulting uint
|
|
func parseStringToInt(s string) int {
|
|
num, err := strconv.Atoi(s)
|
|
if err != nil {
|
|
log.PrintError("can't parse string to uint,", err)
|
|
os.Exit(1)
|
|
}
|
|
return num
|
|
}
|