266 lines
6.0 KiB
Go
266 lines
6.0 KiB
Go
// (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)
|
||
|
||
|
||
}
|