...

Source file src/github.com/prometheus/common/model/value.go

Documentation: github.com/prometheus/common/model

     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
     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 model
    15  
    16  import (
    17  	"encoding/json"
    18  	"fmt"
    19  	"sort"
    20  	"strconv"
    21  	"strings"
    22  )
    23  
    24  // ZeroSample is the pseudo zero-value of Sample used to signal a
    25  // non-existing sample. It is a Sample with timestamp Earliest, value 0.0,
    26  // and metric nil. Note that the natural zero value of Sample has a timestamp
    27  // of 0, which is possible to appear in a real Sample and thus not suitable
    28  // to signal a non-existing Sample.
    29  var ZeroSample = Sample{Timestamp: Earliest}
    30  
    31  // Sample is a sample pair associated with a metric. A single sample must either
    32  // define Value or Histogram but not both. Histogram == nil implies the Value
    33  // field is used, otherwise it should be ignored.
    34  type Sample struct {
    35  	Metric    Metric           `json:"metric"`
    36  	Value     SampleValue      `json:"value"`
    37  	Timestamp Time             `json:"timestamp"`
    38  	Histogram *SampleHistogram `json:"histogram"`
    39  }
    40  
    41  // Equal compares first the metrics, then the timestamp, then the value. The
    42  // semantics of value equality is defined by SampleValue.Equal.
    43  func (s *Sample) Equal(o *Sample) bool {
    44  	if s == o {
    45  		return true
    46  	}
    47  
    48  	if !s.Metric.Equal(o.Metric) {
    49  		return false
    50  	}
    51  	if !s.Timestamp.Equal(o.Timestamp) {
    52  		return false
    53  	}
    54  	if s.Histogram != nil {
    55  		return s.Histogram.Equal(o.Histogram)
    56  	}
    57  	return s.Value.Equal(o.Value)
    58  }
    59  
    60  func (s Sample) String() string {
    61  	if s.Histogram != nil {
    62  		return fmt.Sprintf("%s => %s", s.Metric, SampleHistogramPair{
    63  			Timestamp: s.Timestamp,
    64  			Histogram: s.Histogram,
    65  		})
    66  	}
    67  	return fmt.Sprintf("%s => %s", s.Metric, SamplePair{
    68  		Timestamp: s.Timestamp,
    69  		Value:     s.Value,
    70  	})
    71  }
    72  
    73  // MarshalJSON implements json.Marshaler.
    74  func (s Sample) MarshalJSON() ([]byte, error) {
    75  	if s.Histogram != nil {
    76  		v := struct {
    77  			Metric    Metric              `json:"metric"`
    78  			Histogram SampleHistogramPair `json:"histogram"`
    79  		}{
    80  			Metric: s.Metric,
    81  			Histogram: SampleHistogramPair{
    82  				Timestamp: s.Timestamp,
    83  				Histogram: s.Histogram,
    84  			},
    85  		}
    86  		return json.Marshal(&v)
    87  	}
    88  	v := struct {
    89  		Metric Metric     `json:"metric"`
    90  		Value  SamplePair `json:"value"`
    91  	}{
    92  		Metric: s.Metric,
    93  		Value: SamplePair{
    94  			Timestamp: s.Timestamp,
    95  			Value:     s.Value,
    96  		},
    97  	}
    98  	return json.Marshal(&v)
    99  }
   100  
   101  // UnmarshalJSON implements json.Unmarshaler.
   102  func (s *Sample) UnmarshalJSON(b []byte) error {
   103  	v := struct {
   104  		Metric    Metric              `json:"metric"`
   105  		Value     SamplePair          `json:"value"`
   106  		Histogram SampleHistogramPair `json:"histogram"`
   107  	}{
   108  		Metric: s.Metric,
   109  		Value: SamplePair{
   110  			Timestamp: s.Timestamp,
   111  			Value:     s.Value,
   112  		},
   113  		Histogram: SampleHistogramPair{
   114  			Timestamp: s.Timestamp,
   115  			Histogram: s.Histogram,
   116  		},
   117  	}
   118  
   119  	if err := json.Unmarshal(b, &v); err != nil {
   120  		return err
   121  	}
   122  
   123  	s.Metric = v.Metric
   124  	if v.Histogram.Histogram != nil {
   125  		s.Timestamp = v.Histogram.Timestamp
   126  		s.Histogram = v.Histogram.Histogram
   127  	} else {
   128  		s.Timestamp = v.Value.Timestamp
   129  		s.Value = v.Value.Value
   130  	}
   131  
   132  	return nil
   133  }
   134  
   135  // Samples is a sortable Sample slice. It implements sort.Interface.
   136  type Samples []*Sample
   137  
   138  func (s Samples) Len() int {
   139  	return len(s)
   140  }
   141  
   142  // Less compares first the metrics, then the timestamp.
   143  func (s Samples) Less(i, j int) bool {
   144  	switch {
   145  	case s[i].Metric.Before(s[j].Metric):
   146  		return true
   147  	case s[j].Metric.Before(s[i].Metric):
   148  		return false
   149  	case s[i].Timestamp.Before(s[j].Timestamp):
   150  		return true
   151  	default:
   152  		return false
   153  	}
   154  }
   155  
   156  func (s Samples) Swap(i, j int) {
   157  	s[i], s[j] = s[j], s[i]
   158  }
   159  
   160  // Equal compares two sets of samples and returns true if they are equal.
   161  func (s Samples) Equal(o Samples) bool {
   162  	if len(s) != len(o) {
   163  		return false
   164  	}
   165  
   166  	for i, sample := range s {
   167  		if !sample.Equal(o[i]) {
   168  			return false
   169  		}
   170  	}
   171  	return true
   172  }
   173  
   174  // SampleStream is a stream of Values belonging to an attached COWMetric.
   175  type SampleStream struct {
   176  	Metric     Metric                `json:"metric"`
   177  	Values     []SamplePair          `json:"values"`
   178  	Histograms []SampleHistogramPair `json:"histograms"`
   179  }
   180  
   181  func (ss SampleStream) String() string {
   182  	valuesLength := len(ss.Values)
   183  	vals := make([]string, valuesLength+len(ss.Histograms))
   184  	for i, v := range ss.Values {
   185  		vals[i] = v.String()
   186  	}
   187  	for i, v := range ss.Histograms {
   188  		vals[i+valuesLength] = v.String()
   189  	}
   190  	return fmt.Sprintf("%s =>\n%s", ss.Metric, strings.Join(vals, "\n"))
   191  }
   192  
   193  func (ss SampleStream) MarshalJSON() ([]byte, error) {
   194  	if len(ss.Histograms) > 0 && len(ss.Values) > 0 {
   195  		v := struct {
   196  			Metric     Metric                `json:"metric"`
   197  			Values     []SamplePair          `json:"values"`
   198  			Histograms []SampleHistogramPair `json:"histograms"`
   199  		}{
   200  			Metric:     ss.Metric,
   201  			Values:     ss.Values,
   202  			Histograms: ss.Histograms,
   203  		}
   204  		return json.Marshal(&v)
   205  	} else if len(ss.Histograms) > 0 {
   206  		v := struct {
   207  			Metric     Metric                `json:"metric"`
   208  			Histograms []SampleHistogramPair `json:"histograms"`
   209  		}{
   210  			Metric:     ss.Metric,
   211  			Histograms: ss.Histograms,
   212  		}
   213  		return json.Marshal(&v)
   214  	} else {
   215  		v := struct {
   216  			Metric Metric       `json:"metric"`
   217  			Values []SamplePair `json:"values"`
   218  		}{
   219  			Metric: ss.Metric,
   220  			Values: ss.Values,
   221  		}
   222  		return json.Marshal(&v)
   223  	}
   224  }
   225  
   226  func (ss *SampleStream) UnmarshalJSON(b []byte) error {
   227  	v := struct {
   228  		Metric     Metric                `json:"metric"`
   229  		Values     []SamplePair          `json:"values"`
   230  		Histograms []SampleHistogramPair `json:"histograms"`
   231  	}{
   232  		Metric:     ss.Metric,
   233  		Values:     ss.Values,
   234  		Histograms: ss.Histograms,
   235  	}
   236  
   237  	if err := json.Unmarshal(b, &v); err != nil {
   238  		return err
   239  	}
   240  
   241  	ss.Metric = v.Metric
   242  	ss.Values = v.Values
   243  	ss.Histograms = v.Histograms
   244  
   245  	return nil
   246  }
   247  
   248  // Scalar is a scalar value evaluated at the set timestamp.
   249  type Scalar struct {
   250  	Value     SampleValue `json:"value"`
   251  	Timestamp Time        `json:"timestamp"`
   252  }
   253  
   254  func (s Scalar) String() string {
   255  	return fmt.Sprintf("scalar: %v @[%v]", s.Value, s.Timestamp)
   256  }
   257  
   258  // MarshalJSON implements json.Marshaler.
   259  func (s Scalar) MarshalJSON() ([]byte, error) {
   260  	v := strconv.FormatFloat(float64(s.Value), 'f', -1, 64)
   261  	return json.Marshal([...]interface{}{s.Timestamp, string(v)})
   262  }
   263  
   264  // UnmarshalJSON implements json.Unmarshaler.
   265  func (s *Scalar) UnmarshalJSON(b []byte) error {
   266  	var f string
   267  	v := [...]interface{}{&s.Timestamp, &f}
   268  
   269  	if err := json.Unmarshal(b, &v); err != nil {
   270  		return err
   271  	}
   272  
   273  	value, err := strconv.ParseFloat(f, 64)
   274  	if err != nil {
   275  		return fmt.Errorf("error parsing sample value: %w", err)
   276  	}
   277  	s.Value = SampleValue(value)
   278  	return nil
   279  }
   280  
   281  // String is a string value evaluated at the set timestamp.
   282  type String struct {
   283  	Value     string `json:"value"`
   284  	Timestamp Time   `json:"timestamp"`
   285  }
   286  
   287  func (s *String) String() string {
   288  	return s.Value
   289  }
   290  
   291  // MarshalJSON implements json.Marshaler.
   292  func (s String) MarshalJSON() ([]byte, error) {
   293  	return json.Marshal([]interface{}{s.Timestamp, s.Value})
   294  }
   295  
   296  // UnmarshalJSON implements json.Unmarshaler.
   297  func (s *String) UnmarshalJSON(b []byte) error {
   298  	v := [...]interface{}{&s.Timestamp, &s.Value}
   299  	return json.Unmarshal(b, &v)
   300  }
   301  
   302  // Vector is basically only an alias for Samples, but the
   303  // contract is that in a Vector, all Samples have the same timestamp.
   304  type Vector []*Sample
   305  
   306  func (vec Vector) String() string {
   307  	entries := make([]string, len(vec))
   308  	for i, s := range vec {
   309  		entries[i] = s.String()
   310  	}
   311  	return strings.Join(entries, "\n")
   312  }
   313  
   314  func (vec Vector) Len() int      { return len(vec) }
   315  func (vec Vector) Swap(i, j int) { vec[i], vec[j] = vec[j], vec[i] }
   316  
   317  // Less compares first the metrics, then the timestamp.
   318  func (vec Vector) Less(i, j int) bool {
   319  	switch {
   320  	case vec[i].Metric.Before(vec[j].Metric):
   321  		return true
   322  	case vec[j].Metric.Before(vec[i].Metric):
   323  		return false
   324  	case vec[i].Timestamp.Before(vec[j].Timestamp):
   325  		return true
   326  	default:
   327  		return false
   328  	}
   329  }
   330  
   331  // Equal compares two sets of samples and returns true if they are equal.
   332  func (vec Vector) Equal(o Vector) bool {
   333  	if len(vec) != len(o) {
   334  		return false
   335  	}
   336  
   337  	for i, sample := range vec {
   338  		if !sample.Equal(o[i]) {
   339  			return false
   340  		}
   341  	}
   342  	return true
   343  }
   344  
   345  // Matrix is a list of time series.
   346  type Matrix []*SampleStream
   347  
   348  func (m Matrix) Len() int           { return len(m) }
   349  func (m Matrix) Less(i, j int) bool { return m[i].Metric.Before(m[j].Metric) }
   350  func (m Matrix) Swap(i, j int)      { m[i], m[j] = m[j], m[i] }
   351  
   352  func (mat Matrix) String() string {
   353  	matCp := make(Matrix, len(mat))
   354  	copy(matCp, mat)
   355  	sort.Sort(matCp)
   356  
   357  	strs := make([]string, len(matCp))
   358  
   359  	for i, ss := range matCp {
   360  		strs[i] = ss.String()
   361  	}
   362  
   363  	return strings.Join(strs, "\n")
   364  }
   365  

View as plain text