Add importer for global RRD stats

This commit is contained in:
Julian Kornberger 2016-10-03 19:56:02 +02:00
parent d57d864ab0
commit 75228cf8bf
2 changed files with 90 additions and 0 deletions

24
main.go
View File

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

66
rrd/rrd.go Normal file
View File

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