...

Source file src/go.opencensus.io/metric/cumulative.go

Documentation: go.opencensus.io/metric

     1  // Copyright 2019, 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  
    15  package metric
    16  
    17  import (
    18  	"math"
    19  	"sync/atomic"
    20  	"time"
    21  
    22  	"go.opencensus.io/metric/metricdata"
    23  )
    24  
    25  // Float64Cumulative represents a float64 value that can only go up.
    26  //
    27  // Float64Cumulative maintains a float64 value for each combination of label values
    28  // passed to the Set or Inc methods.
    29  type Float64Cumulative struct {
    30  	bm baseMetric
    31  }
    32  
    33  // Float64CumulativeEntry represents a single value of the cumulative corresponding to a set
    34  // of label values.
    35  type Float64CumulativeEntry struct {
    36  	val uint64 // needs to be uint64 for atomic access, interpret with math.Float64frombits
    37  }
    38  
    39  func (e *Float64CumulativeEntry) read(t time.Time) metricdata.Point {
    40  	v := math.Float64frombits(atomic.LoadUint64(&e.val))
    41  	if v < 0 {
    42  		v = 0
    43  	}
    44  	return metricdata.NewFloat64Point(t, v)
    45  }
    46  
    47  // GetEntry returns a cumulative entry where each key for this cumulative has the value
    48  // given.
    49  //
    50  // The number of label values supplied must be exactly the same as the number
    51  // of keys supplied when this cumulative was created.
    52  func (c *Float64Cumulative) GetEntry(labelVals ...metricdata.LabelValue) (*Float64CumulativeEntry, error) {
    53  	entry, err := c.bm.entryForValues(labelVals, func() baseEntry {
    54  		return &Float64CumulativeEntry{}
    55  	})
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  	return entry.(*Float64CumulativeEntry), nil
    60  }
    61  
    62  // Inc increments the cumulative entry value by val. It returns without incrementing if the val
    63  // is negative.
    64  func (e *Float64CumulativeEntry) Inc(val float64) {
    65  	var swapped bool
    66  	if val <= 0.0 {
    67  		return
    68  	}
    69  	for !swapped {
    70  		oldVal := atomic.LoadUint64(&e.val)
    71  		newVal := math.Float64bits(math.Float64frombits(oldVal) + val)
    72  		swapped = atomic.CompareAndSwapUint64(&e.val, oldVal, newVal)
    73  	}
    74  }
    75  
    76  // Int64Cumulative represents a int64 cumulative value that can only go up.
    77  //
    78  // Int64Cumulative maintains an int64 value for each combination of label values passed to the
    79  // Set or Inc methods.
    80  type Int64Cumulative struct {
    81  	bm baseMetric
    82  }
    83  
    84  // Int64CumulativeEntry represents a single value of the cumulative corresponding to a set
    85  // of label values.
    86  type Int64CumulativeEntry struct {
    87  	val int64
    88  }
    89  
    90  func (e *Int64CumulativeEntry) read(t time.Time) metricdata.Point {
    91  	v := atomic.LoadInt64(&e.val)
    92  	if v < 0 {
    93  		v = 0.0
    94  	}
    95  	return metricdata.NewInt64Point(t, v)
    96  }
    97  
    98  // GetEntry returns a cumulative entry where each key for this cumulative has the value
    99  // given.
   100  //
   101  // The number of label values supplied must be exactly the same as the number
   102  // of keys supplied when this cumulative was created.
   103  func (c *Int64Cumulative) GetEntry(labelVals ...metricdata.LabelValue) (*Int64CumulativeEntry, error) {
   104  	entry, err := c.bm.entryForValues(labelVals, func() baseEntry {
   105  		return &Int64CumulativeEntry{}
   106  	})
   107  	if err != nil {
   108  		return nil, err
   109  	}
   110  	return entry.(*Int64CumulativeEntry), nil
   111  }
   112  
   113  // Inc increments the current cumulative entry value by val. It returns without incrementing if
   114  // the val is negative.
   115  func (e *Int64CumulativeEntry) Inc(val int64) {
   116  	if val <= 0 {
   117  		return
   118  	}
   119  	atomic.AddInt64(&e.val, val)
   120  }
   121  
   122  // Int64DerivedCumulative represents int64 cumulative value that is derived from an object.
   123  //
   124  // Int64DerivedCumulative maintains objects for each combination of label values.
   125  // These objects implement Int64DerivedCumulativeInterface to read instantaneous value
   126  // representing the object.
   127  type Int64DerivedCumulative struct {
   128  	bm baseMetric
   129  }
   130  
   131  type int64DerivedCumulativeEntry struct {
   132  	fn func() int64
   133  }
   134  
   135  func (e *int64DerivedCumulativeEntry) read(t time.Time) metricdata.Point {
   136  	// TODO: [rghetia] handle a condition where new value return by fn is lower than previous call.
   137  	// It requires that we maintain the old values.
   138  	return metricdata.NewInt64Point(t, e.fn())
   139  }
   140  
   141  // UpsertEntry inserts or updates a derived cumulative entry for the given set of label values.
   142  // The object for which this cumulative entry is inserted or updated, must implement func() int64
   143  //
   144  // It returns an error if
   145  // 1. The number of label values supplied are not the same as the number
   146  // of keys supplied when this cumulative was created.
   147  // 2. fn func() int64 is nil.
   148  func (c *Int64DerivedCumulative) UpsertEntry(fn func() int64, labelVals ...metricdata.LabelValue) error {
   149  	if fn == nil {
   150  		return errInvalidParam
   151  	}
   152  	return c.bm.upsertEntry(labelVals, func() baseEntry {
   153  		return &int64DerivedCumulativeEntry{fn}
   154  	})
   155  }
   156  
   157  // Float64DerivedCumulative represents float64 cumulative value that is derived from an object.
   158  //
   159  // Float64DerivedCumulative maintains objects for each combination of label values.
   160  // These objects implement Float64DerivedCumulativeInterface to read instantaneous value
   161  // representing the object.
   162  type Float64DerivedCumulative struct {
   163  	bm baseMetric
   164  }
   165  
   166  type float64DerivedCumulativeEntry struct {
   167  	fn func() float64
   168  }
   169  
   170  func (e *float64DerivedCumulativeEntry) read(t time.Time) metricdata.Point {
   171  	return metricdata.NewFloat64Point(t, e.fn())
   172  }
   173  
   174  // UpsertEntry inserts or updates a derived cumulative entry for the given set of label values.
   175  // The object for which this cumulative entry is inserted or updated, must implement func() float64
   176  //
   177  // It returns an error if
   178  // 1. The number of label values supplied are not the same as the number
   179  // of keys supplied when this cumulative was created.
   180  // 2. fn func() float64 is nil.
   181  func (c *Float64DerivedCumulative) UpsertEntry(fn func() float64, labelVals ...metricdata.LabelValue) error {
   182  	if fn == nil {
   183  		return errInvalidParam
   184  	}
   185  	return c.bm.upsertEntry(labelVals, func() baseEntry {
   186  		return &float64DerivedCumulativeEntry{fn}
   187  	})
   188  }
   189  

View as plain text