feat: multiple changes

- implement changes from pair programming session
- use newParse.val()
- advance parser p if ct is found

Signed-off-by: Manik Rana <manikrana54@gmail.com>
This commit is contained in:
Manik Rana 2024-07-04 21:10:24 +05:30
parent 188d4cc927
commit e841e00eed

View file

@ -21,7 +21,6 @@ import (
"fmt" "fmt"
"io" "io"
"math" "math"
"strconv"
"strings" "strings"
"unicode/utf8" "unicode/utf8"
@ -78,7 +77,7 @@ type OpenMetricsParser struct {
series []byte series []byte
text []byte text []byte
mtype model.MetricType mtype model.MetricType
mName string mName string
val float64 val float64
ts int64 ts int64
hasTS bool hasTS bool
@ -224,59 +223,63 @@ func (p *OpenMetricsParser) Exemplar(e *exemplar.Exemplar) bool {
// CreatedTimestamp returns nil as it's not implemented yet. // CreatedTimestamp returns nil as it's not implemented yet.
// TODO(bwplotka): https://github.com/prometheus/prometheus/issues/12980 // TODO(bwplotka): https://github.com/prometheus/prometheus/issues/12980
func (p *OpenMetricsParser) CreatedTimestamp() *int64 { func (p *OpenMetricsParser) CreatedTimestamp() *int64 {
var lbs labels.Labels
p.Metric(&lbs)
lbs = lbs.DropMetricName()
newParser := deepCopyParser(p) newParser := deepCopyParser(p)
switch t, _ := newParser.Next(); t { loop:
for {
switch t, _ := newParser.Next(); t {
case EntrySeries: case EntrySeries:
// continue instead of return nil until we get new series/labels. can happen for histograms, summaries // continue instead of return nil until we get new series/labels. can happen for histograms, summaries
for { // Check _created suffix
// Check _created suffix var newLbs labels.Labels
var lbs labels.Labels newParser.Metric(&newLbs)
newParser.Metric(&lbs) name := newLbs.Get(model.MetricNameLabel)
name := lbs.Get(model.MetricNameLabel) if !strings.HasSuffix(name, "_created") {
if name[len(name)-8:] != "_created" { continue
return nil
}
if newParser.mName != p.mName {
return nil
}
// edge case: if guage_created of unknown type -> skip parsing
// Check if labelsets are the same
// TODO: for histograms
// if t, _ := newParser.Next(); t != EntrySeries {
// return nil
// }
// return CT value
ctBytes := newParser.l.b[newParser.offsets[len(newParser.offsets)-1]+1:newParser.l.start]
ct, err := strconv.ParseInt(yoloString(ctBytes), 10, 64)
if err != nil {
return nil
}
// guage_created is a metric
return &ct
} }
default:
// If not series, we don't care.
}
return nil
}
// We need this because we want offsets of the original parser unchanged when // TODO: potentially broken? Missing type?
// we're working with a new parser in CreatedTimeStamp() if newParser.mName != p.mName {
func deepCopyParser(p *OpenMetricsParser) OpenMetricsParser { return nil
}
// edge case: if guage_created of unknown type -> skip parsing
newLbs = newLbs.DropMetricName()
if !labels.Equal(lbs, newLbs) {
return nil
}
// TODO: for histograms
// if t, _ := newParser.Next(); t != EntrySeries {
// return nil
// }
// guage_created is a metric
ct := int64(newParser.val)
p.Next()
return &ct
default:
break loop
}
}
return nil
}
// We need this because we want offsets of the original parser unchanged when
// we're working with a new parser in CreatedTimeStamp()
func deepCopyParser(p *OpenMetricsParser) OpenMetricsParser {
newB := make([]byte, len(p.l.b)) newB := make([]byte, len(p.l.b))
copy(newB, p.l.b) copy(newB, p.l.b)
newLexer := &openMetricsLexer{ newLexer := &openMetricsLexer{
b: newB, b: newB,
i: p.l.i, i: p.l.i,
start: p.l.start, start: p.l.start,
err: p.l.err, err: p.l.err,
state: p.l.state, state: p.l.state,
} }
@ -289,28 +292,28 @@ func (p *OpenMetricsParser) CreatedTimestamp() *int64 {
newEOffsets := p.eOffsets newEOffsets := p.eOffsets
newExemplar := p.exemplar newExemplar := p.exemplar
newParser := OpenMetricsParser{ newParser := OpenMetricsParser{
l :newLexer, l: newLexer,
builder :p.builder, builder: p.builder,
series :newSeries, series: newSeries,
text :newText, text: newText,
mtype :p.mtype, mtype: p.mtype,
mName :p.mName, mName: p.mName,
val :p.val, val: p.val,
ts :p.ts, ts: p.ts,
hasTS :p.hasTS, hasTS: p.hasTS,
start :p.start, start: p.start,
offsets :newOffsets, offsets: newOffsets,
eOffsets :newEOffsets, eOffsets: newEOffsets,
exemplar :newExemplar, exemplar: newExemplar,
exemplarVal :p.exemplarVal, exemplarVal: p.exemplarVal,
exemplarTs :p.exemplarTs, exemplarTs: p.exemplarTs,
hasExemplarTs :p.hasExemplarTs, hasExemplarTs: p.hasExemplarTs,
} }
return newParser return newParser
} }
// nextToken returns the next token from the openMetricsLexer. // nextToken returns the next token from the openMetricsLexer.
func (p *OpenMetricsParser) nextToken() token { func (p *OpenMetricsParser) nextToken() token {
tok := p.l.Lex() tok := p.l.Lex()