OPS-03: dev-server fuer live-scrape-verifikation; expfmt-namensvalidierung fixen
This commit is contained in:
@@ -0,0 +1,43 @@
|
|||||||
|
// metrics-devserver stellt den OPS-03-Metrics-Aggregator (internal/metrics)
|
||||||
|
// unter /metrics bereit, damit ein echter Prometheus-Scrape-Vorgang gegen
|
||||||
|
// den Core-Dienst geprueft werden kann (Pruefung 3). Getrennt von cmd/core
|
||||||
|
// aus demselben Grund wie die anderen *-devserver.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"gitea.perlbach24.de/scripte/nexarch/internal/db"
|
||||||
|
"gitea.perlbach24.de/scripte/nexarch/internal/metrics"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
dsn := os.Getenv("NEXARCH_REGISTRY_DSN")
|
||||||
|
if dsn == "" {
|
||||||
|
log.Fatal("NEXARCH_REGISTRY_DSN nicht gesetzt")
|
||||||
|
}
|
||||||
|
addr := os.Getenv("NEXARCH_METRICS_LISTEN_ADDR")
|
||||||
|
if addr == "" {
|
||||||
|
addr = ":8085"
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
pool, err := db.Connect(ctx, dsn)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("db: %v", err)
|
||||||
|
}
|
||||||
|
defer pool.Close()
|
||||||
|
|
||||||
|
sourceStore := metrics.NewSourceStore(pool)
|
||||||
|
agg := metrics.NewAggregator(metrics.NewCoreRegistry(), sourceStore.Provide)
|
||||||
|
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
mux.HandleFunc("/metrics", agg.Handler())
|
||||||
|
mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) })
|
||||||
|
|
||||||
|
log.Printf("metrics-devserver listening on %s", addr)
|
||||||
|
log.Fatal(http.ListenAndServe(addr, mux))
|
||||||
|
}
|
||||||
@@ -25,8 +25,18 @@ import (
|
|||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
dto "github.com/prometheus/client_model/go"
|
dto "github.com/prometheus/client_model/go"
|
||||||
"github.com/prometheus/common/expfmt"
|
"github.com/prometheus/common/expfmt"
|
||||||
|
"github.com/prometheus/common/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// init erzwingt das klassische Prometheus-Namensschema (a-z, A-Z, 0-9, _)
|
||||||
|
// fuer die Namensvalidierung von expfmt/model — ohne diese explizite
|
||||||
|
// Festlegung liefert die Bibliothek "Invalid name validation scheme
|
||||||
|
// requested: unset" beim Parsen/Kodieren, da sie den globalen Default in
|
||||||
|
// dieser Version nicht mehr implizit setzt.
|
||||||
|
func init() {
|
||||||
|
model.NameValidationScheme = model.LegacyValidation
|
||||||
|
}
|
||||||
|
|
||||||
// Source ist EIN registriertes Modul mit seinem eigenen /metrics-Endpunkt
|
// Source ist EIN registriertes Modul mit seinem eigenen /metrics-Endpunkt
|
||||||
// (siehe internal/health fuer das analoge Muster bei Readiness-Checks).
|
// (siehe internal/health fuer das analoge Muster bei Readiness-Checks).
|
||||||
type Source struct {
|
type Source struct {
|
||||||
@@ -122,7 +132,7 @@ func (a *Aggregator) fetchAndRename(ctx context.Context, src Source) ([]*dto.Met
|
|||||||
return nil, fmt.Errorf("modul %s: unerwarteter status %d", src.ModuleName, resp.StatusCode)
|
return nil, fmt.Errorf("modul %s: unerwarteter status %d", src.ModuleName, resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
var parser expfmt.TextParser
|
parser := expfmt.NewTextParser(model.LegacyValidation)
|
||||||
parsed, err := parser.TextToMetricFamilies(resp.Body)
|
parsed, err := parser.TextToMetricFamilies(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("modul %s: metrik-text nicht parsebar: %w", src.ModuleName, err)
|
return nil, fmt.Errorf("modul %s: metrik-text nicht parsebar: %w", src.ModuleName, err)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/prometheus/common/expfmt"
|
"github.com/prometheus/common/expfmt"
|
||||||
|
"github.com/prometheus/common/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
func fakeModuleServer(metricName string) *httptest.Server {
|
func fakeModuleServer(metricName string) *httptest.Server {
|
||||||
@@ -33,7 +34,7 @@ func TestHandler_ServesCoreMetricsInPrometheusFormat(t *testing.T) {
|
|||||||
t.Fatalf("status = %d, want 200", rec.Code)
|
t.Fatalf("status = %d, want 200", rec.Code)
|
||||||
}
|
}
|
||||||
|
|
||||||
var parser expfmt.TextParser
|
parser := expfmt.NewTextParser(model.LegacyValidation)
|
||||||
families, err := parser.TextToMetricFamilies(strings.NewReader(rec.Body.String()))
|
families, err := parser.TextToMetricFamilies(strings.NewReader(rec.Body.String()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("antwort ist kein valides prometheus-textformat: %v", err)
|
t.Fatalf("antwort ist kein valides prometheus-textformat: %v", err)
|
||||||
|
|||||||
Reference in New Issue
Block a user