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.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

164 lines
4.9 KiB

4 years ago
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, "host", "db", "name/ip of mysql host")
4 years ago
flag.StringVar(&mysql_db, "db", "digimode_stats", "db name")
flag.StringVar(&mysql_user, "user", "wsjtx", "mysql username")
flag.StringVar(&mysql_pass, "pass", "secret", "mysql password")
flag.StringVar(&mysql_table, "table", "pskreporter_stats", "mysql table name")
4 years ago
flag.StringVar(&metricpath, "metricpath", "/metrics", "path for prometheus metric endpoint")
4 years ago
flag.IntVar(&port, "port", 2113, "port for prometheus metric endpoint")
4 years ago
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)
}