Add importer for global RRD stats
This commit is contained in:
parent
d57d864ab0
commit
75228cf8bf
24
main.go
24
main.go
|
@ -17,6 +17,7 @@ import (
|
||||||
"github.com/FreifunkBremen/respond-collector/database"
|
"github.com/FreifunkBremen/respond-collector/database"
|
||||||
"github.com/FreifunkBremen/respond-collector/models"
|
"github.com/FreifunkBremen/respond-collector/models"
|
||||||
"github.com/FreifunkBremen/respond-collector/respond"
|
"github.com/FreifunkBremen/respond-collector/respond"
|
||||||
|
"github.com/FreifunkBremen/respond-collector/rrd"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -28,12 +29,19 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
var importPath string
|
||||||
|
flag.StringVar(&importPath, "import", "", "import global statistics from the given RRD file, requires influxdb")
|
||||||
flag.StringVar(&configFile, "config", "config.yml", "path of configuration file (default:config.yaml)")
|
flag.StringVar(&configFile, "config", "config.yml", "path of configuration file (default:config.yaml)")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
config = models.ReadConfigFile(configFile)
|
config = models.ReadConfigFile(configFile)
|
||||||
|
|
||||||
if config.Influxdb.Enable {
|
if config.Influxdb.Enable {
|
||||||
db = database.New(config)
|
db = database.New(config)
|
||||||
|
|
||||||
|
if importPath != "" {
|
||||||
|
importRRD(importPath)
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes = models.NewNodes(config)
|
nodes = models.NewNodes(config)
|
||||||
|
@ -74,3 +82,19 @@ func main() {
|
||||||
db.Close()
|
db.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func importRRD(path string) {
|
||||||
|
log.Println("importing RRD from", path)
|
||||||
|
for ds := range rrd.Read(path) {
|
||||||
|
db.AddPoint(
|
||||||
|
database.MeasurementGlobal,
|
||||||
|
nil,
|
||||||
|
map[string]interface{}{
|
||||||
|
"nodes": ds.Nodes,
|
||||||
|
"clients.total": ds.Clients,
|
||||||
|
},
|
||||||
|
ds.Time,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
db.Close()
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
// Importer for global RRD stats
|
||||||
|
package rrd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"io"
|
||||||
|
"os/exec"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var linePattern = regexp.MustCompile("^<!-- ....-..-.. ..:..:.. [A-Z]+ / (\\d+) --> <row><v>([^<]+)</v><v>([^<]+)</v></row>")
|
||||||
|
|
||||||
|
type Dataset struct {
|
||||||
|
Time time.Time
|
||||||
|
Nodes float64
|
||||||
|
Clients float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func Read(rrdFile string) chan Dataset {
|
||||||
|
out := make(chan Dataset)
|
||||||
|
cmd := exec.Command("rrdtool", "dump", rrdFile)
|
||||||
|
stdout, err := cmd.StdoutPipe()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := cmd.Start(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
r := bufio.NewReader(stdout)
|
||||||
|
found := false
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
// Read stdout by line
|
||||||
|
line, _, err := r.ReadLine()
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
str := strings.TrimSpace(string(line))
|
||||||
|
|
||||||
|
// Search for the start of the daily datasets
|
||||||
|
if !found {
|
||||||
|
found = strings.Contains(str, "<!-- 86400 seconds -->")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if matches := linePattern.FindStringSubmatch(str); matches != nil && matches[2] != "NaN" {
|
||||||
|
seconds, _ := strconv.Atoi(matches[1])
|
||||||
|
nodes, _ := strconv.ParseFloat(matches[2], 64)
|
||||||
|
clients, _ := strconv.ParseFloat(matches[2], 64)
|
||||||
|
|
||||||
|
out <- Dataset{
|
||||||
|
Time: time.Unix(int64(seconds), 0),
|
||||||
|
Nodes: nodes,
|
||||||
|
Clients: clients,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(out)
|
||||||
|
}()
|
||||||
|
return out
|
||||||
|
}
|
Loading…
Reference in New Issue