github.com/m3db/m3@v1.5.0/src/query/api/v1/handler/influxdb/rewrite.go (about) 1 // Copyright (c) 2019 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package influxdb 22 23 import ( 24 "regexp" 25 ) 26 27 type regexpRewriter struct { 28 okStart, okRest [256]bool 29 replacement byte 30 } 31 32 func newRegexpRewriter(startRe, restRe string) *regexpRewriter { 33 createArray := func(okRe string) (ret [256]bool) { 34 re := regexp.MustCompile(okRe) 35 // Check for only 7 bit non-control ASCII characters 36 for i := 32; i < 128; i++ { 37 if re.Match([]byte{byte(i)}) { 38 ret[i] = true 39 } 40 } 41 return 42 } 43 return ®expRewriter{okStart: createArray(startRe), okRest: createArray(restRe), replacement: byte('_')} 44 } 45 46 func (rr *regexpRewriter) rewrite(input []byte) { 47 if len(input) == 0 { 48 return 49 } 50 if !rr.okStart[input[0]] { 51 input[0] = rr.replacement 52 } 53 for i := 1; i < len(input); i++ { 54 if !rr.okRest[input[i]] { 55 input[i] = rr.replacement 56 } 57 } 58 } 59 60 // Utility, which handles both __name__ ('metric') tag, as well as 61 // rest of tags ('labels') 62 // 63 // It allow using any influxdb client, rewriting the tag names + the 64 // magic __name__ tag to match what Prometheus expects 65 type promRewriter struct { 66 metric, metricTail, label *regexpRewriter 67 } 68 69 func newPromRewriter() *promRewriter { 70 return &promRewriter{ 71 metric: newRegexpRewriter( 72 "[a-zA-Z_:]", 73 "[a-zA-Z0-9_:]"), 74 metricTail: newRegexpRewriter( 75 "[a-zA-Z0-9_:]", 76 "[a-zA-Z0-9_:]"), 77 label: newRegexpRewriter( 78 "[a-zA-Z_]", "[a-zA-Z0-9_]")} 79 } 80 81 func (pr *promRewriter) rewriteMetric(data []byte) { 82 pr.metric.rewrite(data) 83 } 84 85 func (pr *promRewriter) rewriteMetricTail(data []byte) { 86 pr.metricTail.rewrite(data) 87 } 88 89 func (pr *promRewriter) rewriteLabel(data []byte) { 90 pr.label.rewrite(data) 91 }