How to map expfmt to samples
go
Wrap Lines
Raw package main
import (
"bytes"
"fmt"
"log"
"net/http"
"time"
"github.com/golang/snappy"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/expfmt"
"github.com/prometheus/common/model"
"github.com/prometheus/prometheus/prompb"
)
const (
pushgatewayURL = "https://prom.scanwizard.ru/api/v1/write"
username = "scanaryd"
password = "$apr1$RseemMSV$H2LzM3cl71lbptrokMhgF/"
)
func main() {
// Create a new registry
registry := prometheus.NewRegistry()
// Create a gauge metric
asicTestMetric := prometheus.NewGauge(prometheus.GaugeOpts{
Name: "asic_test_metric",
Help: "A test metric for ASIC monitoring",
})
// Register the metric with the registry
registry.MustRegister(asicTestMetric)
// Set the metric value
asicTestMetric.Set(150.45)
// Gather metrics from the registry
metricFamilies, err := registry.Gather()
if err != nil {
log.Fatalf("Failed to gather metrics: %v", err)
}
// Convert metric families to samples using expfmt
decodeOptions := &expfmt.DecodeOptions{
Timestamp: model.TimeFromUnixNano(time.Now().UnixNano()),
}
// Extract samples from metric families
samples, err := expfmt.ExtractSamples(decodeOptions, metricFamilies...)
if err != nil {
log.Fatalf("Failed to extract samples: %v", err)
}
fmt.Println(samples)
// Convert samples to remote write format
var timeseries []prompb.TimeSeries
for _, sample := range samples {
// Create labels
var labels []prompb.Label
for name, value := range sample.Metric {
labels = append(labels, prompb.Label{
Name: string(name),
Value: string(value),
})
}
// Create timeseries
timeseries = append(timeseries, prompb.TimeSeries{
Labels: labels,
Samples: []prompb.Sample{
{
Value: float64(sample.Value),
Timestamp: int64(sample.Timestamp),
},
},
})
}
// Create write request according to spec
writeRequest := &prompb.WriteRequest{
Timeseries: timeseries,
}
// Marshal to protobuf
data, err := writeRequest.Marshal()
if err != nil {
log.Fatalf("Failed to marshal protobuf: %v", err)
}
fmt.Println(data)
// Compress with snappy (block format as required by spec)
compressedData := snappy.Encode(nil, data)
// Create HTTP request
req, err := http.NewRequest("POST", pushgatewayURL, bytes.NewBuffer(compressedData))
if err != nil {
log.Fatalf("Failed to create request: %v", err)
}
// Set headers according to Prometheus Remote Write 1.0 spec
req.Header.Set("Content-Type", "application/x-protobuf")
req.Header.Set("Content-Encoding", "snappy")
req.Header.Set("User-Agent", "go-test-script/1.0")
req.Header.Set("X-Prometheus-Remote-Write-Version", "0.1.0")
req.SetBasicAuth(username, password)
client := &http.Client{
Timeout: 10 * time.Second,
}
fmt.Println(req)
resp, err := client.Do(req)
if err != nil {
log.Fatalf("Failed to send request: %v", err)
}
defer resp.Body.Close()
fmt.Printf("Status Code: %d\n", resp.StatusCode)
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusAccepted {
log.Printf("Unexpected status code: %d", resp.StatusCode)
} else {
fmt.Println("Metrics successfully sent to Prometheus!")
}
}