Skip to content

Commit

Permalink
feat: change jicofo metrics prefix (+refactor)
Browse files Browse the repository at this point in the history
  • Loading branch information
hrenard committed Aug 12, 2022
1 parent c397c46 commit 4cdc3e8
Show file tree
Hide file tree
Showing 10 changed files with 886 additions and 424 deletions.
444 changes: 439 additions & 5 deletions README.md

Large diffs are not rendered by default.

21 changes: 0 additions & 21 deletions pkg/cmd/jicofo.go

This file was deleted.

21 changes: 0 additions & 21 deletions pkg/cmd/jvb.go

This file was deleted.

33 changes: 23 additions & 10 deletions pkg/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,43 @@ import (
"net/http"

"github.com/jitsi-contrib/jitsi-exporter/pkg/generic"
"github.com/jitsi-contrib/jitsi-exporter/pkg/jicofo"
"github.com/jitsi-contrib/jitsi-exporter/pkg/jvb"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

var metricsPath, metricsAddr, logLevel string
var prober generic.Prober
var metricsPath, metricsAddr, logLevel, jicofoUrl, jvbUrl string
var httpClient = &http.Client{
Transport: &http.Transport{
MaxIdleConns: 100,
},
}

var rootCmd = &cobra.Command{
Use: "jitsi-exporter",
Short: "A Prometheus exporter for Jitsi. Supports Jicofo and JVB.",
PersistentPreRun: func(cmd *cobra.Command, args []string) {
Use: "jitsi-exporter [components]",
Short: "A Prometheus exporter for Jitsi. Supports Jicofo and JVB.",
ValidArgs: []string{"jicofo", "jvb"},
Args: cobra.MatchAll(cobra.RangeArgs(1, 2), cobra.OnlyValidArgs),
Run: func(cmd *cobra.Command, args []string) {
lvl, _ := log.ParseLevel(logLevel)
log.SetLevel(lvl)

log.Info("Starting Jitsi Colibri Exporter")
},
PersistentPostRun: func(cmd *cobra.Command, args []string) {
collector := generic.NewCollector(prober)
prometheus.MustRegister(collector)

collectors := []prometheus.Collector{}
for _, arg := range args {
if arg == "jicofo" {
log.Info("Collect Jicofo metrics")
collectors = append(collectors, generic.NewCollector(httpClient, jicofoUrl, jicofo.Metrics))
}
if arg == "jvb" {
log.Info("Collect JVB metrics")
collectors = append(collectors, generic.NewCollector(httpClient, jvbUrl, jvb.Metrics))
}
}
prometheus.MustRegister(collectors...)

http.Handle(metricsPath, promhttp.Handler())
log.Fatal(http.ListenAndServe(metricsAddr, nil))
Expand All @@ -44,4 +55,6 @@ func init() {
rootCmd.PersistentFlags().StringVar(&metricsPath, "path", "/metrics", "Path of the metrics")
rootCmd.PersistentFlags().StringVar(&metricsAddr, "address", ":9210", "Address to listen")
rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "info", "Log level.")
rootCmd.Flags().StringVar(&jicofoUrl, "jicofo-url", "http://127.0.0.1:8888/stats", "URL of the Jicofo stats endpoint")
rootCmd.Flags().StringVar(&jvbUrl, "jvb-url", "http://127.0.0.1:8080/colibri/stats", "URL of the JVB stats endpoint")
}
48 changes: 48 additions & 0 deletions pkg/generic/basic_metric.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package generic

import "github.com/prometheus/client_golang/prometheus"

type BasicMetricOptions struct {
component string
variableLabels []string
constLabels prometheus.Labels
getLabels LabelGetter
}

type BasicMetricOption func(*BasicMetricOptions)

func NewBasicMetric(path string, valueType prometheus.ValueType, help string, opts ...BasicMetricOption) Metric {
options := &BasicMetricOptions{}
for _, apply := range opts {
apply(options)
}
return NewMetric(
prometheus.NewDesc(
prometheus.BuildFQName(Namespace, options.component, PathToMetricName(path)), help, options.variableLabels, options.constLabels),
FloatGetter(path, valueType, options.getLabels),
)
}

func WithComponent(component string) BasicMetricOption {
return func(opts *BasicMetricOptions) {
opts.component = component
}
}

func WithVariableLabels(variableLabels []string) BasicMetricOption {
return func(opts *BasicMetricOptions) {
opts.variableLabels = variableLabels
}
}

func WithConstLabels(constLabels prometheus.Labels) BasicMetricOption {
return func(opts *BasicMetricOptions) {
opts.constLabels = constLabels
}
}

func WithLabelGetter(getLabels LabelGetter) BasicMetricOption {
return func(opts *BasicMetricOptions) {
opts.getLabels = getLabels
}
}
59 changes: 59 additions & 0 deletions pkg/generic/collector.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package generic

import (
"io"
"net/http"

"github.com/prometheus/client_golang/prometheus"
log "github.com/sirupsen/logrus"
)

type Collector struct {
client *http.Client
target string
metrics []Metric
}

func NewCollector(client *http.Client, target string, metrics []Metric) *Collector {
return &Collector{
client: client,
target: target,
metrics: metrics,
}
}

func (c *Collector) Describe(ch chan<- *prometheus.Desc) {
for _, m := range c.metrics {
ch <- m.desc
}
}

func (c *Collector) Collect(ch chan<- prometheus.Metric) {
data, err := c.probe()

if err != nil {
log.Error(err)
return
}

for _, m := range c.metrics {
pm := m.get(m.desc, data)
if pm != nil {
ch <- pm
}
}
}

func (c *Collector) probe() (string, error) {
resp, err := c.client.Get(c.target)
if err != nil {
return "", err
}
defer resp.Body.Close()

data, err := io.ReadAll(resp.Body)
if err != nil {
return "", err
}
return string(data), nil
}
133 changes: 38 additions & 95 deletions pkg/generic/generic.go
Original file line number Diff line number Diff line change
@@ -1,97 +1,40 @@
package generic

import (
"regexp"

"github.com/prometheus/client_golang/prometheus"
"github.com/tidwall/gjson"
)

type MetricDecription struct {
ValueType prometheus.ValueType
Path string
Help string
}

type MetricGetter func(string, Prober) prometheus.Metric

type Prober interface {
Name() string
Probe() (string, bool)
MetricGetters() []MetricGetter
Labels() []string
}

type Collector struct {
prober Prober
}

func NewMetricDecription(valueType prometheus.ValueType, path, help string) MetricDecription {
return MetricDecription{
ValueType: valueType,
Path: path,
Help: help,
}
}

func NewCollector(prober Prober) *Collector {
return &Collector{prober: prober}
}

func (c *Collector) Describe(ch chan<- *prometheus.Desc) {
prometheus.DescribeByCollect(c, ch)
}

func (c *Collector) Collect(ch chan<- prometheus.Metric) {
data, ok := c.prober.Probe()

var up float64
if ok {
up = 1
}
ch <- prometheus.MustNewConstMetric(
prometheus.NewDesc(prometheus.BuildFQName("jitsi", c.prober.Name(), "up"), "", c.prober.Labels(), nil), prometheus.GaugeValue, up, getLabels(data, c.prober)...)

for _, getter := range c.prober.MetricGetters() {
ch <- getter(data, c.prober)
}
}

func NewMetricGetter(valueType prometheus.ValueType, path, help string) MetricGetter {
return newMetricGetter(valueType, PathToMetricName(path), help, func(data string) float64 {
return gjson.Get(data, path).Float()
})
}

func NewBoolMetricGetter(valueType prometheus.ValueType, path, help string) MetricGetter {
return newMetricGetter(valueType, PathToMetricName(path), help, func(data string) float64 {
var value float64
if gjson.Get(data, path).Bool() {
value = 1
}
return value
})
}

func PathToMetricName(path string) string {
regex := regexp.MustCompile(`\.|-`)
return regex.ReplaceAllString(path, "_")
}

func newMetricGetter(valueType prometheus.ValueType, name, help string, valueGetter func(data string) float64) MetricGetter {
return func(data string, p Prober) prometheus.Metric {
labels := getLabels(data, p)
return prometheus.MustNewConstMetric(
prometheus.NewDesc(prometheus.BuildFQName("jitsi", p.Name(), name), help, p.Labels(), nil),
prometheus.GaugeValue,
valueGetter(data), labels...)
}
}

func getLabels(data string, p Prober) []string {
labels := make([]string, len(p.Labels()))
for k, v := range p.Labels() {
labels[k] = gjson.Get(data, v).String()
}
return labels
}
// func NewMetricGetter(valueType prometheus.ValueType, path, help string) MetricGetter {
// return newMetricGetter(valueType, PathToMetricName(path), help, func(data string) float64 {
// return gjson.Get(data, path).Float()
// })
// }

// func NewBoolMetricGetter(valueType prometheus.ValueType, path, help string) MetricGetter {
// return newMetricGetter(valueType, PathToMetricName(path), help, func(data string) float64 {
// var value float64
// if gjson.Get(data, path).Bool() {
// value = 1
// }
// return value
// })
// }

// func PathToMetricName(path string) string {
// regex := regexp.MustCompile(`\.|-`)
// return regex.ReplaceAllString(path, "_")
// }

// func newMetricGetter(valueType prometheus.ValueType, name, help string, valueGetter func(data string) float64) MetricGetter {
// return func(data string, p Prober) prometheus.Metric {
// labels := getLabels(data, p)
// return prometheus.MustNewConstMetric(
// prometheus.NewDesc(prometheus.BuildFQName("jitsi", p.Name(), name), help, p.Labels(), nil),
// prometheus.GaugeValue,
// valueGetter(data), labels...)
// }
// }

// func getLabels(data string, p Prober) []string {
// labels := make([]string, len(p.Labels()))
// for k, v := range p.Labels() {
// labels[k] = gjson.Get(data, v).String()
// }
// return labels
// }
Loading

0 comments on commit 4cdc3e8

Please sign in to comment.