Мне удалось получить метрики, отправив 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
Может ли кто-нибудь указать мне правильное направление для анализа приведенных выше данных?
Для этого уже есть хороший пакет, созданный самими авторами 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:
Ссылаться:
Https://github.com/prometheus/pushgateway/issues/147#issuecomment-368215305
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 для окончания строки.
Добавьте символ новой строки в конце файла. На самом деле после метрики есть новая строка.
В опубликованном вами файле есть ошибки форматирования. Попробуйте использовать файл, который я использовал в качестве входных данных.
Я обновил свой ответ. Это должно помочь!
Сценарий не должен игнорировать строку, начинающуюся с #? Как только я удалил все строки, начинающиеся с #, и использовал обновленный код из ответа, ошибка изменилась на «ожидаемое целое число в виде метки времени, получило» 1608520832877\r»
Нет! Почему он будет игнорировать #. Тип метрики указан в # TYPE; посмотрите на пример, который я поделился. Проблема в том формате, который у вас есть. У вас есть \r концовки, которые парсеры Prometheus не принимают. Прочитайте мой ответ еще раз!
Вы должны делать что-то не так. Запустите эту программу, собрав ее (go build). Предположим, имя исполняемого файла — promfmt, затем запустите ./promfmt --f /path/to/file, где /path/to/file — путь (абсолютный или относительный; оба варианта работают!)