value.go 10.0 KB

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