dahdi2prometheus/dahdi2prometheus.go

266 lines
6.0 KiB
Go
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// (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)
}