mirror of
https://github.com/prometheus/prometheus.git
synced 2026-06-03 21:52:13 -04:00
prompb: Generate client proto using Opaque API, for parsing only.
Signed-off-by: bwplotka <bwplotka@gmail.com>
This commit is contained in:
parent
281306765e
commit
e7bde7a5dc
7 changed files with 1540 additions and 4079 deletions
|
|
@ -23,17 +23,18 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/prometheus/common/model"
|
||||
"google.golang.org/protobuf/encoding/protowire"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/prometheus/prometheus/model/exemplar"
|
||||
"github.com/prometheus/prometheus/model/histogram"
|
||||
"github.com/prometheus/prometheus/model/labels"
|
||||
|
||||
dto "github.com/prometheus/prometheus/prompb/io/prometheus/client"
|
||||
prompbdto "github.com/prometheus/prometheus/prompb/io/prometheus/client"
|
||||
)
|
||||
|
||||
// floatFormatBufPool is exclusively used in formatOpenMetricsFloat.
|
||||
|
|
@ -80,7 +81,7 @@ type ProtobufParser struct {
|
|||
|
||||
builder labels.ScratchBuilder // held here to reduce allocations when building Labels
|
||||
|
||||
mf *dto.MetricFamily
|
||||
mf *prompbdto.MetricFamily
|
||||
|
||||
// Whether to also parse a classic histogram that is also present as a
|
||||
// native histogram.
|
||||
|
|
@ -95,7 +96,7 @@ func NewProtobufParser(b []byte, parseClassicHistograms bool, st *labels.SymbolT
|
|||
return &ProtobufParser{
|
||||
in: b,
|
||||
state: EntryInvalid,
|
||||
mf: &dto.MetricFamily{},
|
||||
mf: &prompbdto.MetricFamily{},
|
||||
metricBytes: &bytes.Buffer{},
|
||||
parseClassicHistograms: parseClassicHistograms,
|
||||
builder: labels.NewScratchBuilderWithSymbolTable(st, 16),
|
||||
|
|
@ -111,13 +112,13 @@ func (p *ProtobufParser) Series() ([]byte, *int64, float64) {
|
|||
v float64
|
||||
)
|
||||
switch p.mf.GetType() {
|
||||
case dto.MetricType_COUNTER:
|
||||
case prompbdto.MetricType_COUNTER:
|
||||
v = m.GetCounter().GetValue()
|
||||
case dto.MetricType_GAUGE:
|
||||
case prompbdto.MetricType_GAUGE:
|
||||
v = m.GetGauge().GetValue()
|
||||
case dto.MetricType_UNTYPED:
|
||||
case prompbdto.MetricType_UNTYPED:
|
||||
v = m.GetUntyped().GetValue()
|
||||
case dto.MetricType_SUMMARY:
|
||||
case prompbdto.MetricType_SUMMARY:
|
||||
s := m.GetSummary()
|
||||
switch p.fieldPos {
|
||||
case -2:
|
||||
|
|
@ -131,7 +132,7 @@ func (p *ProtobufParser) Series() ([]byte, *int64, float64) {
|
|||
default:
|
||||
v = s.GetQuantile()[p.fieldPos].GetValue()
|
||||
}
|
||||
case dto.MetricType_HISTOGRAM, dto.MetricType_GAUGE_HISTOGRAM:
|
||||
case prompbdto.MetricType_HISTOGRAM, prompbdto.MetricType_GAUGE_HISTOGRAM:
|
||||
// This should only happen for a classic histogram.
|
||||
h := m.GetHistogram()
|
||||
switch p.fieldPos {
|
||||
|
|
@ -214,7 +215,7 @@ func (p *ProtobufParser) Histogram() ([]byte, *int64, *histogram.Histogram, *his
|
|||
fh.NegativeSpans[i].Offset = span.GetOffset()
|
||||
fh.NegativeSpans[i].Length = span.GetLength()
|
||||
}
|
||||
if p.mf.GetType() == dto.MetricType_GAUGE_HISTOGRAM {
|
||||
if p.mf.GetType() == prompbdto.MetricType_GAUGE_HISTOGRAM {
|
||||
fh.CounterResetHint = histogram.GaugeType
|
||||
}
|
||||
fh.Compact(0)
|
||||
|
|
@ -246,7 +247,7 @@ func (p *ProtobufParser) Histogram() ([]byte, *int64, *histogram.Histogram, *his
|
|||
sh.NegativeSpans[i].Offset = span.GetOffset()
|
||||
sh.NegativeSpans[i].Length = span.GetLength()
|
||||
}
|
||||
if p.mf.GetType() == dto.MetricType_GAUGE_HISTOGRAM {
|
||||
if p.mf.GetType() == prompbdto.MetricType_GAUGE_HISTOGRAM {
|
||||
sh.CounterResetHint = histogram.GaugeType
|
||||
}
|
||||
sh.Compact(0)
|
||||
|
|
@ -269,15 +270,15 @@ func (p *ProtobufParser) Help() ([]byte, []byte) {
|
|||
func (p *ProtobufParser) Type() ([]byte, model.MetricType) {
|
||||
n := p.metricBytes.Bytes()
|
||||
switch p.mf.GetType() {
|
||||
case dto.MetricType_COUNTER:
|
||||
case prompbdto.MetricType_COUNTER:
|
||||
return n, model.MetricTypeCounter
|
||||
case dto.MetricType_GAUGE:
|
||||
case prompbdto.MetricType_GAUGE:
|
||||
return n, model.MetricTypeGauge
|
||||
case dto.MetricType_HISTOGRAM:
|
||||
case prompbdto.MetricType_HISTOGRAM:
|
||||
return n, model.MetricTypeHistogram
|
||||
case dto.MetricType_GAUGE_HISTOGRAM:
|
||||
case prompbdto.MetricType_GAUGE_HISTOGRAM:
|
||||
return n, model.MetricTypeGaugeHistogram
|
||||
case dto.MetricType_SUMMARY:
|
||||
case prompbdto.MetricType_SUMMARY:
|
||||
return n, model.MetricTypeSummary
|
||||
}
|
||||
return n, model.MetricTypeUnknown
|
||||
|
|
@ -327,11 +328,11 @@ func (p *ProtobufParser) Exemplar(ex *exemplar.Exemplar) bool {
|
|||
return false
|
||||
}
|
||||
m := p.mf.GetMetric()[p.metricPos]
|
||||
var exProto *dto.Exemplar
|
||||
var exProto *prompbdto.Exemplar
|
||||
switch p.mf.GetType() {
|
||||
case dto.MetricType_COUNTER:
|
||||
case prompbdto.MetricType_COUNTER:
|
||||
exProto = m.GetCounter().GetExemplar()
|
||||
case dto.MetricType_HISTOGRAM, dto.MetricType_GAUGE_HISTOGRAM:
|
||||
case prompbdto.MetricType_HISTOGRAM, prompbdto.MetricType_GAUGE_HISTOGRAM:
|
||||
isClassic := p.state == EntrySeries
|
||||
if !isClassic && len(m.GetHistogram().GetExemplars()) > 0 {
|
||||
exs := m.GetHistogram().GetExemplars()
|
||||
|
|
@ -393,22 +394,17 @@ func (p *ProtobufParser) Exemplar(ex *exemplar.Exemplar) bool {
|
|||
// CreatedTimestamp returns CT or nil if CT is not present or
|
||||
// invalid (as timestamp e.g. negative value) on counters, summaries or histograms.
|
||||
func (p *ProtobufParser) CreatedTimestamp() *int64 {
|
||||
var ct *types.Timestamp
|
||||
var ct time.Time
|
||||
switch p.mf.GetType() {
|
||||
case dto.MetricType_COUNTER:
|
||||
ct = p.mf.GetMetric()[p.metricPos].GetCounter().GetCreatedTimestamp()
|
||||
case dto.MetricType_SUMMARY:
|
||||
ct = p.mf.GetMetric()[p.metricPos].GetSummary().GetCreatedTimestamp()
|
||||
case dto.MetricType_HISTOGRAM, dto.MetricType_GAUGE_HISTOGRAM:
|
||||
ct = p.mf.GetMetric()[p.metricPos].GetHistogram().GetCreatedTimestamp()
|
||||
case prompbdto.MetricType_COUNTER:
|
||||
ct = p.mf.GetMetric()[p.metricPos].GetCounter().GetCreatedTimestamp().AsTime()
|
||||
case prompbdto.MetricType_SUMMARY:
|
||||
ct = p.mf.GetMetric()[p.metricPos].GetSummary().GetCreatedTimestamp().AsTime()
|
||||
case prompbdto.MetricType_HISTOGRAM, prompbdto.MetricType_GAUGE_HISTOGRAM:
|
||||
ct = p.mf.GetMetric()[p.metricPos].GetHistogram().GetCreatedTimestamp().AsTime()
|
||||
default:
|
||||
}
|
||||
ctAsTime, err := types.TimestampFromProto(ct)
|
||||
if err != nil {
|
||||
// Errors means ct == nil or invalid timestamp, which we silently ignore.
|
||||
return nil
|
||||
}
|
||||
ctMilis := ctAsTime.UnixMilli()
|
||||
ctMilis := ct.UnixMilli()
|
||||
return &ctMilis
|
||||
}
|
||||
|
||||
|
|
@ -443,19 +439,19 @@ func (p *ProtobufParser) Next() (Entry, error) {
|
|||
return EntryInvalid, fmt.Errorf("invalid help for metric %q: %s", name, help)
|
||||
}
|
||||
switch p.mf.GetType() {
|
||||
case dto.MetricType_COUNTER,
|
||||
dto.MetricType_GAUGE,
|
||||
dto.MetricType_HISTOGRAM,
|
||||
dto.MetricType_GAUGE_HISTOGRAM,
|
||||
dto.MetricType_SUMMARY,
|
||||
dto.MetricType_UNTYPED:
|
||||
case prompbdto.MetricType_COUNTER,
|
||||
prompbdto.MetricType_GAUGE,
|
||||
prompbdto.MetricType_HISTOGRAM,
|
||||
prompbdto.MetricType_GAUGE_HISTOGRAM,
|
||||
prompbdto.MetricType_SUMMARY,
|
||||
prompbdto.MetricType_UNTYPED:
|
||||
// All good.
|
||||
default:
|
||||
return EntryInvalid, fmt.Errorf("unknown metric type for metric %q: %s", name, p.mf.GetType())
|
||||
}
|
||||
unit := p.mf.GetUnit()
|
||||
if len(unit) > 0 {
|
||||
if p.mf.GetType() == dto.MetricType_COUNTER && strings.HasSuffix(name, "_total") {
|
||||
if p.mf.GetType() == prompbdto.MetricType_COUNTER && strings.HasSuffix(name, "_total") {
|
||||
if !strings.HasSuffix(name[:len(name)-6], unit) || len(name)-6 < len(unit)+1 || name[len(name)-6-len(unit)-1] != '_' {
|
||||
return EntryInvalid, fmt.Errorf("unit %q not a suffix of counter %q", unit, name)
|
||||
}
|
||||
|
|
@ -468,7 +464,7 @@ func (p *ProtobufParser) Next() (Entry, error) {
|
|||
|
||||
p.state = EntryHelp
|
||||
case EntryHelp:
|
||||
if p.mf.Unit != "" {
|
||||
if p.mf.GetUnit() != "" {
|
||||
p.state = EntryUnit
|
||||
} else {
|
||||
p.state = EntryType
|
||||
|
|
@ -477,7 +473,7 @@ func (p *ProtobufParser) Next() (Entry, error) {
|
|||
p.state = EntryType
|
||||
case EntryType:
|
||||
t := p.mf.GetType()
|
||||
if (t == dto.MetricType_HISTOGRAM || t == dto.MetricType_GAUGE_HISTOGRAM) &&
|
||||
if (t == prompbdto.MetricType_HISTOGRAM || t == prompbdto.MetricType_GAUGE_HISTOGRAM) &&
|
||||
isNativeHistogram(p.mf.GetMetric()[0].GetHistogram()) {
|
||||
p.state = EntryHistogram
|
||||
} else {
|
||||
|
|
@ -495,9 +491,9 @@ func (p *ProtobufParser) Next() (Entry, error) {
|
|||
}
|
||||
t := p.mf.GetType()
|
||||
if p.state == EntrySeries && !p.fieldsDone &&
|
||||
(t == dto.MetricType_SUMMARY ||
|
||||
t == dto.MetricType_HISTOGRAM ||
|
||||
t == dto.MetricType_GAUGE_HISTOGRAM) {
|
||||
(t == prompbdto.MetricType_SUMMARY ||
|
||||
t == prompbdto.MetricType_HISTOGRAM ||
|
||||
t == prompbdto.MetricType_GAUGE_HISTOGRAM) {
|
||||
p.fieldPos++
|
||||
} else {
|
||||
p.metricPos++
|
||||
|
|
@ -508,7 +504,7 @@ func (p *ProtobufParser) Next() (Entry, error) {
|
|||
// histograms, we have to switch back to native
|
||||
// histograms after parsing a classic histogram.
|
||||
if p.state == EntrySeries &&
|
||||
(t == dto.MetricType_HISTOGRAM || t == dto.MetricType_GAUGE_HISTOGRAM) &&
|
||||
(t == prompbdto.MetricType_HISTOGRAM || t == prompbdto.MetricType_GAUGE_HISTOGRAM) &&
|
||||
isNativeHistogram(p.mf.GetMetric()[0].GetHistogram()) {
|
||||
p.state = EntryHistogram
|
||||
}
|
||||
|
|
@ -558,7 +554,7 @@ func (p *ProtobufParser) updateMetricBytes() error {
|
|||
// state.
|
||||
func (p *ProtobufParser) getMagicName() string {
|
||||
t := p.mf.GetType()
|
||||
if p.state == EntryHistogram || (t != dto.MetricType_HISTOGRAM && t != dto.MetricType_GAUGE_HISTOGRAM && t != dto.MetricType_SUMMARY) {
|
||||
if p.state == EntryHistogram || (t != prompbdto.MetricType_HISTOGRAM && t != prompbdto.MetricType_GAUGE_HISTOGRAM && t != prompbdto.MetricType_SUMMARY) {
|
||||
return p.mf.GetName()
|
||||
}
|
||||
if p.fieldPos == -2 {
|
||||
|
|
@ -567,7 +563,7 @@ func (p *ProtobufParser) getMagicName() string {
|
|||
if p.fieldPos == -1 {
|
||||
return p.mf.GetName() + "_sum"
|
||||
}
|
||||
if t == dto.MetricType_HISTOGRAM || t == dto.MetricType_GAUGE_HISTOGRAM {
|
||||
if t == prompbdto.MetricType_HISTOGRAM || t == prompbdto.MetricType_GAUGE_HISTOGRAM {
|
||||
return p.mf.GetName() + "_bucket"
|
||||
}
|
||||
return p.mf.GetName()
|
||||
|
|
@ -580,12 +576,12 @@ func (p *ProtobufParser) getMagicLabel() (bool, string, string) {
|
|||
return false, "", ""
|
||||
}
|
||||
switch p.mf.GetType() {
|
||||
case dto.MetricType_SUMMARY:
|
||||
case prompbdto.MetricType_SUMMARY:
|
||||
qq := p.mf.GetMetric()[p.metricPos].GetSummary().GetQuantile()
|
||||
q := qq[p.fieldPos]
|
||||
p.fieldsDone = p.fieldPos == len(qq)-1
|
||||
return true, model.QuantileLabel, formatOpenMetricsFloat(q.GetQuantile())
|
||||
case dto.MetricType_HISTOGRAM, dto.MetricType_GAUGE_HISTOGRAM:
|
||||
case prompbdto.MetricType_HISTOGRAM, prompbdto.MetricType_GAUGE_HISTOGRAM:
|
||||
bb := p.mf.GetMetric()[p.metricPos].GetHistogram().GetBucket()
|
||||
if p.fieldPos >= len(bb) {
|
||||
p.fieldsDone = true
|
||||
|
|
@ -605,11 +601,11 @@ var errInvalidVarint = errors.New("protobufparse: invalid varint encountered")
|
|||
// specific to a MetricFamily, utilizes the more efficient gogo-protobuf
|
||||
// unmarshaling, and acts on a byte slice directly without any additional
|
||||
// staging buffers.
|
||||
func readDelimited(b []byte, mf *dto.MetricFamily) (n int, err error) {
|
||||
func readDelimited(b []byte, mf *prompbdto.MetricFamily) (n int, err error) {
|
||||
if len(b) == 0 {
|
||||
return 0, io.EOF
|
||||
}
|
||||
messageLength, varIntLength := proto.DecodeVarint(b)
|
||||
messageLength, varIntLength := protowire.ConsumeVarint(b)
|
||||
if varIntLength == 0 || varIntLength > binary.MaxVarintLen32 {
|
||||
return 0, errInvalidVarint
|
||||
}
|
||||
|
|
@ -618,7 +614,7 @@ func readDelimited(b []byte, mf *dto.MetricFamily) (n int, err error) {
|
|||
return 0, fmt.Errorf("protobufparse: insufficient length of buffer, expected at least %d bytes, got %d bytes", totalLength, len(b))
|
||||
}
|
||||
mf.Reset()
|
||||
return totalLength, mf.Unmarshal(b[varIntLength:totalLength])
|
||||
return totalLength, proto.Unmarshal(b[varIntLength:totalLength], mf)
|
||||
}
|
||||
|
||||
// formatOpenMetricsFloat works like the usual Go string formatting of a float
|
||||
|
|
@ -659,7 +655,7 @@ func formatOpenMetricsFloat(f float64) string {
|
|||
// zero) to signal that the histogram is meant to be parsed as a native
|
||||
// histogram. Failing to do so will cause Prometheus to parse it as a classic
|
||||
// histogram as long as no observations have happened.
|
||||
func isNativeHistogram(h *dto.Histogram) bool {
|
||||
func isNativeHistogram(h *prompbdto.Histogram) bool {
|
||||
return len(h.GetPositiveSpan()) > 0 ||
|
||||
len(h.GetNegativeSpan()) > 0 ||
|
||||
h.GetZeroThreshold() > 0 ||
|
||||
|
|
|
|||
11
prompb/buf.gen.yaml
Normal file
11
prompb/buf.gen.yaml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
version: v2
|
||||
|
||||
plugins:
|
||||
- remote: buf.build/protocolbuffers/go:v1.36.1
|
||||
out: .
|
||||
opt:
|
||||
- Mio/prometheus/client/metrics.proto=io/prometheus/client
|
||||
- default_api_level=API_OPAQUE
|
||||
|
||||
inputs:
|
||||
- directory: . # Pointing to the module in the buf.yaml.
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -13,15 +13,20 @@
|
|||
|
||||
// This is copied and lightly edited from
|
||||
// github.com/prometheus/client_model/io/prometheus/client/metrics.proto
|
||||
// and finally converted to proto3 syntax to make it usable for the
|
||||
// gogo-protobuf approach taken within prometheus/prometheus.
|
||||
// and finally converted to proto3 syntax. Initially to make it usable for the
|
||||
// gogo-protobuf approach taken within prometheus/prometheus, but now this copy
|
||||
// is actually source of the truth for buf registry.
|
||||
// TODO(bwplotka): Decide if we want to deprecate client_model or move proto and
|
||||
// buf module publishing there. On top of that we need two generated Go code, one
|
||||
// for efficient decoding with reusable strings and Opaque API, one designed to
|
||||
// be used as a dto e.g. in client_golang.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package io.prometheus.client;
|
||||
|
||||
option go_package = "io_prometheus_client";
|
||||
|
||||
import "gogoproto/gogo.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
message LabelPair {
|
||||
|
|
@ -63,7 +68,7 @@ message Quantile {
|
|||
message Summary {
|
||||
uint64 sample_count = 1;
|
||||
double sample_sum = 2;
|
||||
repeated Quantile quantile = 3 [(gogoproto.nullable) = false];
|
||||
repeated Quantile quantile = 3;
|
||||
|
||||
google.protobuf.Timestamp created_timestamp = 4;
|
||||
}
|
||||
|
|
@ -77,7 +82,7 @@ message Histogram {
|
|||
double sample_count_float = 4; // Overrides sample_count if > 0.
|
||||
double sample_sum = 2;
|
||||
// Buckets for the classic histogram.
|
||||
repeated Bucket bucket = 3 [(gogoproto.nullable) = false]; // Ordered in increasing order of upper_bound, +Inf bucket is optional.
|
||||
repeated Bucket bucket = 3; // Ordered in increasing order of upper_bound, +Inf bucket is optional.
|
||||
|
||||
google.protobuf.Timestamp created_timestamp = 15;
|
||||
|
||||
|
|
@ -95,7 +100,7 @@ message Histogram {
|
|||
double zero_count_float = 8; // Overrides sb_zero_count if > 0.
|
||||
|
||||
// Negative buckets for the native histogram.
|
||||
repeated BucketSpan negative_span = 9 [(gogoproto.nullable) = false];
|
||||
repeated BucketSpan negative_span = 9;
|
||||
// Use either "negative_delta" or "negative_count", the former for
|
||||
// regular histograms with integer counts, the latter for float
|
||||
// histograms.
|
||||
|
|
@ -106,7 +111,7 @@ message Histogram {
|
|||
// Use a no-op span (offset 0, length 0) for a native histogram without any
|
||||
// observations yet and with a zero_threshold of 0. Otherwise, it would be
|
||||
// indistinguishable from a classic histogram.
|
||||
repeated BucketSpan positive_span = 12 [(gogoproto.nullable) = false];
|
||||
repeated BucketSpan positive_span = 12;
|
||||
// Use either "positive_delta" or "positive_count", the former for
|
||||
// regular histograms with integer counts, the latter for float
|
||||
// histograms.
|
||||
|
|
@ -136,13 +141,13 @@ message BucketSpan {
|
|||
}
|
||||
|
||||
message Exemplar {
|
||||
repeated LabelPair label = 1 [(gogoproto.nullable) = false];
|
||||
repeated LabelPair label = 1;
|
||||
double value = 2;
|
||||
google.protobuf.Timestamp timestamp = 3; // OpenMetrics-style.
|
||||
}
|
||||
|
||||
message Metric {
|
||||
repeated LabelPair label = 1 [(gogoproto.nullable) = false];
|
||||
repeated LabelPair label = 1;
|
||||
Gauge gauge = 2;
|
||||
Counter counter = 3;
|
||||
Summary summary = 4;
|
||||
|
|
@ -155,6 +160,6 @@ message MetricFamily {
|
|||
string name = 1;
|
||||
string help = 2;
|
||||
MetricType type = 3;
|
||||
repeated Metric metric = 4 [(gogoproto.nullable) = false];
|
||||
repeated Metric metric = 4;
|
||||
string unit = 5;
|
||||
}
|
||||
|
|
|
|||
37
prompb/io/prometheus/client/registry.go
Normal file
37
prompb/io/prometheus/client/registry.go
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright 2024 Prometheus Team
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package io_prometheus_client //nolint
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
)
|
||||
|
||||
type nopTypeRegistry struct{}
|
||||
|
||||
func (nopTypeRegistry) RegisterMessage(protoreflect.MessageType) error { return nil }
|
||||
func (nopTypeRegistry) RegisterEnum(protoreflect.EnumType) error { return nil }
|
||||
func (nopTypeRegistry) RegisterExtension(protoreflect.ExtensionType) error { return nil }
|
||||
|
||||
type nopFileRegistry struct{}
|
||||
|
||||
func (nopFileRegistry) FindFileByPath(string) (protoreflect.FileDescriptor, error) {
|
||||
return nil, errors.New("nop file registry, shouldn't be used for querying")
|
||||
}
|
||||
|
||||
func (nopFileRegistry) FindDescriptorByName(protoreflect.FullName) (protoreflect.Descriptor, error) {
|
||||
return nil, errors.New("nop file registry, shouldn't be used for querying")
|
||||
}
|
||||
func (nopFileRegistry) RegisterFile(protoreflect.FileDescriptor) error { return nil }
|
||||
|
|
@ -32,7 +32,6 @@ import (
|
|||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/grafana/regexp"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
|
@ -43,6 +42,8 @@ import (
|
|||
"github.com/prometheus/common/model"
|
||||
"github.com/prometheus/common/promslog"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/protobuf/encoding/prototext"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/prometheus/prometheus/config"
|
||||
"github.com/prometheus/prometheus/discovery"
|
||||
|
|
@ -2501,12 +2502,11 @@ metric: <
|
|||
}
|
||||
}
|
||||
|
||||
func textToProto(text string, buf *bytes.Buffer) error {
|
||||
func textToProto(text string, buf io.Writer) error {
|
||||
// In case of protobuf, we have to create the binary representation.
|
||||
pb := &dto.MetricFamily{}
|
||||
// From text to proto message.
|
||||
err := proto.UnmarshalText(text, pb)
|
||||
if err != nil {
|
||||
if err := prototext.Unmarshal([]byte(text), pb); err != nil {
|
||||
return err
|
||||
}
|
||||
// From proto message to binary protobuf.
|
||||
|
|
@ -4201,20 +4201,7 @@ metric: <
|
|||
if metricsText.contentType != "" {
|
||||
w.Header().Set("Content-Type", `application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited`)
|
||||
for _, text := range metricsText.text {
|
||||
buf := &bytes.Buffer{}
|
||||
// In case of protobuf, we have to create the binary representation.
|
||||
pb := &dto.MetricFamily{}
|
||||
// From text to proto message.
|
||||
require.NoError(t, proto.UnmarshalText(text, pb))
|
||||
// From proto message to binary protobuf.
|
||||
protoBuf, err := proto.Marshal(pb)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Write first length, then binary protobuf.
|
||||
varintBuf := binary.AppendUvarint(nil, uint64(len(protoBuf)))
|
||||
buf.Write(varintBuf)
|
||||
buf.Write(protoBuf)
|
||||
w.Write(buf.Bytes())
|
||||
require.NoError(t, textToProto(text, w))
|
||||
}
|
||||
} else {
|
||||
for _, text := range metricsText.text {
|
||||
|
|
|
|||
|
|
@ -10,27 +10,39 @@ if ! [[ "$0" =~ "scripts/genproto.sh" ]]; then
|
|||
exit 255
|
||||
fi
|
||||
|
||||
# TODO(bwplotka): Move to buf, this is not OSS agnostic, likely won't work locally.
|
||||
if ! [[ $(protoc --version) =~ "3.15.8" ]]; then
|
||||
echo "could not find protoc 3.15.8, is it installed + in PATH? Consider commenting out this check for local flow"
|
||||
exit 255
|
||||
fi
|
||||
SED=$(which gsed 2>/dev/null || which sed)
|
||||
|
||||
# Since we run go install, go mod download, the go.sum will change.
|
||||
# Make a backup.
|
||||
cp go.sum go.sum.bak
|
||||
|
||||
INSTALL_PKGS="golang.org/x/tools/cmd/goimports github.com/gogo/protobuf/protoc-gen-gogofast github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger"
|
||||
INSTALL_PKGS="golang.org/x/tools/cmd/goimports github.com/gogo/protobuf/protoc-gen-gogofast github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger github.com/bufbuild/buf/cmd/buf@v1.48.0"
|
||||
for pkg in ${INSTALL_PKGS}; do
|
||||
GO111MODULE=on go install "$pkg"
|
||||
done
|
||||
|
||||
# Build client proto via buf.
|
||||
pushd ./prompb
|
||||
buf generate --path=./io/prometheus/client
|
||||
# We have to hack global registry which blocks multiple generated types
|
||||
# from the same proto file (the same path+file and full name).
|
||||
${SED} -i.bak -E 's/protoimpl.DescBuilder\{/protoimpl.DescBuilder\{FileRegistry:nopFileRegistry{},/g' ./io/prometheus/client/*.pb.go
|
||||
${SED} -i.bak -E 's/protoimpl.TypeBuilder\{/protoimpl.TypeBuilder\{TypeRegistry:nopTypeRegistry{},/g' ./io/prometheus/client/*.pb.go
|
||||
goimports -w ./io/prometheus/client/*.go
|
||||
rm -f ./io/prometheus/client/*.bak
|
||||
popd
|
||||
|
||||
# TODO(bwplotka): Move write building to buf e.g. once moved out of gogo.
|
||||
if ! [[ $(protoc --version) =~ "3.15.8" ]]; then
|
||||
echo "could not find protoc 3.15.8, is it installed + in PATH? Consider commenting out this check for local flow"
|
||||
exit 255
|
||||
fi
|
||||
|
||||
PROM_ROOT="${PWD}"
|
||||
PROM_PATH="${PROM_ROOT}/prompb"
|
||||
GOGOPROTO_ROOT="$(GO111MODULE=on go list -mod=readonly -f '{{ .Dir }}' -m github.com/gogo/protobuf)"
|
||||
GOGOPROTO_PATH="${GOGOPROTO_ROOT}:${GOGOPROTO_ROOT}/protobuf"
|
||||
GRPC_GATEWAY_ROOT="$(GO111MODULE=on go list -mod=readonly -f '{{ .Dir }}' -m github.com/grpc-ecosystem/grpc-gateway)"
|
||||
|
||||
DIRS="prompb"
|
||||
|
||||
echo "generating code"
|
||||
|
|
@ -44,14 +56,11 @@ for dir in ${DIRS}; do
|
|||
protoc --gogofast_out=plugins=grpc:. -I=. \
|
||||
-I="${GOGOPROTO_PATH}" \
|
||||
./io/prometheus/write/v2/*.proto
|
||||
protoc --gogofast_out=Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types,paths=source_relative:. -I=. \
|
||||
-I="${GOGOPROTO_PATH}" \
|
||||
./io/prometheus/client/*.proto
|
||||
sed -i.bak -E 's/import _ \"github.com\/gogo\/protobuf\/gogoproto\"//g' *.pb.go
|
||||
sed -i.bak -E 's/import _ \"google\/protobuf\"//g' *.pb.go
|
||||
sed -i.bak -E 's/\t_ \"google\/protobuf\"//g' *.pb.go
|
||||
sed -i.bak -E 's/golang\/protobuf\/descriptor/gogo\/protobuf\/protoc-gen-gogo\/descriptor/g' *.go
|
||||
sed -i.bak -E 's/golang\/protobuf/gogo\/protobuf/g' *.go
|
||||
${SED} -i.bak -E 's/import _ \"github.com\/gogo\/protobuf\/gogoproto\"//g' *.pb.go
|
||||
${SED} -i.bak -E 's/import _ \"google\/protobuf\"//g' *.pb.go
|
||||
${SED} -i.bak -E 's/\t_ \"google\/protobuf\"//g' *.pb.go
|
||||
${SED} -i.bak -E 's/golang\/protobuf\/descriptor/gogo\/protobuf\/protoc-gen-gogo\/descriptor/g' *.go
|
||||
${SED} -i.bak -E 's/golang\/protobuf/gogo\/protobuf/g' *.go
|
||||
rm -f -- *.bak
|
||||
goimports -w ./*.go ./io/prometheus/client/*.go
|
||||
popd
|
||||
|
|
|
|||
Loading…
Reference in a new issue