You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
4.9 KiB
163 lines
4.9 KiB
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/namsral/flag"
|
|
"net/http"
|
|
"time"
|
|
"os"
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
var station string
|
|
var debug bool
|
|
var reportList = make(map[string]report)
|
|
var metricpath string
|
|
var mysql_host string
|
|
var mysql_db string
|
|
var mysql_user string
|
|
var mysql_pass string
|
|
var mysql_table string
|
|
var port int
|
|
//var promcalls bool
|
|
var trace bool
|
|
var useProm bool
|
|
var useMysql bool
|
|
|
|
|
|
func usage() {
|
|
fmt.Printf("Usage of %s:\n", os.Args[0])
|
|
flag.PrintDefaults()
|
|
}
|
|
|
|
func init() {
|
|
flag.StringVar(&station, "station", "", "callsign to monitor on pskreporter")
|
|
flag.StringVar(&mysql_host, "dbhost", "db", "name/ip of mysql host")
|
|
flag.StringVar(&mysql_db, "db", "digimode_stats", "db name")
|
|
flag.StringVar(&mysql_user, "dbuser", "wsjtx", "mysql username")
|
|
flag.StringVar(&mysql_pass, "dbpass", "secret", "mysql password")
|
|
flag.StringVar(&mysql_table, "dbtable", "pskreporter_stats", "mysql table name")
|
|
flag.StringVar(&metricpath, "metricpath", "/metrics", "path for prometheus metric endpoint")
|
|
flag.IntVar(&port, "port", 2113, "port for prometheus metric endpoint")
|
|
flag.BoolVar(&useProm, "prometheus", false, "activate prometheus exporter")
|
|
flag.BoolVar(&useMysql, "mysql", false, "activate mysql exporter")
|
|
// flag.BoolVar(&promcalls, "promcalls", false, "activate prometheus callsign metrics")
|
|
flag.BoolVar(&trace, "trace", false, "log almost everything")
|
|
flag.BoolVar(&debug, "debug", false, "enable debug logging")
|
|
|
|
flag.Parse()
|
|
|
|
formatter := &log.TextFormatter{
|
|
FullTimestamp: true,
|
|
}
|
|
log.SetFormatter(formatter)
|
|
|
|
if trace {
|
|
log.SetLevel(log.TraceLevel)
|
|
log.Info("trace logging enabled")
|
|
} else {
|
|
log.Info("normal logging enabled")
|
|
}
|
|
|
|
if !useProm && !useMysql {
|
|
usage()
|
|
log.Fatal("you have to enable at least one exporter. see -mysql and -prometheus flags")
|
|
}
|
|
|
|
if useProm {
|
|
log.Info("prometheus exporter enabled..")
|
|
}
|
|
|
|
if useMysql {
|
|
log.Info("mysql exporter enabled..")
|
|
|
|
// wait for stupid mysql container to come up..
|
|
_, db_down := dbConn()
|
|
for db_down {
|
|
log.Info("waiting for db to come up..")
|
|
time.Sleep(2 * time.Second)
|
|
_, db_down = dbConn()
|
|
}
|
|
|
|
init_db()
|
|
}
|
|
}
|
|
|
|
func handleResults(reports chan report) {
|
|
for {
|
|
select {
|
|
case report := <- reports :
|
|
_ , seen := reportList[report.CallSign]
|
|
// check if receiver is known
|
|
if seen {
|
|
// check if fetched record is newer than existing one
|
|
if report.lastReport > reportList[report.CallSign].lastReport {
|
|
log.WithFields(log.Fields{
|
|
"Callsign":report.CallSign,
|
|
"Report":report.Signal,
|
|
"Grid":report.Grid,
|
|
"Geohash":report.GeoHash,
|
|
"Mode":report.Mode,
|
|
"Continent":report.Continent,
|
|
"LastReport":report.lastReport,
|
|
"ITUZone":fmt.Sprintf("%d",report.ITUZone),
|
|
"CQZone":fmt.Sprintf("%d",report.CQZone),
|
|
"DXCC":report.Dxcc,
|
|
}).Trace("known receiver with fresh report")
|
|
|
|
if useProm {
|
|
handlePrometheus(report)
|
|
}
|
|
if useMysql {
|
|
handleMysql(report)
|
|
}
|
|
// put in cache
|
|
reportList[report.CallSign] = report
|
|
} else { // just hit an old entry, no need to store
|
|
log.Trace("known receiver with known report")
|
|
}
|
|
} else {
|
|
// FIXME is it safe that lastReport is the last Report from the other station or is it the last Report he reported us?
|
|
// if it is the last, the check could be wrong :-/
|
|
// -> add debugging output to check!
|
|
if report.lastReport > (time.Now().Unix() - 300) {
|
|
log.WithFields(log.Fields{
|
|
"Callsign":report.CallSign,
|
|
"Report":report.Signal,
|
|
"Grid":report.Grid,
|
|
"Geohash":report.GeoHash,
|
|
"Mode":report.Mode,
|
|
"Continent":report.Continent,
|
|
"LastReport":report.lastReport,
|
|
"ITUZone":fmt.Sprintf("%d",report.ITUZone),
|
|
"CQZone":fmt.Sprintf("%d",report.CQZone),
|
|
"DXCC":report.Dxcc,
|
|
}).Trace("unknown receiver with fresh report")
|
|
if useProm {
|
|
handlePrometheus(report)
|
|
}
|
|
if useMysql {
|
|
handleMysql(report)
|
|
}
|
|
} else {
|
|
log.Trace("unknown receiver with old report")
|
|
}
|
|
// put in cache
|
|
reportList[report.CallSign] = report
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
func main(){
|
|
reports := make(chan report)
|
|
|
|
go fetchReports(reports)
|
|
go handleResults(reports)
|
|
|
|
log.Infof("listening on :%d%s",port, metricpath)
|
|
http.Handle(metricpath, promhttp.Handler())
|
|
http.ListenAndServe(fmt.Sprintf(":%d",port), nil)
|
|
}
|
|
|