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 }