Giter Club home page Giter Club logo

hetzner_exporter's Introduction

Hetzner Exporter

Current Tag General Build Join the Matrix chat at https://matrix.to/#/#webhippie:matrix.org Codacy Badge Go Doc Go Report

An exporter for Prometheus that collects metrics from Hetzner.

Install

You can download prebuilt binaries from our GitHub releases, or you can use our containers published on Docker Hub and Quay. If you need further guidance how to install this take a look at our documentation.

Development

Make sure you have a working Go environment, for further reference or a guide take a look at the install instructions. This project requires Go >= v1.17, at least that's the version we are using.

git clone https://github.com/promhippie/hetzner_exporter.git
cd hetzner_exporter

make generate build

./bin/hetzner_exporter -h

Security

If you find a security issue please contact [email protected] first.

Contributing

Fork -> Patch -> Push -> Pull Request

Authors

License

Apache-2.0

Copyright

Copyright (c) 2018 Thomas Boerger <[email protected]>

hetzner_exporter's People

Contributors

albertogviana avatar dependabot[bot] avatar renovate-bot avatar renovate[bot] avatar tboerger avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

hetzner_exporter's Issues

Provide some documentation

So far we already prepared some simple Hugo documentation. It should get some content to guide the installation.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Repository problems

These problems occurred while renovating this repository. View logs.

  • WARN: Use matchDepNames instead of matchPackageNames

This repository currently has no open or pending branches.

Detected dependencies

dockerfile
docker/Dockerfile.linux.386
  • i386/alpine 3.19@sha256:15c46ced65c6abed6a27472a7904b04273e9a8091a5627badd6ff016ab073171
docker/Dockerfile.linux.amd64
  • alpine 3.19@sha256:6457d53fb065d6f250e1504b9bc42d5b6c65941d57532c072d929dd0628977d0
docker/Dockerfile.linux.arm
  • arm32v6/alpine 3.19@sha256:b229a85166aadbde58e73e03c5e2b9737fb4642ffb2d98ba453adc90d144c1d8
docker/Dockerfile.linux.arm64
  • arm64v8/alpine 3.19@sha256:a0264d60f80df12bc1e6dd98bae6c43debe6667c0ba482711f0d806493467a46
github-actions
.github/workflows/automerge.yml
  • tibdex/github-app-token v2
  • dependabot/fetch-metadata v2
.github/workflows/binaries.yml
  • actions/checkout v4
  • actions/setup-go v5
  • actionhippie/gpgsign v1
  • actionhippie/calens v1
  • ncipollo/release-action v1
.github/workflows/changes.yml
  • actions/checkout v4
  • actions/checkout v4
  • actions/setup-go v5
  • EndBug/add-and-commit v9
  • actions/checkout v4
  • actions/checkout v4
  • actions/setup-go v5
  • EndBug/add-and-commit v9
  • actions/checkout v4
  • actions/checkout v4
  • actions/setup-go v5
  • EndBug/add-and-commit v9
.github/workflows/docker.yml
  • actions/checkout v4
  • actions/setup-go v5
  • docker/metadata-action v5
  • docker/setup-qemu-action v3
  • docker/setup-buildx-action v3
  • docker/login-action v3
  • docker/login-action v3
  • docker/login-action v3
  • docker/build-push-action v5
  • actions/checkout v4
  • docker/metadata-action v5
  • actionhippie/manifest v1
  • docker/metadata-action v5
  • actionhippie/manifest v1
  • docker/metadata-action v5
  • actionhippie/manifest v1
  • actions/checkout v4
  • actionhippie/pushrm v1
  • actionhippie/pushrm v1
.github/workflows/docs.yml
  • actions/checkout v4
  • peaceiris/actions-hugo v3
  • peaceiris/actions-gh-pages v4
.github/workflows/general.yml
  • actions/checkout v4
  • actions/setup-go v5
  • codacy/codacy-coverage-reporter-action v1
.github/workflows/kustomize.yml
  • actions/checkout v4
  • actionhippie/kustomize v2
gomod
go.mod
  • go 1.21
  • go 1.22.3
  • github.com/dustin/go-humanize v1.0.1
  • github.com/go-chi/chi/v5 v5.0.12
  • github.com/go-kit/log v0.2.1
  • github.com/joho/godotenv v1.5.1
  • github.com/oklog/run v1.1.0
  • github.com/prometheus/client_golang v1.19.0
  • github.com/prometheus/exporter-toolkit v0.11.0
  • github.com/stretchr/testify v1.9.0
  • github.com/urfave/cli/v2 v2.27.2
kustomize
deploy/kubernetes/kustomization.yml

  • Check this box to trigger a request for Renovate to run again on this repository

Export transactions

The upstream client library is not correctly working for transactions, we should fix that and implement the exporter afterward. Here is an example how the collector could look like:

package exporter

import (
	"fmt"
	"time"

	"github.com/appscode/go-hetzner"
	"github.com/go-kit/kit/log"
	"github.com/go-kit/kit/log/level"
	"github.com/prometheus/client_golang/prometheus"
)

// TransactionCollector collects metrics about the SSH keys.
type TransactionCollector struct {
	client   *hetzner.Client
	logger   log.Logger
	failures *prometheus.CounterVec
	duration *prometheus.HistogramVec
	timeout  time.Duration

	Dummy *prometheus.Desc
}

// NewTransactionCollector returns a new TransactionCollector.
func NewTransactionCollector(logger log.Logger, client *hetzner.Client, failures *prometheus.CounterVec, duration *prometheus.HistogramVec, timeout time.Duration) *TransactionCollector {
	failures.WithLabelValues("transaction").Add(0)

	labels := []string{"id"}
	return &TransactionCollector{
		client:   client,
		logger:   logger,
		failures: failures,
		duration: duration,
		timeout:  timeout,

		Dummy: prometheus.NewDesc(
			"hetzner_transaction_dummy",
			"Dummy help",
			labels,
			nil,
		),
	}
}

// Describe sends the super-set of all possible descriptors of metrics collected by this Collector.
func (c *TransactionCollector) Describe(ch chan<- *prometheus.Desc) {
	ch <- c.Dummy
}

// Collect is called by the Prometheus registry when collecting metrics.
func (c *TransactionCollector) Collect(ch chan<- prometheus.Metric) {
	now := time.Now()
	transactions, _, err := c.client.WithTimeout(c.timeout).Ordering.ListTransactions()
	c.duration.WithLabelValues("transaction").Observe(time.Since(now).Seconds())

	if err != nil {
		level.Error(c.logger).Log(
			"msg", "Failed to fetch transactions",
			"err", err,
		)

		c.failures.WithLabelValues("transaction").Inc()
		return
	}

	level.Debug(c.logger).Log(
		"msg", "Fetched transactions",
		"count", len(transactions),
	)

	for _, transaction := range transactions {

		level.Debug(c.logger).Log(
			"record", fmt.Sprintf("%+v", transaction),
		)

		labels := []string{
			transaction.ID,
		}

		ch <- prometheus.MustNewConstMetric(
			c.Dummy,
			prometheus.GaugeValue,
			0.0,
			labels...,
		)
	}
}

Export products

The upstream client library is not correctly working for products, we should fix that and implement the exporter afterward. Here is an example how the collector could look like:

package exporter

import (
	"fmt"
	"strconv"
	"time"

	"github.com/appscode/go-hetzner"
	"github.com/go-kit/kit/log"
	"github.com/go-kit/kit/log/level"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/dustin/go-humanize"
)

// ProductCollector collects metrics about the SSH keys.
type ProductCollector struct {
	client   *hetzner.Client
	logger   log.Logger
	failures *prometheus.CounterVec
	duration *prometheus.HistogramVec
	timeout  time.Duration

	Up *prometheus.Desc
	Traffic *prometheus.Desc
	SetupVat *prometheus.Desc
	Setup *prometheus.Desc
	PriceVat *prometheus.Desc
	Price *prometheus.Desc
}

// NewProductCollector returns a new ProductCollector.
func NewProductCollector(logger log.Logger, client *hetzner.Client, failures *prometheus.CounterVec, duration *prometheus.HistogramVec, timeout time.Duration) *ProductCollector {
	failures.WithLabelValues("product").Add(0)

	labels := []string{"id", "name"}
	return &ProductCollector{
		client:   client,
		logger:   logger,
		failures: failures,
		duration: duration,
		timeout:  timeout,

		Up: prometheus.NewDesc(
			"hetzner_product_up",
			"1 if the product is available",
			labels,
			nil,
		),
		Traffic: prometheus.NewDesc(
			"hetzner_product_traffic_bytes",
			"Show the inclusive traffic for this product",
			labels,
			nil,
		),
		SetupVat: prometheus.NewDesc(
			"hetzner_product_setup_vat_euro",
			"Setup VAT for the product in €",
			labels,
			nil,
		),
		Setup: prometheus.NewDesc(
			"hetzner_product_setup_euro",
			"Setup fee for the product in €",
			labels,
			nil,
		),
		PriceVat: prometheus.NewDesc(
			"hetzner_product_price_vat_euro",
			"Monthly VAT for the product in €",
			labels,
			nil,
		),
		Price: prometheus.NewDesc(
			"hetzner_product_price_euro",
			"Monthly fee for the product in €",
			labels,
			nil,
		),
	}
}

// Describe sends the super-set of all possible descriptors of metrics collected by this Collector.
func (c *ProductCollector) Describe(ch chan<- *prometheus.Desc) {
	ch <- c.Up
	ch <- c.Traffic
	ch <- c.SetupVat
	ch <- c.Setup
	ch <- c.PriceVat
	ch <- c.Price
}

// Collect is called by the Prometheus registry when collecting metrics.
func (c *ProductCollector) Collect(ch chan<- prometheus.Metric) {
	now := time.Now()
	products, _, err := c.client.WithTimeout(c.timeout).Ordering.ListProducts()
	c.duration.WithLabelValues("product").Observe(time.Since(now).Seconds())

	if err != nil {
		level.Error(c.logger).Log(
			"msg", "Failed to fetch products",
			"err", err,
		)

		c.failures.WithLabelValues("product").Inc()
		return
	}

	level.Debug(c.logger).Log(
		"msg", "Fetched products",
		"count", len(products),
	)

	for _, product := range products {
		var (
			traffic float64
			setup float64
			setupVat float64
			price float64
			priceVat float64
		)

		labels := []string{
			product.ID,
			product.Name,
		}

		ch <- prometheus.MustNewConstMetric(
			c.Up,
			prometheus.GaugeValue,
			1.0,
			labels...,
		)

		if num, err := humanize.ParseBytes(product.Traffic); err == nil {
			traffic = float64(num)
		}

		ch <- prometheus.MustNewConstMetric(
			c.Traffic,
			prometheus.GaugeValue,
			traffic,
			labels...,
		)

		if num, err := strconv.ParseFloat(product.PriceSetup, 64); err == nil {
			setup = num
		}

		ch <- prometheus.MustNewConstMetric(
			c.Setup,
			prometheus.GaugeValue,
			setup,
			labels...,
		)

		if num, err := strconv.ParseFloat(product.PriceSetupVat, 64); err == nil {
			setupVat = num
		}

		ch <- prometheus.MustNewConstMetric(
			c.SetupVat,
			prometheus.GaugeValue,
			setupVat,
			labels...,
		)

		if num, err := strconv.ParseFloat(product.Price, 64); err == nil {
			price = num
		}

		ch <- prometheus.MustNewConstMetric(
			c.Price,
			prometheus.GaugeValue,
			price,
			labels...,
		)

		if num, err := strconv.ParseFloat(product.PriceVat, 64); err == nil {
			priceVat = num
		}

		ch <- prometheus.MustNewConstMetric(
			c.PriceVat,
			prometheus.GaugeValue,
			priceVat,
			labels...,
		)
	}
}

Drop darwin/386 release builds

We got to drop the darwin/386 builds, they are not supported by the used Go version anymore. Soonish we should also add arm64 builds to stay compatible with current macOS hardware.

Initial release of basic version

Just prepare an initial version of the exporter which scrapes the most basic
metrics and defines the basic exporter structure.

Storagebox metrics

Hey,
I just found the project and I have to say its awesome. After setting it up I noticed that there are no metrics for Hetzner Storage boxes since they are also managed via the Robot I think adding metrics for those would be quite nice.

Make collectors configurable

So far all collectors are executed, but I'm sure there are cases where only a subset should be enabled. Let's add some option for that.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.