Skip to content

Commit

Permalink
add hetzner collector
Browse files Browse the repository at this point in the history
  • Loading branch information
identw committed May 27, 2024
1 parent fb161d3 commit 5f58859
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 26 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ go 1.22

require (
github.com/go-yaml/yaml v2.1.0+incompatible
github.com/nl2go/hrobot-go v0.1.4
github.com/prometheus/client_golang v1.19.1
github.com/prometheus/procfs v0.15.0
)

require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/kr/text v0.1.0 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.53.0 // indirect
golang.org/x/sys v0.20.0 // indirect
Expand Down
16 changes: 4 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
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.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
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=
Expand All @@ -10,35 +8,29 @@ github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwn
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
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/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/nl2go/hrobot-go v0.1.4 h1:tCzFvd/jaUZDue/7snP52NefNclZhNxRhqYAJcsbU1o=
github.com/nl2go/hrobot-go v0.1.4/go.mod h1:VMTP9hTc27eO3zHFkpvmiurLmlH1uxl1/3p3JFu2FEg=
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
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.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE=
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE=
github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U=
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
github.com/prometheus/procfs v0.15.0 h1:A82kmvXJq2jTu5YUhSGNlYoxh85zLnKgPz4bMZgI5Ek=
github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
Expand Down
45 changes: 33 additions & 12 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/orangeAppsRu/custom-exporter/pkg/config"
"github.com/orangeAppsRu/custom-exporter/pkg/filehash"
"github.com/orangeAppsRu/custom-exporter/pkg/hetzner"
"github.com/orangeAppsRu/custom-exporter/pkg/metrics"
"github.com/orangeAppsRu/custom-exporter/pkg/network"
"github.com/orangeAppsRu/custom-exporter/pkg/proc"
Expand All @@ -19,7 +20,7 @@ import (
)

const (
version = "v0.0.5"
version = "v0.0.6"
)

func main() {
Expand Down Expand Up @@ -59,7 +60,7 @@ func main() {

metrics.RegistrMetrics(cfg)

if cfg.FileHashCollector.Enabled {
if cfg.FileHashCollector.Enabled {
go func() {
for {

Expand All @@ -84,7 +85,7 @@ func main() {
}()
}

if cfg.PortCollector.Enabled {
if cfg.PortCollector.Enabled {
go func() {
for {
rTargets := network.CheckTargets(cfg.PortCollector.Targets)
Expand Down Expand Up @@ -120,14 +121,14 @@ func main() {
}
}

if processRunningStatus, err := proc.FindProcessesByRegex(cfg.ProcessCollector.Processes); err != nil {
if processRunningStatus, err := proc.FindProcessesByRegex(cfg.ProcessCollector.Processes); err != nil {
fmt.Printf("Error finding processes: %v\n", err)
} else {
for process, count := range processRunningStatus {
metrics.UpdateProcessRunningStatusMetrics(process, count)
}
}

time.Sleep(60 * time.Second)
}
}()
Expand All @@ -149,14 +150,14 @@ func main() {
} else {
metrics.UpdateUnameChecksumMetrics(unameChecksum)
}
// hostname

// hostname
if hostname, err := os.Hostname(); err != nil {
fmt.Fprintf(os.Stderr, "Error getting hostname: %v\n", err)
} else {
metrics.UpdateHostnameMetrics(hostname)
}

// uptime
if uptime, err := system.UptimeInSeconds(); err != nil {
fmt.Fprintf(os.Stderr, "Error getting uptime: %v\n", err)
Expand All @@ -171,7 +172,6 @@ func main() {
metrics.UpdateLoginUsersCountMetrics(countLoginUsers)
}


time.Sleep(60 * time.Second)
}
}()
Expand All @@ -189,8 +189,29 @@ func main() {
}
}()
}



if cfg.HetznerCollector.Enabled {
hrobotUser := os.Getenv("HROBOT_USER")
if hrobotUser == "" {
fmt.Fprintf(os.Stderr, "Error: env \"HROBOT_USER\" is required if hetznerCollector is enabled\n")
os.Exit(1)
}

hrobotPass := os.Getenv("HROBOT_PASS")
if hrobotPass == "" {
fmt.Fprintf(os.Stderr, "Error: env \"HROBOT_PASS\" is required if hetznerCollector is enabled\n")
os.Exit(1)
}

hetzner := hetzner.NewHetzner(hrobotUser, hrobotPass)
go func() {
for {
metrics.UpdateHetznerServersMetrics(hetzner.GetServers())
time.Sleep(300 * time.Second)
}
}()
}

http.Handle("/metrics", promhttp.Handler())
http.HandleFunc("/ready", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
Expand All @@ -200,4 +221,4 @@ func main() {
if err := http.ListenAndServe(listenAddr, nil); err != nil {
fmt.Printf("Error starting server: %s\n", err)
}
}
}
4 changes: 4 additions & 0 deletions pkg/config/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ type Config struct {
Enabled bool `yaml:"enabled"`
LastRunReportPath string `yaml:"lastRunReportPath"`
} `yaml:"puppetCollector"`

HetznerCollector struct {
Enabled bool `yaml:"enabled"`
} `yaml:"hetznerCollector"`
}


Expand Down
77 changes: 77 additions & 0 deletions pkg/hetzner/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package hetzner

import (
"fmt"
"net"
"strings"
"sync"
"os"

hrobot "github.com/nl2go/hrobot-go"
)

var (
updateServerList sync.Mutex
)

const (
hrobotPeriod = 300
)

type Hetzner struct {
hrobotServers []HrobotServer
hrobot hrobot.RobotClient
}


type HrobotServer struct {
ID int `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
Zone string `json:"zone"`
Region string `json:"region"`
IP net.IP `json:"ip"`
}


func NewHetzner(user string, pass string) (*Hetzner) {
hetzner := Hetzner{}
hetzner.hrobot = hrobot.NewBasicAuthClient(user, pass)
err := hetzner.readHrobotServers()
if err != nil {
fmt.Fprintf(os.Stderr, "Error reading hrobot servers: %v\n", err)
}
return &hetzner
}

func (h *Hetzner) readHrobotServers() error {
servers, err := h.hrobot.ServerGetList()
if err != nil {
return err
}
var hservers []HrobotServer
for _, s := range servers {
zone := strings.ToLower(strings.Split(s.Dc, "-")[0])
server := HrobotServer{
ID: s.ServerNumber,
Name: s.ServerName,
Type: s.Product,
Zone: zone,
Region: strings.ToLower(s.Dc),
IP: net.ParseIP(s.ServerIP),
}
hservers = append(hservers, server)
}
updateServerList.Lock()
h.hrobotServers = hservers
updateServerList.Unlock()
return nil
}

func (h *Hetzner) GetServers() []HrobotServer {
err := h.readHrobotServers()
if err != nil {
fmt.Fprintf(os.Stderr, "Error reading hrobot servers: %v\n", err)
}
return h.hrobotServers
}
32 changes: 31 additions & 1 deletion pkg/metrics/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/orangeAppsRu/custom-exporter/pkg/config"
"github.com/orangeAppsRu/custom-exporter/pkg/filehash"
"github.com/orangeAppsRu/custom-exporter/pkg/network"
"github.com/orangeAppsRu/custom-exporter/pkg/hetzner"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/collectors"
)
Expand Down Expand Up @@ -110,6 +111,14 @@ var (
},
)

hetznerServersGauge = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "hetzner_robot_server",
Help: "Hetzner robot server",
},
[]string{"id", "name", "type", "zone", "region", "ip"},
)


previousHostnameLabel string

Expand All @@ -126,6 +135,7 @@ var (
countLoginUsersMutex sync.Mutex
puppetCatalogLastCompileTimestampMutex sync.Mutex
puppetCatalogLastCompileStatusMutex sync.Mutex
hetznerServersMutex sync.Mutex
)

func RegistrMetrics(cfg config.Config) {
Expand Down Expand Up @@ -159,6 +169,10 @@ func RegistrMetrics(cfg config.Config) {
prometheus.MustRegister(puppetCatalogLastCompileTimestampGauge)
prometheus.MustRegister(puppetCatalogLastCompileStatusGauge)
}

if cfg.HetznerCollector.Enabled {
prometheus.MustRegister(hetznerServersGauge)
}
}

func UpdateFileHashMetrics(filesWithHash []filehash.FileHash) {
Expand Down Expand Up @@ -257,4 +271,20 @@ func UpdatePuppetCatalogLastCompileStatusMetrics(status bool) {
puppetCatalogLastCompileStatusMutex.Lock()
puppetCatalogLastCompileStatusGauge.Set(float64(statusValue))
puppetCatalogLastCompileStatusMutex.Unlock()
}
}

func UpdateHetznerServersMetrics(servers []hetzner.HrobotServer) {
for _, s := range servers {
hetznerServersMutex.Lock()
hetznerServersGauge.With(prometheus.Labels{
"id": strconv.Itoa(s.ID),
"name": s.Name,
"type": s.Type,
"zone": s.Zone,
"region": s.Region,
"ip": s.IP.String(),
}).Set(1)
hetznerServersMutex.Unlock()
}
}

0 comments on commit 5f58859

Please sign in to comment.