skip to Main Content

Would you please tell me what is correct json payload to send to VictoriaMetrics

JSON payload I’m sending and getting error:

[{"metric":{"__name__":"cpu_usage_percent","instance":"localhost:9100","job":"Alexs-MBP.Home"},"timestamps":[1736670067000],"values":[7.737105]}]

Error:

2025-01-12T08:21:09.324Z    error   VictoriaMetrics/lib/protoparser/vmimport/parser.go:239  skipping json line "[{"metric":{"__name__":"cpu_usage_percent","instance":"localhost:9100","job":"Alexs-MBP.Home"},"timestamps":[1736670067000],"values":[7.737105]}]" because of error: missing `metric` object

Func:

func sendMetricToVictoria(metricName string, value float32, timestampStr string) error {
    timestamp, err := strconv.ParseInt(timestampStr, 10, 64)
    if err != nil {
        return fmt.Errorf("invalid timestamp format: %v", err)
    }

    // Get Hostname
    hostname, err := os.Hostname()
    if err != nil {
        return fmt.Errorf("error getting hostname: %v", err)
    }

    // Prepare the payload for VictoriaMetrics
    data := []map[string]interface{}{
        {
            "metric": map[string]interface{}{
                "__name__": metricName,       // Name of the metric
                "job":      hostname,         // Add the job label
                "instance": "localhost:9100", // Add the instance label
            },
            "values":     []float32{value},
            "timestamps": []int64{timestamp * 1000}, // Convert seconds to milliseconds
        },
    }

    log.Printf("JSON being sent: %vn", data)

    // Send data to VictoriaMetrics
    return sendToVictoriaMetrics(data)
}

API:

http://127.0.0.1:8428/api/v1/import

2

Answers


  1. From https://docs.victoriametrics.com/#how-to-import-time-series-data and https://docs.victoriametrics.com/#json-line-format, that endpoint want a JSON-line payload, that is, something like

    {"foo": "bar 1"}
    {"foo": "bar 2"}
    

    while if I look at your payload, it is plain JSON, that is, the outer data structure is a JSON array:

    [
      {"foo": "bar 1"},
      {"foo": "bar 2"},
      ...
    ]
    

    For more information about JSON-line, see for example https://jsonlines.org/.

    Creating JSON lines with Go is simple, it can be done with the stdlib json package: instead of marshaling the whole slice, iterate over the slice and marshal the individual elements.

    Login or Signup to reply.
  2. Please see this go code example https://go.dev/play/p/LqLMWdNOBD9

    func importSeries(metric string, value float64, timestamp int64) {
      b := strings.Builder{}
      job, instance := "myjob", "myinstance"
      b.WriteString(fmt.Sprintf("{"metric":{"__name__":%q, "instance":%q, "job":%q}", metric, instance, job))
      b.WriteString(fmt.Sprintf(","timestamps":[%d]", timestamp))
      b.WriteString(fmt.Sprintf(","values":[%v]}", value))
      fmt.Println(b.String())
    }
    

    Ofcourse, this is very naive implementation without batching or sending multilines. You can find more production-like setups for sending data here and here.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search