gauge.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. // Copyright 2018, OpenCensus Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package metric
  15. import (
  16. "math"
  17. "sync/atomic"
  18. "time"
  19. "go.opencensus.io/metric/metricdata"
  20. )
  21. // Float64Gauge represents a float64 value that can go up and down.
  22. //
  23. // Float64Gauge maintains a float64 value for each combination of of label values
  24. // passed to the Set or Add methods.
  25. type Float64Gauge struct {
  26. bm baseMetric
  27. }
  28. // Float64Entry represents a single value of the gauge corresponding to a set
  29. // of label values.
  30. type Float64Entry struct {
  31. val uint64 // needs to be uint64 for atomic access, interpret with math.Float64frombits
  32. }
  33. func (e *Float64Entry) read(t time.Time) metricdata.Point {
  34. v := math.Float64frombits(atomic.LoadUint64(&e.val))
  35. if v < 0 {
  36. v = 0
  37. }
  38. return metricdata.NewFloat64Point(t, v)
  39. }
  40. // GetEntry returns a gauge entry where each key for this gauge has the value
  41. // given.
  42. //
  43. // The number of label values supplied must be exactly the same as the number
  44. // of keys supplied when this gauge was created.
  45. func (g *Float64Gauge) GetEntry(labelVals ...metricdata.LabelValue) (*Float64Entry, error) {
  46. entry, err := g.bm.entryForValues(labelVals, func() baseEntry {
  47. return &Float64Entry{}
  48. })
  49. if err != nil {
  50. return nil, err
  51. }
  52. return entry.(*Float64Entry), nil
  53. }
  54. // Set sets the gauge entry value to val.
  55. func (e *Float64Entry) Set(val float64) {
  56. atomic.StoreUint64(&e.val, math.Float64bits(val))
  57. }
  58. // Add increments the gauge entry value by val.
  59. func (e *Float64Entry) Add(val float64) {
  60. var swapped bool
  61. for !swapped {
  62. oldVal := atomic.LoadUint64(&e.val)
  63. newVal := math.Float64bits(math.Float64frombits(oldVal) + val)
  64. swapped = atomic.CompareAndSwapUint64(&e.val, oldVal, newVal)
  65. }
  66. }
  67. // Int64Gauge represents a int64 gauge value that can go up and down.
  68. //
  69. // Int64Gauge maintains an int64 value for each combination of label values passed to the
  70. // Set or Add methods.
  71. type Int64Gauge struct {
  72. bm baseMetric
  73. }
  74. // Int64GaugeEntry represents a single value of the gauge corresponding to a set
  75. // of label values.
  76. type Int64GaugeEntry struct {
  77. val int64
  78. }
  79. func (e *Int64GaugeEntry) read(t time.Time) metricdata.Point {
  80. v := atomic.LoadInt64(&e.val)
  81. if v < 0 {
  82. v = 0.0
  83. }
  84. return metricdata.NewInt64Point(t, v)
  85. }
  86. // GetEntry returns a gauge entry where each key for this gauge has the value
  87. // given.
  88. //
  89. // The number of label values supplied must be exactly the same as the number
  90. // of keys supplied when this gauge was created.
  91. func (g *Int64Gauge) GetEntry(labelVals ...metricdata.LabelValue) (*Int64GaugeEntry, error) {
  92. entry, err := g.bm.entryForValues(labelVals, func() baseEntry {
  93. return &Int64GaugeEntry{}
  94. })
  95. if err != nil {
  96. return nil, err
  97. }
  98. return entry.(*Int64GaugeEntry), nil
  99. }
  100. // Set sets the value of the gauge entry to the provided value.
  101. func (e *Int64GaugeEntry) Set(val int64) {
  102. atomic.StoreInt64(&e.val, val)
  103. }
  104. // Add increments the current gauge entry value by val, which may be negative.
  105. func (e *Int64GaugeEntry) Add(val int64) {
  106. atomic.AddInt64(&e.val, val)
  107. }
  108. // Int64DerivedGauge represents int64 gauge value that is derived from an object.
  109. //
  110. // Int64DerivedGauge maintains objects for each combination of label values.
  111. // These objects implement Int64DerivedGaugeInterface to read instantaneous value
  112. // representing the object.
  113. type Int64DerivedGauge struct {
  114. bm baseMetric
  115. }
  116. type int64DerivedGaugeEntry struct {
  117. fn func() int64
  118. }
  119. func (e *int64DerivedGaugeEntry) read(t time.Time) metricdata.Point {
  120. return metricdata.NewInt64Point(t, e.fn())
  121. }
  122. // UpsertEntry inserts or updates a derived gauge entry for the given set of label values.
  123. // The object for which this gauge entry is inserted or updated, must implement func() int64
  124. //
  125. // It returns an error if
  126. // 1. The number of label values supplied are not the same as the number
  127. // of keys supplied when this gauge was created.
  128. // 2. fn func() int64 is nil.
  129. func (g *Int64DerivedGauge) UpsertEntry(fn func() int64, labelVals ...metricdata.LabelValue) error {
  130. if fn == nil {
  131. return errInvalidParam
  132. }
  133. return g.bm.upsertEntry(labelVals, func() baseEntry {
  134. return &int64DerivedGaugeEntry{fn}
  135. })
  136. }
  137. // Float64DerivedGauge represents float64 gauge value that is derived from an object.
  138. //
  139. // Float64DerivedGauge maintains objects for each combination of label values.
  140. // These objects implement Float64DerivedGaugeInterface to read instantaneous value
  141. // representing the object.
  142. type Float64DerivedGauge struct {
  143. bm baseMetric
  144. }
  145. type float64DerivedGaugeEntry struct {
  146. fn func() float64
  147. }
  148. func (e *float64DerivedGaugeEntry) read(t time.Time) metricdata.Point {
  149. return metricdata.NewFloat64Point(t, e.fn())
  150. }
  151. // UpsertEntry inserts or updates a derived gauge entry for the given set of label values.
  152. // The object for which this gauge entry is inserted or updated, must implement func() float64
  153. //
  154. // It returns an error if
  155. // 1. The number of label values supplied are not the same as the number
  156. // of keys supplied when this gauge was created.
  157. // 2. fn func() float64 is nil.
  158. func (g *Float64DerivedGauge) UpsertEntry(fn func() float64, labelVals ...metricdata.LabelValue) error {
  159. if fn == nil {
  160. return errInvalidParam
  161. }
  162. return g.bm.upsertEntry(labelVals, func() baseEntry {
  163. return &float64DerivedGaugeEntry{fn}
  164. })
  165. }