github.com/go-graphite/carbonapi@v0.17.0/zipper/protocols/irondb/irondb_helpers.go (about)

     1  package irondb
     2  
     3  import (
     4  	"fmt"
     5  	"math"
     6  	"regexp"
     7  	"strings"
     8  )
     9  
    10  // graphiteExprListToIronDBTagQuery - converts list of Graphite Tag expressions to IronDB Tag query
    11  // e.g. ["name=~cpu\..*", "tag1!=value1"] => and(__name:/cpu\..*/,not(tag1:value1))
    12  func graphiteExprListToIronDBTagQuery(exprList []string) string {
    13  	var r []string
    14  	var irondbOp string
    15  	for _, expr := range exprList {
    16  		// remove escaped quotes
    17  		expr = strings.ReplaceAll(expr, "\"", "")
    18  		eqIdx := strings.Index(expr, "=")
    19  		if eqIdx > 0 {
    20  			tagName := expr[:eqIdx]
    21  			neqIdx := strings.Index(expr, "!")
    22  			if neqIdx == -1 {
    23  				irondbOp = "and"
    24  			} else {
    25  				irondbOp = "not"
    26  				tagName = expr[:neqIdx]
    27  			}
    28  			if tagName == "name" {
    29  				tagName = "__name"
    30  			}
    31  			if expr[eqIdx+1] == '~' {
    32  				// op = "=~" or op = "!~"
    33  				// tagValue = expr[eq_idx+2:]
    34  				r = append(r, fmt.Sprintf("%s(%s:/%s/)", irondbOp, tagName, expr[eqIdx+2:]))
    35  			} else {
    36  				// op = "=" or op = "!="
    37  				// tagValue = expr[eq_idx+1:]
    38  				r = append(r, fmt.Sprintf("%s(%s:%s)", irondbOp, tagName, expr[eqIdx+1:]))
    39  			}
    40  		}
    41  	}
    42  	switch len(r) {
    43  	case 0:
    44  		return ""
    45  	case 1:
    46  		return r[0]
    47  	default:
    48  		return fmt.Sprintf("and(%s)", strings.Join(r, ","))
    49  	}
    50  }
    51  
    52  // convertNameToGraphite - convert IronDB tagged name to Graphite-web
    53  func convertNameToGraphite(name string) string {
    54  	// if name contains tags - convert to same format as python graphite-irondb uses
    55  	// remove all MT tags
    56  	if strings.Contains(name, "|MT{") {
    57  		mtRe := regexp.MustCompile(`\|MT{([^}]*)}`)
    58  		name = mtRe.ReplaceAllString(name, "")
    59  	}
    60  	if strings.Contains(name, "|ST[") {
    61  		name = strings.ReplaceAll(name, "|ST[", ";")
    62  		name = strings.ReplaceAll(name, "]", "")
    63  		name = strings.ReplaceAll(name, ",", ";")
    64  		name = strings.ReplaceAll(name, ":", "=")
    65  	}
    66  	return name
    67  }
    68  
    69  // AdjustStep adjusts step keeping in mind default/configurable limit of maximum points per query
    70  // Steps sequence is aligned with Grafana. Step progresses in the following order:
    71  // minimal configured step if not default => 20 => 30 => 60 => 120 => 300 => 600 => 900 => 1200 => 1800 => 3600 => 7200 => 10800 => 21600 => 43200 => 86400
    72  func adjustStep(start, stop, maxPointsPerQuery, minStep int64) int64 {
    73  	safeStep := minStep
    74  	if maxPointsPerQuery != 0 {
    75  		safeStep = int64(math.Ceil(float64(stop-start) / float64(maxPointsPerQuery)))
    76  	}
    77  
    78  	step := minStep
    79  	if safeStep > minStep {
    80  		step = safeStep
    81  	}
    82  
    83  	switch {
    84  	case step <= minStep:
    85  		return minStep // minimal configured step
    86  	case step <= 20:
    87  		return 20 // 20s
    88  	case step <= 30:
    89  		return 30 // 30s
    90  	case step <= 60:
    91  		return 60 // 1m
    92  	case step <= 120:
    93  		return 120 // 2m
    94  	case step <= 300:
    95  		return 300 // 5m
    96  	case step <= 600:
    97  		return 600 // 10m
    98  	case step <= 900:
    99  		return 900 // 15m
   100  	case step <= 1200:
   101  		return 1200 // 20m
   102  	case step <= 1800:
   103  		return 1800 // 30m
   104  	case step <= 3600:
   105  		return 3600 // 1h
   106  	case step <= 7200:
   107  		return 7200 // 2h
   108  	case step <= 10800:
   109  		return 10800 // 3h
   110  	case step <= 21600:
   111  		return 21600 // 6h
   112  	case step <= 43200:
   113  		return 43200 // 12h
   114  	default:
   115  		return 86400 // 24h
   116  	}
   117  }