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.
 
 

179 lines
4.4 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. "strconv"
  18. "strings"
  19. )
  20. type FloatString float64
  21. func (v FloatString) String() string {
  22. return strconv.FormatFloat(float64(v), 'f', -1, 64)
  23. }
  24. func (v FloatString) MarshalJSON() ([]byte, error) {
  25. return json.Marshal(v.String())
  26. }
  27. func (v *FloatString) UnmarshalJSON(b []byte) error {
  28. if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' {
  29. return fmt.Errorf("float value must be a quoted string")
  30. }
  31. f, err := strconv.ParseFloat(string(b[1:len(b)-1]), 64)
  32. if err != nil {
  33. return err
  34. }
  35. *v = FloatString(f)
  36. return nil
  37. }
  38. type HistogramBucket struct {
  39. Boundaries int32
  40. Lower FloatString
  41. Upper FloatString
  42. Count FloatString
  43. }
  44. func (s HistogramBucket) MarshalJSON() ([]byte, error) {
  45. b, err := json.Marshal(s.Boundaries)
  46. if err != nil {
  47. return nil, err
  48. }
  49. l, err := json.Marshal(s.Lower)
  50. if err != nil {
  51. return nil, err
  52. }
  53. u, err := json.Marshal(s.Upper)
  54. if err != nil {
  55. return nil, err
  56. }
  57. c, err := json.Marshal(s.Count)
  58. if err != nil {
  59. return nil, err
  60. }
  61. return []byte(fmt.Sprintf("[%s,%s,%s,%s]", b, l, u, c)), nil
  62. }
  63. func (s *HistogramBucket) UnmarshalJSON(buf []byte) error {
  64. tmp := []interface{}{&s.Boundaries, &s.Lower, &s.Upper, &s.Count}
  65. wantLen := len(tmp)
  66. if err := json.Unmarshal(buf, &tmp); err != nil {
  67. return err
  68. }
  69. if gotLen := len(tmp); gotLen != wantLen {
  70. return fmt.Errorf("wrong number of fields: %d != %d", gotLen, wantLen)
  71. }
  72. return nil
  73. }
  74. func (s *HistogramBucket) Equal(o *HistogramBucket) bool {
  75. return s == o || (s.Boundaries == o.Boundaries && s.Lower == o.Lower && s.Upper == o.Upper && s.Count == o.Count)
  76. }
  77. func (b HistogramBucket) String() string {
  78. var sb strings.Builder
  79. lowerInclusive := b.Boundaries == 1 || b.Boundaries == 3
  80. upperInclusive := b.Boundaries == 0 || b.Boundaries == 3
  81. if lowerInclusive {
  82. sb.WriteRune('[')
  83. } else {
  84. sb.WriteRune('(')
  85. }
  86. fmt.Fprintf(&sb, "%g,%g", b.Lower, b.Upper)
  87. if upperInclusive {
  88. sb.WriteRune(']')
  89. } else {
  90. sb.WriteRune(')')
  91. }
  92. fmt.Fprintf(&sb, ":%v", b.Count)
  93. return sb.String()
  94. }
  95. type HistogramBuckets []*HistogramBucket
  96. func (s HistogramBuckets) Equal(o HistogramBuckets) bool {
  97. if len(s) != len(o) {
  98. return false
  99. }
  100. for i, bucket := range s {
  101. if !bucket.Equal(o[i]) {
  102. return false
  103. }
  104. }
  105. return true
  106. }
  107. type SampleHistogram struct {
  108. Count FloatString `json:"count"`
  109. Sum FloatString `json:"sum"`
  110. Buckets HistogramBuckets `json:"buckets"`
  111. }
  112. func (s SampleHistogram) String() string {
  113. return fmt.Sprintf("Count: %f, Sum: %f, Buckets: %v", s.Count, s.Sum, s.Buckets)
  114. }
  115. func (s *SampleHistogram) Equal(o *SampleHistogram) bool {
  116. return s == o || (s.Count == o.Count && s.Sum == o.Sum && s.Buckets.Equal(o.Buckets))
  117. }
  118. type SampleHistogramPair struct {
  119. Timestamp Time
  120. // Histogram should never be nil, it's only stored as pointer for efficiency.
  121. Histogram *SampleHistogram
  122. }
  123. func (s SampleHistogramPair) MarshalJSON() ([]byte, error) {
  124. if s.Histogram == nil {
  125. return nil, fmt.Errorf("histogram is nil")
  126. }
  127. t, err := json.Marshal(s.Timestamp)
  128. if err != nil {
  129. return nil, err
  130. }
  131. v, err := json.Marshal(s.Histogram)
  132. if err != nil {
  133. return nil, err
  134. }
  135. return []byte(fmt.Sprintf("[%s,%s]", t, v)), nil
  136. }
  137. func (s *SampleHistogramPair) UnmarshalJSON(buf []byte) error {
  138. tmp := []interface{}{&s.Timestamp, &s.Histogram}
  139. wantLen := len(tmp)
  140. if err := json.Unmarshal(buf, &tmp); err != nil {
  141. return err
  142. }
  143. if gotLen := len(tmp); gotLen != wantLen {
  144. return fmt.Errorf("wrong number of fields: %d != %d", gotLen, wantLen)
  145. }
  146. if s.Histogram == nil {
  147. return fmt.Errorf("histogram is null")
  148. }
  149. return nil
  150. }
  151. func (s SampleHistogramPair) String() string {
  152. return fmt.Sprintf("%s @[%s]", s.Histogram, s.Timestamp)
  153. }
  154. func (s *SampleHistogramPair) Equal(o *SampleHistogramPair) bool {
  155. return s == o || (s.Histogram.Equal(o.Histogram) && s.Timestamp.Equal(o.Timestamp))
  156. }