2018-03-21 02:28:10 +01:00
|
|
|
package collector
|
|
|
|
|
|
|
|
import (
|
2020-12-06 18:08:44 +01:00
|
|
|
"fmt"
|
2018-09-11 05:30:13 +02:00
|
|
|
"math"
|
2020-12-06 18:08:44 +01:00
|
|
|
"regexp"
|
2018-09-11 05:30:13 +02:00
|
|
|
"strconv"
|
2018-03-21 02:28:10 +01:00
|
|
|
"strings"
|
2020-12-06 18:08:44 +01:00
|
|
|
"time"
|
2018-03-21 02:28:10 +01:00
|
|
|
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
2020-12-06 18:08:44 +01:00
|
|
|
log "github.com/sirupsen/logrus"
|
2018-03-21 02:28:10 +01:00
|
|
|
)
|
|
|
|
|
2020-12-06 18:08:44 +01:00
|
|
|
var durationRegex *regexp.Regexp
|
2021-07-28 21:26:27 +02:00
|
|
|
var durationParts [6]time.Duration
|
2020-12-06 18:08:44 +01:00
|
|
|
|
|
|
|
func init() {
|
2021-07-28 21:26:27 +02:00
|
|
|
durationRegex = regexp.MustCompile(`(?:(\d*)w)?(?:(\d*)d)?(?:(\d*)h)?(?:(\d*)m)?(?:(\d*)s)?(?:(\d*)ms)?`)
|
|
|
|
durationParts = [6]time.Duration{time.Hour * 168, time.Hour * 24, time.Hour, time.Minute, time.Second, time.Millisecond}
|
2020-12-06 18:08:44 +01:00
|
|
|
}
|
|
|
|
|
2018-03-21 02:28:10 +01:00
|
|
|
func metricStringCleanup(in string) string {
|
|
|
|
return strings.Replace(in, "-", "_", -1)
|
|
|
|
}
|
|
|
|
|
|
|
|
func descriptionForPropertyName(prefix, property string, labelNames []string) *prometheus.Desc {
|
2020-02-10 19:55:10 +01:00
|
|
|
return descriptionForPropertyNameHelpText(prefix, property, labelNames, property)
|
|
|
|
}
|
|
|
|
|
|
|
|
func descriptionForPropertyNameHelpText(prefix, property string, labelNames []string, helpText string) *prometheus.Desc {
|
2018-03-21 02:28:10 +01:00
|
|
|
return prometheus.NewDesc(
|
|
|
|
prometheus.BuildFQName(namespace, prefix, metricStringCleanup(property)),
|
2020-02-10 19:55:10 +01:00
|
|
|
helpText,
|
2018-03-21 02:28:10 +01:00
|
|
|
labelNames,
|
|
|
|
nil,
|
|
|
|
)
|
|
|
|
}
|
2018-04-11 15:21:38 +02:00
|
|
|
|
|
|
|
func description(prefix, name, helpText string, labelNames []string) *prometheus.Desc {
|
|
|
|
return prometheus.NewDesc(
|
2021-07-28 21:26:27 +02:00
|
|
|
prometheus.BuildFQName(namespace, prefix, metricStringCleanup(name)),
|
2018-04-11 15:21:38 +02:00
|
|
|
helpText,
|
|
|
|
labelNames,
|
|
|
|
nil,
|
|
|
|
)
|
|
|
|
}
|
2018-09-11 05:30:13 +02:00
|
|
|
|
|
|
|
func splitStringToFloats(metric string) (float64, float64, error) {
|
2019-08-21 04:11:03 +02:00
|
|
|
strs := strings.Split(metric, ",")
|
2019-12-03 04:01:36 +01:00
|
|
|
if len(strs) == 0 {
|
|
|
|
return 0, 0, nil
|
|
|
|
}
|
2019-08-21 04:11:03 +02:00
|
|
|
m1, err := strconv.ParseFloat(strs[0], 64)
|
2018-09-11 05:30:13 +02:00
|
|
|
if err != nil {
|
|
|
|
return math.NaN(), math.NaN(), err
|
|
|
|
}
|
2019-08-21 04:11:03 +02:00
|
|
|
m2, err := strconv.ParseFloat(strs[1], 64)
|
2018-09-11 05:30:13 +02:00
|
|
|
if err != nil {
|
|
|
|
return math.NaN(), math.NaN(), err
|
|
|
|
}
|
|
|
|
return m1, m2, nil
|
|
|
|
}
|
2020-12-06 18:08:44 +01:00
|
|
|
|
|
|
|
func parseDuration(duration string) (float64, error) {
|
|
|
|
var u time.Duration
|
|
|
|
|
|
|
|
reMatch := durationRegex.FindAllStringSubmatch(duration, -1)
|
|
|
|
|
|
|
|
// should get one and only one match back on the regex
|
|
|
|
if len(reMatch) != 1 {
|
|
|
|
return 0, fmt.Errorf("invalid duration value sent to regex")
|
|
|
|
} else {
|
|
|
|
for i, match := range reMatch[0] {
|
|
|
|
if match != "" && i != 0 {
|
|
|
|
v, err := strconv.Atoi(match)
|
|
|
|
if err != nil {
|
|
|
|
log.WithFields(log.Fields{
|
|
|
|
"duration": duration,
|
|
|
|
"value": match,
|
|
|
|
"error": err,
|
|
|
|
}).Error("error parsing duration field value")
|
|
|
|
return float64(0), err
|
|
|
|
}
|
|
|
|
u += time.Duration(v) * durationParts[i-1]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return u.Seconds(), nil
|
|
|
|
}
|