You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

367 lines
8.9 KiB

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