mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-23 12:31:07 +01:00
b09272ccac
Some checks are pending
build / Build (push) Waiting to run
CodeQL Go / Analyze (push) Waiting to run
main / lint (push) Waiting to run
main / test (test-full) (push) Blocked by required conditions
main / test (test-full-386) (push) Blocked by required conditions
main / test (test-pure) (push) Blocked by required conditions
publish-docs / Build (push) Waiting to run
1. Avoid storing the last evaluation results outside of rules, check for stale time series as soon as possible; 2. remove duplicated template `Clone()`. This pull request is primarily reducing memory usage when rules produce large volumes of results, as seen in https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6894. The CPU time spent on garbage collection remains high and may be addressed in a separate PR.
108 lines
2.2 KiB
Go
108 lines
2.2 KiB
Go
package rule
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/datasource"
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal"
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promrelabel"
|
|
)
|
|
|
|
// newTimeSeries first sorts given labels, then returns new time series.
|
|
func newTimeSeries(values []float64, timestamps []int64, labels []prompbmarshal.Label) prompbmarshal.TimeSeries {
|
|
promrelabel.SortLabels(labels)
|
|
ts := prompbmarshal.TimeSeries{
|
|
Labels: labels,
|
|
Samples: make([]prompbmarshal.Sample, len(values)),
|
|
}
|
|
for i := range values {
|
|
ts.Samples[i] = prompbmarshal.Sample{
|
|
Value: values[i],
|
|
Timestamp: time.Unix(timestamps[i], 0).UnixNano() / 1e6,
|
|
}
|
|
}
|
|
return ts
|
|
}
|
|
|
|
type curlWriter struct {
|
|
b strings.Builder
|
|
}
|
|
|
|
func (cw *curlWriter) string() string {
|
|
res := "curl " + cw.b.String()
|
|
cw.b.Reset()
|
|
return strings.TrimSpace(res)
|
|
}
|
|
|
|
func (cw *curlWriter) addWithEsc(str string) {
|
|
escStr := `'` + strings.Replace(str, `'`, `'\''`, -1) + `'`
|
|
cw.add(escStr)
|
|
}
|
|
|
|
func (cw *curlWriter) add(str string) {
|
|
cw.b.WriteString(str)
|
|
cw.b.WriteString(" ")
|
|
}
|
|
|
|
func requestToCurl(req *http.Request) string {
|
|
if req == nil || req.URL == nil {
|
|
return ""
|
|
}
|
|
|
|
cw := &curlWriter{}
|
|
|
|
schema := req.URL.Scheme
|
|
requestURL := req.URL.String()
|
|
if !datasource.ShowDatasourceURL() {
|
|
requestURL = req.URL.Redacted()
|
|
}
|
|
if schema == "" {
|
|
schema = "http"
|
|
if req.TLS != nil {
|
|
schema = "https"
|
|
}
|
|
requestURL = schema + "://" + req.Host + requestURL
|
|
}
|
|
|
|
if schema == "https" {
|
|
cw.add("-k")
|
|
}
|
|
|
|
cw.add("-X")
|
|
cw.add(req.Method)
|
|
|
|
var keys []string
|
|
for k := range req.Header {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Strings(keys)
|
|
|
|
for _, k := range keys {
|
|
cw.add("-H")
|
|
if !datasource.ShowDatasourceURL() && isSecreteHeader(k) {
|
|
cw.addWithEsc(fmt.Sprintf("%s: <secret>", k))
|
|
continue
|
|
}
|
|
cw.addWithEsc(fmt.Sprintf("%s: %s", k, strings.Join(req.Header[k], " ")))
|
|
}
|
|
|
|
cw.addWithEsc(requestURL)
|
|
return cw.string()
|
|
}
|
|
|
|
var secretWords = []string{"auth", "pass", "key", "secret", "token"}
|
|
|
|
func isSecreteHeader(str string) bool {
|
|
s := strings.ToLower(str)
|
|
for _, secret := range secretWords {
|
|
if strings.Contains(s, secret) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|