1 // Copyright 2013 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
6 // http://www.apache.org/licenses/LICENSE-2.0
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.
26 // ZeroSamplePair is the pseudo zero-value of SamplePair used to signal a
27 // non-existing sample pair. It is a SamplePair with timestamp Earliest and
28 // value 0.0. Note that the natural zero value of SamplePair has a timestamp
29 // of 0, which is possible to appear in a real SamplePair and thus not
30 // suitable to signal a non-existing SamplePair.
31 ZeroSamplePair = SamplePair{Timestamp: Earliest}
33 // ZeroSample is the pseudo zero-value of Sample used to signal a
34 // non-existing sample. It is a Sample with timestamp Earliest, value 0.0,
35 // and metric nil. Note that the natural zero value of Sample has a timestamp
36 // of 0, which is possible to appear in a real Sample and thus not suitable
37 // to signal a non-existing Sample.
38 ZeroSample = Sample{Timestamp: Earliest}
41 // A SampleValue is a representation of a value for a given sample at a given
43 type SampleValue float64
45 // MarshalJSON implements json.Marshaler.
46 func (v SampleValue) MarshalJSON() ([]byte, error) {
47 return json.Marshal(v.String())
50 // UnmarshalJSON implements json.Unmarshaler.
51 func (v *SampleValue) UnmarshalJSON(b []byte) error {
52 if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' {
53 return fmt.Errorf("sample value must be a quoted string")
55 f, err := strconv.ParseFloat(string(b[1:len(b)-1]), 64)
63 // Equal returns true if the value of v and o is equal or if both are NaN. Note
64 // that v==o is false if both are NaN. If you want the conventional float
65 // behavior, use == to compare two SampleValues.
66 func (v SampleValue) Equal(o SampleValue) bool {
70 return math.IsNaN(float64(v)) && math.IsNaN(float64(o))
73 func (v SampleValue) String() string {
74 return strconv.FormatFloat(float64(v), 'f', -1, 64)
77 // SamplePair pairs a SampleValue with a Timestamp.
78 type SamplePair struct {
83 // MarshalJSON implements json.Marshaler.
84 func (s SamplePair) MarshalJSON() ([]byte, error) {
85 t, err := json.Marshal(s.Timestamp)
89 v, err := json.Marshal(s.Value)
93 return []byte(fmt.Sprintf("[%s,%s]", t, v)), nil
96 // UnmarshalJSON implements json.Unmarshaler.
97 func (s *SamplePair) UnmarshalJSON(b []byte) error {
98 v := [...]json.Unmarshaler{&s.Timestamp, &s.Value}
99 return json.Unmarshal(b, &v)
102 // Equal returns true if this SamplePair and o have equal Values and equal
103 // Timestamps. The semantics of Value equality is defined by SampleValue.Equal.
104 func (s *SamplePair) Equal(o *SamplePair) bool {
105 return s == o || (s.Value.Equal(o.Value) && s.Timestamp.Equal(o.Timestamp))
108 func (s SamplePair) String() string {
109 return fmt.Sprintf("%s @[%s]", s.Value, s.Timestamp)
112 // Sample is a sample pair associated with a metric.
114 Metric Metric `json:"metric"`
115 Value SampleValue `json:"value"`
116 Timestamp Time `json:"timestamp"`
119 // Equal compares first the metrics, then the timestamp, then the value. The
120 // semantics of value equality is defined by SampleValue.Equal.
121 func (s *Sample) Equal(o *Sample) bool {
126 if !s.Metric.Equal(o.Metric) {
129 if !s.Timestamp.Equal(o.Timestamp) {
133 return s.Value.Equal(o.Value)
136 func (s Sample) String() string {
137 return fmt.Sprintf("%s => %s", s.Metric, SamplePair{
138 Timestamp: s.Timestamp,
143 // MarshalJSON implements json.Marshaler.
144 func (s Sample) MarshalJSON() ([]byte, error) {
146 Metric Metric `json:"metric"`
147 Value SamplePair `json:"value"`
151 Timestamp: s.Timestamp,
156 return json.Marshal(&v)
159 // UnmarshalJSON implements json.Unmarshaler.
160 func (s *Sample) UnmarshalJSON(b []byte) error {
162 Metric Metric `json:"metric"`
163 Value SamplePair `json:"value"`
167 Timestamp: s.Timestamp,
172 if err := json.Unmarshal(b, &v); err != nil {
177 s.Timestamp = v.Value.Timestamp
178 s.Value = v.Value.Value
183 // Samples is a sortable Sample slice. It implements sort.Interface.
184 type Samples []*Sample
186 func (s Samples) Len() int {
190 // Less compares first the metrics, then the timestamp.
191 func (s Samples) Less(i, j int) bool {
193 case s[i].Metric.Before(s[j].Metric):
195 case s[j].Metric.Before(s[i].Metric):
197 case s[i].Timestamp.Before(s[j].Timestamp):
204 func (s Samples) Swap(i, j int) {
205 s[i], s[j] = s[j], s[i]
208 // Equal compares two sets of samples and returns true if they are equal.
209 func (s Samples) Equal(o Samples) bool {
210 if len(s) != len(o) {
214 for i, sample := range s {
215 if !sample.Equal(o[i]) {
222 // SampleStream is a stream of Values belonging to an attached COWMetric.
223 type SampleStream struct {
224 Metric Metric `json:"metric"`
225 Values []SamplePair `json:"values"`
228 func (ss SampleStream) String() string {
229 vals := make([]string, len(ss.Values))
230 for i, v := range ss.Values {
233 return fmt.Sprintf("%s =>\n%s", ss.Metric, strings.Join(vals, "\n"))
236 // Value is a generic interface for values resulting from a query evaluation.
237 type Value interface {
242 func (Matrix) Type() ValueType { return ValMatrix }
243 func (Vector) Type() ValueType { return ValVector }
244 func (*Scalar) Type() ValueType { return ValScalar }
245 func (*String) Type() ValueType { return ValString }
250 ValNone ValueType = iota
257 // MarshalJSON implements json.Marshaler.
258 func (et ValueType) MarshalJSON() ([]byte, error) {
259 return json.Marshal(et.String())
262 func (et *ValueType) UnmarshalJSON(b []byte) error {
264 if err := json.Unmarshal(b, &s); err != nil {
279 return fmt.Errorf("unknown value type %q", s)
284 func (e ValueType) String() string {
297 panic("ValueType.String: unhandled value type")
300 // Scalar is a scalar value evaluated at the set timestamp.
302 Value SampleValue `json:"value"`
303 Timestamp Time `json:"timestamp"`
306 func (s Scalar) String() string {
307 return fmt.Sprintf("scalar: %v @[%v]", s.Value, s.Timestamp)
310 // MarshalJSON implements json.Marshaler.
311 func (s Scalar) MarshalJSON() ([]byte, error) {
312 v := strconv.FormatFloat(float64(s.Value), 'f', -1, 64)
313 return json.Marshal([...]interface{}{s.Timestamp, string(v)})
316 // UnmarshalJSON implements json.Unmarshaler.
317 func (s *Scalar) UnmarshalJSON(b []byte) error {
319 v := [...]interface{}{&s.Timestamp, &f}
321 if err := json.Unmarshal(b, &v); err != nil {
325 value, err := strconv.ParseFloat(f, 64)
327 return fmt.Errorf("error parsing sample value: %s", err)
329 s.Value = SampleValue(value)
333 // String is a string value evaluated at the set timestamp.
335 Value string `json:"value"`
336 Timestamp Time `json:"timestamp"`
339 func (s *String) String() string {
343 // MarshalJSON implements json.Marshaler.
344 func (s String) MarshalJSON() ([]byte, error) {
345 return json.Marshal([]interface{}{s.Timestamp, s.Value})
348 // UnmarshalJSON implements json.Unmarshaler.
349 func (s *String) UnmarshalJSON(b []byte) error {
350 v := [...]interface{}{&s.Timestamp, &s.Value}
351 return json.Unmarshal(b, &v)
354 // Vector is basically only an alias for Samples, but the
355 // contract is that in a Vector, all Samples have the same timestamp.
356 type Vector []*Sample
358 func (vec Vector) String() string {
359 entries := make([]string, len(vec))
360 for i, s := range vec {
361 entries[i] = s.String()
363 return strings.Join(entries, "\n")
366 func (vec Vector) Len() int { return len(vec) }
367 func (vec Vector) Swap(i, j int) { vec[i], vec[j] = vec[j], vec[i] }
369 // Less compares first the metrics, then the timestamp.
370 func (vec Vector) Less(i, j int) bool {
372 case vec[i].Metric.Before(vec[j].Metric):
374 case vec[j].Metric.Before(vec[i].Metric):
376 case vec[i].Timestamp.Before(vec[j].Timestamp):
383 // Equal compares two sets of samples and returns true if they are equal.
384 func (vec Vector) Equal(o Vector) bool {
385 if len(vec) != len(o) {
389 for i, sample := range vec {
390 if !sample.Equal(o[i]) {
397 // Matrix is a list of time series.
398 type Matrix []*SampleStream
400 func (m Matrix) Len() int { return len(m) }
401 func (m Matrix) Less(i, j int) bool { return m[i].Metric.Before(m[j].Metric) }
402 func (m Matrix) Swap(i, j int) { m[i], m[j] = m[j], m[i] }
404 func (mat Matrix) String() string {
405 matCp := make(Matrix, len(mat))
409 strs := make([]string, len(matCp))
411 for i, ss := range matCp {
412 strs[i] = ss.String()
415 return strings.Join(strs, "\n")