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