mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-25 05:34:05 -08:00
feat: make push metrics labels generic and repeatable
Signed-off-by: François Gouteroux <francois.gouteroux@gmail.com>
This commit is contained in:
parent
3524a16aa0
commit
934c5ddb8d
|
@ -187,7 +187,7 @@ func main() {
|
|||
"metric-files",
|
||||
"The metric files to push, default is read from standard input (STDIN).",
|
||||
).ExistingFiles()
|
||||
metricJobLabel := pushMetricsCmd.Flag("job-label", "Job label to attach to metrics.").Default("promtool").String()
|
||||
pushMetricsLabels := pushMetricsCmd.Flag("label", "Label to attach to metrics. Can be specified multiple times.").Default("job=promtool").StringMap()
|
||||
pushMetricsTimeout := pushMetricsCmd.Flag("timeout", "The time to wait for pushing metrics.").Default("30s").Duration()
|
||||
pushMetricsHeaders := pushMetricsCmd.Flag("header", "Prometheus remote write header.").StringMap()
|
||||
|
||||
|
@ -315,7 +315,7 @@ func main() {
|
|||
os.Exit(CheckMetrics(*checkMetricsExtended))
|
||||
|
||||
case pushMetricsCmd.FullCommand():
|
||||
os.Exit(PushMetrics(remoteWriteURL, httpRoundTripper, *pushMetricsHeaders, *pushMetricsTimeout, *metricJobLabel, *metricFiles...))
|
||||
os.Exit(PushMetrics(remoteWriteURL, httpRoundTripper, *pushMetricsHeaders, *pushMetricsTimeout, *pushMetricsLabels, *metricFiles...))
|
||||
|
||||
case queryInstantCmd.FullCommand():
|
||||
os.Exit(QueryInstant(serverURL, httpRoundTripper, *queryInstantExpr, *queryInstantTime, p))
|
||||
|
|
|
@ -32,7 +32,7 @@ import (
|
|||
)
|
||||
|
||||
// Push metrics to a prometheus remote write (for testing purpose only).
|
||||
func PushMetrics(url *url.URL, roundTripper http.RoundTripper, headers map[string]string, timeout time.Duration, jobLabel string, files ...string) int {
|
||||
func PushMetrics(url *url.URL, roundTripper http.RoundTripper, headers map[string]string, timeout time.Duration, labels map[string]string, files ...string) int {
|
||||
failed := false
|
||||
|
||||
addressURL, err := url.Parse(url.String())
|
||||
|
@ -76,32 +76,32 @@ func PushMetrics(url *url.URL, roundTripper http.RoundTripper, headers map[strin
|
|||
if file == "" {
|
||||
data, err = io.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
fmt.Fprintln(os.Stderr, " FAILED:", err)
|
||||
failed = true
|
||||
break
|
||||
}
|
||||
|
||||
fmt.Printf("Parsing stdin\n")
|
||||
fmt.Printf("Parsing input from stdin\n")
|
||||
} else {
|
||||
data, err = os.ReadFile(file)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
fmt.Fprintln(os.Stderr, " FAILED:", err)
|
||||
failed = true
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("Parsing metric file %s\n", file)
|
||||
fmt.Printf("Parsing input from metric file %s\n", file)
|
||||
}
|
||||
metricsData, err := fmtutil.ParseMetricsTextAndFormat(bytes.NewReader(data), jobLabel)
|
||||
metricsData, err := fmtutil.ParseMetricsTextAndFormat(bytes.NewReader(data), labels)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
fmt.Fprintln(os.Stderr, " FAILED:", err)
|
||||
failed = true
|
||||
continue
|
||||
}
|
||||
|
||||
raw, err := metricsData.Marshal()
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
fmt.Fprintln(os.Stderr, " FAILED:", err)
|
||||
failed = true
|
||||
continue
|
||||
}
|
||||
|
@ -110,11 +110,16 @@ func PushMetrics(url *url.URL, roundTripper http.RoundTripper, headers map[strin
|
|||
compressed := snappy.Encode(nil, raw)
|
||||
err = client.Store(context.Background(), compressed)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
fmt.Fprintln(os.Stderr, " FAILED:", err)
|
||||
failed = true
|
||||
continue
|
||||
}
|
||||
fmt.Printf("Successfully pushed metric file %s\n", file)
|
||||
|
||||
if file == "" {
|
||||
fmt.Printf(" SUCCESS: metric pushed to remote write.\n")
|
||||
} else {
|
||||
fmt.Printf(" SUCCESS: metric file %s pushed to remote write.\n", file)
|
||||
}
|
||||
}
|
||||
|
||||
if failed {
|
||||
|
|
|
@ -398,7 +398,7 @@ Push metrics to a prometheus remote write (for testing purpose only).
|
|||
|
||||
| Flag | Description | Default |
|
||||
| --- | --- | --- |
|
||||
| <code class="text-nowrap">--job-label</code> | Job label to attach to metrics. | `promtool` |
|
||||
| <code class="text-nowrap">--label</code> | Label to attach to metrics. Can be specified multiple times. | `job=promtool` |
|
||||
| <code class="text-nowrap">--timeout</code> | The time to wait for pushing metrics. | `30s` |
|
||||
| <code class="text-nowrap">--header</code> | Prometheus remote write header. | |
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ var MetricMetadataTypeValue = map[string]int32{
|
|||
}
|
||||
|
||||
// FormatMetrics convert metric family to a writerequest.
|
||||
func FormatMetrics(mf map[string]*dto.MetricFamily, jobLabel string) (*prompb.WriteRequest, error) {
|
||||
func FormatMetrics(mf map[string]*dto.MetricFamily, extraLabels map[string]string) (*prompb.WriteRequest, error) {
|
||||
wr := &prompb.WriteRequest{}
|
||||
|
||||
// build metric list
|
||||
|
@ -63,10 +63,15 @@ func FormatMetrics(mf map[string]*dto.MetricFamily, jobLabel string) (*prompb.Wr
|
|||
var timeserie prompb.TimeSeries
|
||||
|
||||
// build labels map
|
||||
labels := make(map[string]string, len(metric.Label)+2)
|
||||
labels := make(map[string]string, len(metric.Label)+len(extraLabels))
|
||||
labels[model.MetricNameLabel] = metricName
|
||||
labels[model.JobLabel] = jobLabel
|
||||
|
||||
// add extra labels
|
||||
for key, value := range extraLabels {
|
||||
labels[key] = value
|
||||
}
|
||||
|
||||
// add metric labels
|
||||
for _, label := range metric.Label {
|
||||
labelname := label.GetName()
|
||||
if labelname == model.JobLabel {
|
||||
|
@ -133,10 +138,10 @@ func ParseMetricsTextReader(input io.Reader) (map[string]*dto.MetricFamily, erro
|
|||
}
|
||||
|
||||
// ParseMetricsTextAndFormat return the data in the expected prometheus metrics write request format.
|
||||
func ParseMetricsTextAndFormat(input io.Reader, jobLabel string) (*prompb.WriteRequest, error) {
|
||||
func ParseMetricsTextAndFormat(input io.Reader, labels map[string]string) (*prompb.WriteRequest, error) {
|
||||
mf, err := ParseMetricsTextReader(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return FormatMetrics(mf, jobLabel)
|
||||
return FormatMetrics(mf, labels)
|
||||
}
|
||||
|
|
|
@ -63,8 +63,9 @@ func TestParseMetricsTextAndFormat(t *testing.T) {
|
|||
test_metric1{b="c",baz="qux",d="e",foo="bar"} 1 1
|
||||
test_metric1{b="c",baz="qux",d="e",foo="bar"} 2 1
|
||||
`))
|
||||
labels := map[string]string{"job": "promtool"}
|
||||
|
||||
expected, err := ParseMetricsTextAndFormat(input, "promtool")
|
||||
expected, err := ParseMetricsTextAndFormat(input, labels)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, writeRequestFixture, expected)
|
||||
|
|
Loading…
Reference in a new issue