2020-11-29 05:44:21 +05:00
|
|
|
package application
|
|
|
|
|
|
|
|
import (
|
|
|
|
"log"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Parses passed body and returns a map suitable for pushing into storage.
|
|
|
|
func (a *Application) parse(body string) map[string]string {
|
|
|
|
data := make(map[string]string)
|
|
|
|
|
|
|
|
// ToDo: switch to bytes buffer and maybe do not read body in caller?
|
|
|
|
splittedBody := strings.Split(body, "\n")
|
|
|
|
|
|
|
|
for _, line := range splittedBody {
|
|
|
|
// Prometheus line contains metric name and metric parameters defined
|
|
|
|
// in "{}".
|
|
|
|
var (
|
|
|
|
name, value string
|
|
|
|
params []string
|
|
|
|
)
|
|
|
|
|
|
|
|
// Skip empty lines.
|
|
|
|
if line == "" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that line isn't commented. We should skip comments for now.
|
|
|
|
if strings.HasPrefix(line, "#") {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Println("Analyzing line:", line)
|
|
|
|
|
|
|
|
// Check if we have parametrized metric. If no - push it to data map.
|
|
|
|
if !strings.Contains(line, "{") {
|
|
|
|
name = strings.Split(line, " ")[0]
|
|
|
|
value = strings.Split(line, " ")[1]
|
|
|
|
} else {
|
|
|
|
value = strings.Split(line, " ")[1]
|
|
|
|
name = strings.Split(line, "{")[0]
|
2020-11-29 05:49:45 +05:00
|
|
|
params = a.getParametersForPrometheusMetric(line)
|
2020-11-29 05:44:21 +05:00
|
|
|
|
2020-11-29 05:49:45 +05:00
|
|
|
for _, param := range params {
|
|
|
|
name += "/" + param
|
|
|
|
}
|
|
|
|
}
|
2020-11-29 05:44:21 +05:00
|
|
|
|
2020-11-29 05:49:45 +05:00
|
|
|
data[name] = value
|
|
|
|
}
|
2020-11-29 05:44:21 +05:00
|
|
|
|
2020-11-29 05:49:45 +05:00
|
|
|
log.Printf("Data parsed: %+v\n", data)
|
2020-11-29 05:44:21 +05:00
|
|
|
|
2020-11-29 05:49:45 +05:00
|
|
|
return data
|
|
|
|
}
|
2020-11-29 05:44:21 +05:00
|
|
|
|
2020-11-29 05:49:45 +05:00
|
|
|
// Parses passed line and returns a slice of strings with parameters parsed.
|
|
|
|
func (a *Application) getParametersForPrometheusMetric(line string) []string {
|
|
|
|
valuesString := strings.Split(strings.Split(line, "{")[1], "}")[0]
|
2020-11-29 05:44:21 +05:00
|
|
|
|
2020-11-29 05:49:45 +05:00
|
|
|
var (
|
|
|
|
params []string
|
|
|
|
paramName, paramValue string
|
|
|
|
paramNameFinished, paramValueStarted, paramValueFinished bool
|
|
|
|
)
|
2020-11-29 05:44:21 +05:00
|
|
|
|
2020-11-29 05:49:45 +05:00
|
|
|
for _, r := range valuesString {
|
|
|
|
if paramValueFinished && string(r) == "," {
|
|
|
|
params = append(params, paramName+":"+paramValue)
|
|
|
|
paramName, paramValue = "", ""
|
|
|
|
paramNameFinished, paramValueStarted, paramValueFinished = false, false, false
|
2020-11-29 05:44:21 +05:00
|
|
|
|
2020-11-29 05:49:45 +05:00
|
|
|
continue
|
|
|
|
}
|
2020-11-29 05:44:21 +05:00
|
|
|
|
2020-11-29 05:49:45 +05:00
|
|
|
// Sometimes nestif causes questions, like here. Is code below is
|
|
|
|
// "deply nested"? I think not. So:
|
|
|
|
// nolint:nestif
|
|
|
|
if !paramNameFinished {
|
|
|
|
if string(r) != "=" {
|
|
|
|
paramName += string(r)
|
2020-11-29 05:44:21 +05:00
|
|
|
|
2020-11-29 05:49:45 +05:00
|
|
|
continue
|
|
|
|
} else {
|
|
|
|
paramNameFinished = true
|
2020-11-29 05:44:21 +05:00
|
|
|
|
2020-11-29 05:49:45 +05:00
|
|
|
continue
|
2020-11-29 05:44:21 +05:00
|
|
|
}
|
2020-11-29 05:49:45 +05:00
|
|
|
} else {
|
|
|
|
if string(r) == "\"" && !paramValueStarted {
|
|
|
|
paramValueStarted = true
|
2020-11-29 05:44:21 +05:00
|
|
|
|
2020-11-29 05:49:45 +05:00
|
|
|
continue
|
2020-11-29 05:44:21 +05:00
|
|
|
}
|
|
|
|
|
2020-11-29 05:49:45 +05:00
|
|
|
if paramValueStarted && string(r) != "\"" {
|
|
|
|
paramValue += string(r)
|
|
|
|
|
|
|
|
continue
|
2020-11-29 05:44:21 +05:00
|
|
|
}
|
|
|
|
|
2020-11-29 05:49:45 +05:00
|
|
|
if paramValueStarted && string(r) == "\"" {
|
|
|
|
paramValueFinished = true
|
|
|
|
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
2020-11-29 05:44:21 +05:00
|
|
|
}
|
|
|
|
|
2020-11-29 05:49:45 +05:00
|
|
|
if paramName != "" && paramValue != "" {
|
|
|
|
params = append(params, paramName+":"+paramValue)
|
|
|
|
}
|
2020-11-29 05:44:21 +05:00
|
|
|
|
2020-11-29 05:49:45 +05:00
|
|
|
return params
|
2020-11-29 05:44:21 +05:00
|
|
|
}
|