github.com/muhammadn/cortex@v1.9.1-0.20220510110439-46bb7000d03d/pkg/configs/legacy_promql/value.go (about)

     1  // Copyright 2017 The Prometheus Authors
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package promql
    15  
    16  import (
    17  	"encoding/json"
    18  	"fmt"
    19  	"strconv"
    20  	"strings"
    21  
    22  	"github.com/prometheus/prometheus/pkg/labels"
    23  )
    24  
    25  // Value is a generic interface for values resulting from a query evaluation.
    26  type Value interface {
    27  	Type() ValueType
    28  	String() string
    29  }
    30  
    31  func (Matrix) Type() ValueType { return ValueTypeMatrix }
    32  func (Vector) Type() ValueType { return ValueTypeVector }
    33  func (Scalar) Type() ValueType { return ValueTypeScalar }
    34  func (String) Type() ValueType { return ValueTypeString }
    35  
    36  // ValueType describes a type of a value.
    37  type ValueType string
    38  
    39  // The valid value types.
    40  const (
    41  	ValueTypeNone   = "none"
    42  	ValueTypeVector = "vector"
    43  	ValueTypeScalar = "scalar"
    44  	ValueTypeMatrix = "matrix"
    45  	ValueTypeString = "string"
    46  )
    47  
    48  // String represents a string value.
    49  type String struct {
    50  	V string
    51  	T int64
    52  }
    53  
    54  func (s String) String() string {
    55  	return s.V
    56  }
    57  
    58  func (s String) MarshalJSON() ([]byte, error) {
    59  	return json.Marshal([...]interface{}{float64(s.T) / 1000, s.V})
    60  }
    61  
    62  // Scalar is a data point that's explicitly not associated with a metric.
    63  type Scalar struct {
    64  	T int64
    65  	V float64
    66  }
    67  
    68  func (s Scalar) String() string {
    69  	v := strconv.FormatFloat(s.V, 'f', -1, 64)
    70  	return fmt.Sprintf("scalar: %v @[%v]", v, s.T)
    71  }
    72  
    73  func (s Scalar) MarshalJSON() ([]byte, error) {
    74  	v := strconv.FormatFloat(s.V, 'f', -1, 64)
    75  	return json.Marshal([...]interface{}{float64(s.T) / 1000, v})
    76  }
    77  
    78  // Series is a stream of data points belonging to a metric.
    79  type Series struct {
    80  	Metric labels.Labels `json:"metric"`
    81  	Points []Point       `json:"values"`
    82  }
    83  
    84  func (s Series) String() string {
    85  	vals := make([]string, len(s.Points))
    86  	for i, v := range s.Points {
    87  		vals[i] = v.String()
    88  	}
    89  	return fmt.Sprintf("%s =>\n%s", s.Metric, strings.Join(vals, "\n"))
    90  }
    91  
    92  // Point represents a single data point for a given timestamp.
    93  type Point struct {
    94  	T int64
    95  	V float64
    96  }
    97  
    98  func (p Point) String() string {
    99  	v := strconv.FormatFloat(p.V, 'f', -1, 64)
   100  	return fmt.Sprintf("%v @[%v]", v, p.T)
   101  }
   102  
   103  // MarshalJSON implements json.Marshaler.
   104  func (p Point) MarshalJSON() ([]byte, error) {
   105  	v := strconv.FormatFloat(p.V, 'f', -1, 64)
   106  	return json.Marshal([...]interface{}{float64(p.T) / 1000, v})
   107  }
   108  
   109  // Sample is a single sample belonging to a metric.
   110  type Sample struct {
   111  	Point
   112  
   113  	Metric labels.Labels
   114  }
   115  
   116  func (s Sample) String() string {
   117  	return fmt.Sprintf("%s => %s", s.Metric, s.Point)
   118  }
   119  
   120  func (s Sample) MarshalJSON() ([]byte, error) {
   121  	v := struct {
   122  		M labels.Labels `json:"metric"`
   123  		V Point         `json:"value"`
   124  	}{
   125  		M: s.Metric,
   126  		V: s.Point,
   127  	}
   128  	return json.Marshal(v)
   129  }
   130  
   131  // Vector is basically only an alias for model.Samples, but the
   132  // contract is that in a Vector, all Samples have the same timestamp.
   133  type Vector []Sample
   134  
   135  func (vec Vector) String() string {
   136  	entries := make([]string, len(vec))
   137  	for i, s := range vec {
   138  		entries[i] = s.String()
   139  	}
   140  	return strings.Join(entries, "\n")
   141  }
   142  
   143  // Matrix is a slice of Seriess that implements sort.Interface and
   144  // has a String method.
   145  type Matrix []Series
   146  
   147  func (m Matrix) String() string {
   148  	// TODO(fabxc): sort, or can we rely on order from the querier?
   149  	strs := make([]string, len(m))
   150  
   151  	for i, ss := range m {
   152  		strs[i] = ss.String()
   153  	}
   154  
   155  	return strings.Join(strs, "\n")
   156  }
   157  
   158  func (m Matrix) Len() int           { return len(m) }
   159  func (m Matrix) Less(i, j int) bool { return labels.Compare(m[i].Metric, m[j].Metric) < 0 }
   160  func (m Matrix) Swap(i, j int)      { m[i], m[j] = m[j], m[i] }
   161  
   162  // Result holds the resulting value of an execution or an error
   163  // if any occurred.
   164  type Result struct {
   165  	Err   error
   166  	Value Value
   167  }
   168  
   169  // Vector returns a Vector if the result value is one. An error is returned if
   170  // the result was an error or the result value is not a Vector.
   171  func (r *Result) Vector() (Vector, error) {
   172  	if r.Err != nil {
   173  		return nil, r.Err
   174  	}
   175  	v, ok := r.Value.(Vector)
   176  	if !ok {
   177  		return nil, fmt.Errorf("query result is not a Vector")
   178  	}
   179  	return v, nil
   180  }
   181  
   182  // Matrix returns a Matrix. An error is returned if
   183  // the result was an error or the result value is not a Matrix.
   184  func (r *Result) Matrix() (Matrix, error) {
   185  	if r.Err != nil {
   186  		return nil, r.Err
   187  	}
   188  	v, ok := r.Value.(Matrix)
   189  	if !ok {
   190  		return nil, fmt.Errorf("query result is not a range Vector")
   191  	}
   192  	return v, nil
   193  }
   194  
   195  // Scalar returns a Scalar value. An error is returned if
   196  // the result was an error or the result value is not a Scalar.
   197  func (r *Result) Scalar() (Scalar, error) {
   198  	if r.Err != nil {
   199  		return Scalar{}, r.Err
   200  	}
   201  	v, ok := r.Value.(Scalar)
   202  	if !ok {
   203  		return Scalar{}, fmt.Errorf("query result is not a Scalar")
   204  	}
   205  	return v, nil
   206  }
   207  
   208  func (r *Result) String() string {
   209  	if r.Err != nil {
   210  		return r.Err.Error()
   211  	}
   212  	if r.Value == nil {
   213  		return ""
   214  	}
   215  	return r.Value.String()
   216  }