Как парсить данные Prometheus

Мне удалось получить метрики, отправив HTTP GET следующим образом:

# TYPE net_conntrack_dialer_conn_attempted_total untyped net_conntrack_dialer_conn_attempted_total{dialer_name = "federate",instance = "localhost:9090",job = "prometheus"} 1 1608520832877

Теперь мне нужно проанализировать эти данные и получить контроль над каждой частью данных, чтобы я мог преобразовать формат tand, например json.

Я искал пакет ebnf в Go: пакет ebnf

Может ли кто-нибудь указать мне правильное направление для анализа приведенных выше данных?

Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
8
0
9 769
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Для этого уже есть хороший пакет, созданный самими авторами Prometheus.

Они написали кучу библиотек Go, которые используются всеми компонентами и библиотеками Prometheus. Они считаются внутренними для Prometheus, но вы можете их использовать.

См.: github.com/prometheus/common doc. Существует пакет под названием expfmt, который может декодировать и кодировать формат экспозиции Прометея ( Ссылка). Да, он соответствует синтаксису EBNF, поэтому пакет ebnf также можно использовать, но вы получаете expfmt прямо из коробки.

Используемый пакет: expfmt

Пример ввода:

# HELP net_conntrack_dialer_conn_attempted_total
# TYPE net_conntrack_dialer_conn_attempted_total untyped
net_conntrack_dialer_conn_attempted_total{dialer_name = "federate",instance = "localhost:9090",job = "prometheus"} 1 1608520832877

Пример программы:

package main

import (
    "flag"
    "fmt"
    "log"
    "os"

    dto "github.com/prometheus/client_model/go"
    "github.com/prometheus/common/expfmt"
)

func fatal(err error) {
    if err != nil {
        log.Fatalln(err)
    }
}

func parseMF(path string) (map[string]*dto.MetricFamily, error) {
    reader, err := os.Open(path)
    if err != nil {
        return nil, err
    }

    var parser expfmt.TextParser
    mf, err := parser.TextToMetricFamilies(reader)
    if err != nil {
        return nil, err
    }
    return mf, nil
}

func main() {
    f := flag.String("f", "", "set filepath")
    flag.Parse()

    mf, err := parseMF(*f)
    fatal(err)

    for k, v := range mf {
        fmt.Println("KEY: ", k)
        fmt.Println("VAL: ", v)
    }
}

Пример вывода:

KEY:  net_conntrack_dialer_conn_attempted_total
VAL:  name:"net_conntrack_dialer_conn_attempted_total" type:UNTYPED metric:<label:<name:"dialer_name" value:"federate" > label:<name:"instance" value:"localhost:9090" > label:<name:"job" value:"prometheus" > untyped:<value:1 > timestamp_ms:1608520832877 >

Итак, expfmt — хороший выбор для вашего случая использования.

Обновление: проблема форматирования в опубликованном вводе OP:

Ссылаться:

  1. Https://github.com/prometheus/pushgateway/issues/147#issuecomment-368215305

  2. Https://github.com/prometheus/pushgateway#command-line

Note that in the text protocol, each line has to end with a line-feed
character (aka 'LF' or '\n'). Ending a line in other ways, e.g. with 
'CR' aka '\r', 'CRLF' aka '\r\n', or just the end of the packet, will
result in a protocol error.

Но из сообщения об ошибке я мог видеть, что в путе присутствует \r char, что недопустимо по дизайну. Поэтому используйте \n для окончания строки.

Вы должны делать что-то не так. Запустите эту программу, собрав ее (go build). Предположим, имя исполняемого файла — promfmt, затем запустите ./promfmt --f /path/to/file, где /path/to/file — путь (абсолютный или относительный; оба варианта работают!)

shmsr 21.12.2020 11:33

Добавьте символ новой строки в конце файла. На самом деле после метрики есть новая строка.

shmsr 21.12.2020 12:03

В опубликованном вами файле есть ошибки форматирования. Попробуйте использовать файл, который я использовал в качестве входных данных.

shmsr 21.12.2020 12:38

Я обновил свой ответ. Это должно помочь!

shmsr 21.12.2020 12:48

Сценарий не должен игнорировать строку, начинающуюся с #? Как только я удалил все строки, начинающиеся с #, и использовал обновленный код из ответа, ошибка изменилась на «ожидаемое целое число в виде метки времени, получило» 1608520832877\r»

Sijan Bhattarai 21.12.2020 12:55

Нет! Почему он будет игнорировать #. Тип метрики указан в # TYPE; посмотрите на пример, который я поделился. Проблема в том формате, который у вас есть. У вас есть \r концовки, которые парсеры Prometheus не принимают. Прочитайте мой ответ еще раз!

shmsr 21.12.2020 12:58

Другие вопросы по теме