promql字符串解析
lexer 用来将promql字符串解析成item
volume_manager_total_volumes{instance="lfgphicprd07591",job="kubernetes-nodes",kubernetes_io_arch="amd64"}[5m]
// item represents a token or text string returned from the scanner.
type item struct {
typ ItemType // The type of this item.
pos Pos // The starting position, in bytes, of this item in the input string.
val string // The value of this item.
}StateFunc
// stateFn represents the state of the scanner as a function that returns the next state. type stateFn func(*lexer) stateFn
lexStatements 识别所有表达式中可分类的部分,并将一般可解析的转化为itemlexInsideBraces 识别{}中可能出现的字符解析:eof space 字母或者下划线 ," ' =~ != !~ ` lexValueSequence lexLineComment 识别注释行lexNumberOrDuration 识别数组或者区间 lexString 识别引号中的文本包括单双引号lexRawString 识别原始的文本lexKeywordOrIdentifier 识别字母数字标记符号(labelname)或关键字lexDuration识别时间区间 smhdwy lexSpace识别空白字符 lexIdentifier 识别字母数字标记符号lexNumber 识别数字lexEscape 识别转义字符
操作pos
next
// next returns the next rune in the input.
func (l *lexer) next() rune {
if int(l.pos) >= len(l.input) {
l.width = 0
return eof
}
r, w := utf8.DecodeRuneInString(l.input[l.pos:])
l.width = Pos(w)
l.pos += l.width
return r
}peek
// peek returns but does not consume the next rune in the input.
func (l *lexer) peek() rune {
r := l.next()
l.backup()
return r
}backup
// backup steps back one rune. Can only be called once per call of next.
func (l *lexer) backup() {
l.pos -= l.width
}读取item
emit
loop
// run runs the state machine for the lexer.
func (l *lexer) run() {
for l.state = lexStatements; l.state != nil; {
l.state = l.state(l)
}
close(l.items)
}utf8.DecodeRuneInString() 返回一个r和长度,r对应字符本身,长度对应r采用UTF8编码后的编码字节数目
parse
ParseMetric、ParseMetricSelector 处理基本逻辑一致:
初始化新的解析器
使用
func (p *parser) labelMatchers(operators ...ItemType) []*labels.Matcher获取过滤器中所有matchParseMetric 直接获取labelMatchers中name、value返回labels.Labels
ParseMetricSelector 获取所有p.labelMatchers(ItemEQL, ItemNEQ, ItemEQLRegex, ItemNEQRegex)过滤并根据传入的name 字符串创建一个
__name__="name"的Matcher
func newParser(input string) *parser {
p := &parser{
lex: lex(input),
}
return p
}ParseMetric
newParser(input string) --> metric() 判断第一个item类型为左大括号:p.labelSet() 判断最后一个是不是 ItemComma ItemRightBrace 作为终止标志 获取label name、value以及 matchType(过滤类型)
ParseMetricSelector
newParser(input string) --> parseExpr() --> VectorSelector(name)
ParseExpr
newParser(input string) --> parseExpr() --> typecheck(expr)
- 点赞
- 收藏
- 关注作者
评论(0)