dahdi2prometheus/dahdi2prometheus.go

266 lines
6.0 KiB
Go
Raw Permalink Normal View History

2023-01-05 16:55:38 +00:00
// (C) 2022 by Harald Welte <laforge@gnumonks.org>
// SPDX-License-Identifier: Apache-2.0
package main
/*
#include <dahdi/user.h>
*/
import "C"
import (
"fmt"
"flag"
"unsafe"
"syscall"
"acln.ro/ioctl"
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
listen_http = flag.String("http",":2113", "local HTTP listen host:port")
dahdi_ctl int
spanno = promauto.NewGaugeVec(
prometheus.GaugeOpts {
Subsystem: "dahdi",
Name: "spaninfo_span_number",
Help: "span number of this span",
},
[]string{
"span_name",
})
txlevel = promauto.NewGaugeVec(
prometheus.GaugeOpts {
Subsystem: "dahdi",
Name: "spaninfo_txlevel",
Help: "current Tx Level",
},
[]string{
"span_name",
})
rxlevel = promauto.NewGaugeVec(
prometheus.GaugeOpts {
Subsystem: "dahdi",
Name: "spaninfo_rxlevel",
Help: "current Rx Level",
},
[]string{
"span_name",
})
bpvcount = promauto.NewGaugeVec(
prometheus.GaugeOpts {
Subsystem: "dahdi",
Name: "spaninfo_bpv_error_total",
Help: "current BPV (bi-polar violation) count",
},
[]string{
"span_name",
})
crc4count = promauto.NewGaugeVec(
prometheus.GaugeOpts {
Subsystem: "dahdi",
Name: "spaninfo_crc4_error_total",
Help: "current CRC4 error count",
},
[]string{
"span_name",
})
ebitcount = promauto.NewGaugeVec(
prometheus.GaugeOpts {
Subsystem: "dahdi",
Name: "spaninfo_ebit_error_total",
Help: "current E-bit error count",
},
[]string{
"span_name",
})
fascount = promauto.NewGaugeVec(
prometheus.GaugeOpts {
Subsystem: "dahdi",
Name: "spaninfo_fas_error_total",
Help: "current FAS error count",
},
[]string{
"span_name",
})
fecount = promauto.NewGaugeVec(
prometheus.GaugeOpts {
Subsystem: "dahdi",
Name: "spaninfo_framing_error_total",
Help: "current framing error count",
},
[]string{
"span_name",
})
cvcount = promauto.NewGaugeVec(
prometheus.GaugeOpts {
Subsystem: "dahdi",
Name: "spaninfo_coding_violation_total",
Help: "current coding violation error count",
},
[]string{
"span_name",
})
becount = promauto.NewGaugeVec(
prometheus.GaugeOpts {
Subsystem: "dahdi",
Name: "spaninfo_bit_error_total",
Help: "current bit error count",
},
[]string{
"span_name",
})
prbs = promauto.NewGaugeVec(
prometheus.GaugeOpts {
Subsystem: "dahdi",
Name: "spaninfo_prbs",
Help: "current PRBS detected pattern",
},
[]string{
"span_name",
})
errsec = promauto.NewGaugeVec(
prometheus.GaugeOpts {
Subsystem: "dahdi",
Name: "spaninfo_errored_seconds",
Help: "errored seconds",
},
[]string{
"span_name",
})
irqmisses = promauto.NewGaugeVec(
prometheus.GaugeOpts {
Subsystem: "dahdi",
Name: "spaninfo_irq_misses_total",
Help: "current IRQ misses",
},
[]string{
"span_name",
})
syncsrc = promauto.NewGaugeVec(
prometheus.GaugeOpts {
Subsystem: "dahdi",
Name: "spaninfo_sync_source_span",
Help: "span number of current sync source",
},
[]string{
"span_name",
})
numchans = promauto.NewGaugeVec(
prometheus.GaugeOpts {
Subsystem: "dahdi",
Name: "spaninfo_channels_configured_total",
Help: "number of configured channels in this span",
},
[]string{
"span_name",
})
totalchans = promauto.NewGaugeVec(
prometheus.GaugeOpts {
Subsystem: "dahdi",
Name: "spaninfo_channels_total",
Help: "number of channels in this span",
},
[]string{
"span_name",
})
)
/* report one span to prometheus */
func report_span(spaninfo *C.struct_dahdi_spaninfo) {
name := C.GoString(&spaninfo.name[0])
spanno.WithLabelValues(name).Set(float64(spaninfo.spanno))
txlevel.WithLabelValues(name).Set(float64(spaninfo.txlevel))
rxlevel.WithLabelValues(name).Set(float64(spaninfo.rxlevel))
bpvcount.WithLabelValues(name).Set(float64(spaninfo.bpvcount))
crc4count.WithLabelValues(name).Set(float64(spaninfo.crc4count))
ebitcount.WithLabelValues(name).Set(float64(spaninfo.ebitcount))
fascount.WithLabelValues(name).Set(float64(spaninfo.fascount))
fecount.WithLabelValues(name).Set(float64(spaninfo.fecount))
cvcount.WithLabelValues(name).Set(float64(spaninfo.cvcount))
becount.WithLabelValues(name).Set(float64(spaninfo.becount))
prbs.WithLabelValues(name).Set(float64(spaninfo.prbs))
errsec.WithLabelValues(name).Set(float64(spaninfo.errsec))
irqmisses.WithLabelValues(name).Set(float64(spaninfo.irqmisses))
syncsrc.WithLabelValues(name).Set(float64(spaninfo.syncsrc))
numchans.WithLabelValues(name).Set(float64(spaninfo.numchans))
totalchans.WithLabelValues(name).Set(float64(spaninfo.totalchans))
}
/* read spanstat of one span */
func read_span(spaninfo *C.struct_dahdi_spaninfo) {
var spanstat ioctl.WR
//var spaninfo C.struct_dahdi_spaninfo
var err error
spanstat.Name = "DAHDI Spaninfo"
spanstat.Type = 0xDA
spanstat.Nr = 10
spanstat.Size = uint16(unsafe.Sizeof(*spaninfo))
fmt.Println("SPANSTAT ioctl on span ", spaninfo)
if err = spanstat.Exec(dahdi_ctl, unsafe.Pointer(spaninfo)); err != nil {
fmt.Println("spaninfo ", spaninfo)
panic(fmt.Sprintf("Failed to execute ioctl: %s", err))
}
}
/* iterate over all spans, read + report each of them */
func read_spans() {
var spaninfo C.struct_dahdi_spaninfo
//var err error
/* first obtain the total number of spans */
spaninfo.spanno = 1
read_span(&spaninfo)
report_span(&spaninfo)
total_spans := int(spaninfo.totalspans)
/* then iterate over the remainder of them */
for i := 2; i <= total_spans; i++ {
spaninfo.spanno = C.int(i)
read_span(&spaninfo)
report_span(&spaninfo)
}
}
func main() {
var err error
flag.Parse()
if dahdi_ctl, err = syscall.Open("/dev/dahdi/ctl", syscall.O_RDWR, 0775); err != nil {
panic(fmt.Sprintf("Failed to open DAHDI ctl: %s", err))
}
read_spans()
fmt.Println("Listening to HTTP requests at", *listen_http)
http.Handle("/metrics", promhttp.Handler())
http.ListenAndServe(*listen_http, nil)
}