github.com/go-graphite/carbonapi@v0.17.0/expr/helper/metric/extract.go (about) 1 package metric 2 3 import ( 4 "unicode" 5 "unicode/utf8" 6 7 "github.com/go-graphite/carbonapi/pkg/parser" 8 ) 9 10 // ExtractMetric extracts metric out of function list 11 func ExtractMetric(s string) string { 12 // search for a metric name in 's' 13 // metric name is defined to be a Series of name characters terminated by a ',' or ')' 14 // work sample: bla(bla{bl,a}b[la,b]la) => bla{bl,a}b[la 15 16 var ( 17 start, braces, i, w int 18 r rune 19 ) 20 21 FOR: 22 for braces, i, w = 0, 0, 0; i < len(s); i += w { 23 24 w = 1 25 if parser.IsNameChar(s[i]) { 26 continue 27 } 28 29 switch s[i] { 30 // If metric name have tags, we want to skip them 31 case ';': 32 break FOR 33 case '{': 34 braces++ 35 case '}': 36 if braces == 0 { 37 break FOR 38 } 39 braces-- 40 case ',': 41 if braces == 0 { 42 break FOR 43 } 44 case ')': 45 break FOR 46 case '=': 47 // allow metric name to end with any amount of `=` without treating it as a named arg or tag 48 if i == len(s)-1 || s[i+1] == '=' || s[i+1] == ',' || s[i+1] == ')' { 49 continue 50 } 51 fallthrough 52 default: 53 r, w = utf8.DecodeRuneInString(s[i:]) 54 if unicode.In(r, parser.RangeTables...) { 55 continue 56 } 57 start = i + 1 58 } 59 } 60 61 return s[start:i] 62 }