in pkg/export/gcm/promtest/local_export.go [132:223]
func (l *localExportWithGCM) injectScrapes(t testing.TB, scrapeRecordings [][]*dto.MetricFamily, _ time.Duration) {
t.Helper()
for _, mfs := range scrapeRecordings {
// Encode gathered metric family as proto Prometheus exposition format, decode as internal
// Prometheus textparse format to have metrics how Prometheus would have
// before append. We don't use dto straight away due to quite complex code
// for generating multi counter metrics like legacy histograms and summaries.
b := bytes.Buffer{}
enc := expfmt.NewEncoder(&b, expfmt.NewFormat(expfmt.TypeProtoDelim))
for _, mf := range mfs {
if err := enc.Encode(mf); err != nil {
t.Fatal(err)
}
}
if closer, ok := enc.(expfmt.Closer); ok {
if err := closer.Close(); err != nil {
t.Fatal(err)
}
}
tp, err := textparse.New(b.Bytes(), string(expfmt.NewFormat(expfmt.TypeProtoDelim)), true)
if err != nil {
t.Fatal(err)
}
// Iterate over textparse parser results and mimic Prometheus scrape loop
// with exporter.Export injection.
// It's fine to start ref from 0 and clean labelsByRef for every Export invocation,
// as exporter does not need to further (after conversions).
l.labelsByRef = map[storage.SeriesRef]labels.Labels{}
ref := uint64(0)
var (
currMeta export.MetricMetadata
batch []record.RefSample
metadata = map[string]export.MetricMetadata{}
)
for {
et, err := tp.Next()
if err != nil {
if errors.Is(err, io.EOF) {
break
}
t.Fatal(err)
}
switch et {
case textparse.EntryType:
_, currMeta.Type = tp.Type()
continue
case textparse.EntryHelp:
mName, mHelp := tp.Help()
currMeta.Metric, currMeta.Help = string(mName), string(mHelp)
continue
case textparse.EntryUnit:
// Proto format won't give us that anyway.
continue
case textparse.EntryComment:
continue
case textparse.EntryHistogram:
// TODO(bwplotka): Sparse histogram would be here TBD.
panic("not implemented")
default:
}
// TODO(bwplotka): Support exemplars and created timestamp.
t := timestamp.FromTime(time.Now())
_, parsedTimestamp, val := tp.Series()
if parsedTimestamp != nil {
t = *parsedTimestamp
}
metadata[currMeta.Metric] = currMeta
lset := labels.New()
_ = tp.Metric(&lset)
l.labelsByRef[storage.SeriesRef(ref)] = lset
batch = append(batch, record.RefSample{
Ref: chunks.HeadSeriesRef(ref), V: val, T: t,
})
ref++
}
l.e.Export(func(metric string) (export.MetricMetadata, bool) {
m, ok := metadata[metric]
return m, ok
}, batch, nil)
}
}