英文:
Transform Prometheus Metrics to Json with Golang
问题
我有一些 Prometheus 指标数据,想要使用 Golang 将其转换为 JSON 格式。我写了一些代码,但没有成功。
例如,Prometheus 指标数据如下:
# TYPE http_requests_total counter
http_requests_total{code="200",method="GET"} 28
http_requests_total{code="200",method="POST"} 3
我想要转换成的 JSON 格式如下:
{
"http_requests_total": [
{
"http_requests_total": {
"code": "200",
"method": "GET",
"value": 28
}
},
{
"http_requests_total": {
"code": "200",
"method": "POST",
"value": 3
}
}
]
}
英文:
I have prometgeus metrics and I want to convert it to json format using golang. I wrote some code but without success.
For example: Prometheus Metric:
# TYPE http_requests_total counter
http_requests_total{code="200",method="GET"} 28
http_requests_total{code="200",method="POST"} 3
The JSON I want to convert:
{
"http_requests_total": [
{
"http_requests_total": {
"code": "200",
"method": "GET",
"value": 28
}
},
{
"http_requests_total": {
"code": "200",
"method": "POST",
"value": 3
}
}
]
}
答案1
得分: 1
我假设你希望这段代码具有灵活性,即不仅仅处理特定的指标。如果是这样的话,下面的代码应该可以解决问题。
package main
import (
"encoding/json"
"fmt"
"log"
"os"
"strings"
dto "github.com/prometheus/client_model/go"
"github.com/prometheus/common/expfmt"
)
func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}
func run() error {
str := `# TYPE http_requests_total counter
http_requests_total{code="200",method="GET"} 28
http_requests_total{code="200",method="POST"} 3
`
parser := &expfmt.TextParser{}
families, err := parser.TextToMetricFamilies(strings.NewReader(str))
if err != nil {
return fmt.Errorf("failed to parse input: %w", err)
}
out := make(map[string][]map[string]map[string]interface{})
for key, val := range families {
family := out[key]
for _, m := range val.GetMetric() {
metric := make(map[string]interface{})
for _, label := range m.GetLabel() {
metric[label.GetName()] = label.GetValue()
}
switch val.GetType() {
case dto.MetricType_COUNTER:
metric["value"] = m.GetCounter().GetValue()
case dto.MetricType_GAUGE:
metric["value"] = m.GetGauge().GetValue()
default:
return fmt.Errorf("unsupported type: %v", val.GetType())
}
family = append(family, map[string]map[string]interface{}{
val.GetName(): metric,
})
}
out[key] = family
}
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
if err = enc.Encode(out); err != nil {
return fmt.Errorf("failed to encode json: %w", err)
}
return nil
}
输出结果:
{
"http_requests_total": [
{
"http_requests_total": {
"code": "200",
"method": "GET",
"value": 28
}
},
{
"http_requests_total": {
"code": "200",
"method": "POST",
"value": 3
}
}
]
}
希望对你有帮助!
英文:
I'm assuming you're looking for this to be flexible, i.e. not just handling those specific metrics? If so, the following code should do the trick.
package main
import (
"encoding/json"
"fmt"
"log"
"os"
"strings"
dto "github.com/prometheus/client_model/go"
"github.com/prometheus/common/expfmt"
)
func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}
func run() error {
str := `# TYPE http_requests_total counter
http_requests_total{code="200",method="GET"} 28
http_requests_total{code="200",method="POST"} 3
`
parser := &expfmt.TextParser{}
families, err := parser.TextToMetricFamilies(strings.NewReader(str))
if err != nil {
return fmt.Errorf("failed to parse input: %w", err)
}
out := make(map[string][]map[string]map[string]any)
for key, val := range families {
family := out[key]
for _, m := range val.GetMetric() {
metric := make(map[string]any)
for _, label := range m.GetLabel() {
metric[label.GetName()] = label.GetValue()
}
switch val.GetType() {
case dto.MetricType_COUNTER:
metric["value"] = m.GetCounter().GetValue()
case dto.MetricType_GAUGE:
metric["value"] = m.GetGauge().GetValue()
default:
return fmt.Errorf("unsupported type: %v", val.GetType())
}
family = append(family, map[string]map[string]any{
val.GetName(): metric,
})
}
out[key] = family
}
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
if err = enc.Encode(out); err != nil {
return fmt.Errorf("failed to encode json: %w", err)
}
return nil
}
Output:
{
"http_requests_total": [
{
"http_requests_total": {
"code": "200",
"method": "GET",
"value": 28
}
},
{
"http_requests_total": {
"code": "200",
"method": "POST",
"value": 3
}
}
]
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论