opencensus 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/README.md +2 -1
  4. data/lib/opencensus/stats.rb +143 -1
  5. data/lib/opencensus/stats/aggregation.rb +27 -0
  6. data/lib/opencensus/stats/aggregation/count.rb +18 -0
  7. data/lib/opencensus/stats/aggregation/distribution.rb +41 -0
  8. data/lib/opencensus/stats/aggregation/last_value.rb +18 -0
  9. data/lib/opencensus/stats/aggregation/sum.rb +18 -0
  10. data/lib/opencensus/stats/aggregation_data.rb +24 -0
  11. data/lib/opencensus/stats/aggregation_data/count.rb +37 -0
  12. data/lib/opencensus/stats/aggregation_data/distribution.rb +109 -0
  13. data/lib/opencensus/stats/aggregation_data/last_value.rb +32 -0
  14. data/lib/opencensus/stats/aggregation_data/sum.rb +37 -0
  15. data/lib/opencensus/stats/config.rb +79 -0
  16. data/lib/opencensus/stats/exemplar.rb +40 -0
  17. data/lib/opencensus/stats/exporters.rb +31 -0
  18. data/lib/opencensus/stats/exporters/logger.rb +77 -0
  19. data/lib/opencensus/stats/exporters/multi.rb +57 -0
  20. data/lib/opencensus/stats/measure.rb +99 -0
  21. data/lib/opencensus/stats/measure_registry.rb +72 -0
  22. data/lib/opencensus/stats/measurement.rb +35 -0
  23. data/lib/opencensus/stats/recorder.rb +100 -0
  24. data/lib/opencensus/stats/view.rb +57 -0
  25. data/lib/opencensus/stats/view_data.rb +68 -0
  26. data/lib/opencensus/tags.rb +39 -2
  27. data/lib/opencensus/tags/config.rb +74 -0
  28. data/lib/opencensus/tags/formatters.rb +15 -0
  29. data/lib/opencensus/tags/formatters/binary.rb +141 -0
  30. data/lib/opencensus/tags/tag_map.rb +137 -0
  31. data/lib/opencensus/trace/annotation.rb +1 -1
  32. data/lib/opencensus/trace/link.rb +1 -1
  33. data/lib/opencensus/trace/span.rb +1 -1
  34. data/lib/opencensus/trace/span_builder.rb +5 -4
  35. data/lib/opencensus/version.rb +1 -1
  36. metadata +32 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 536fa079d66a3bb4bef7a0e70439d5e9cc016f25e86e775a74d7426c4ef3a7e7
4
- data.tar.gz: '00688752f3c40bd18f08d4b0f311b8bd16435798647b1c09b70ad3c9240fb233'
3
+ metadata.gz: 91a03df4a06baad585ee01c05d653eb296bb5903e848d989fa125a32061d891c
4
+ data.tar.gz: 1b298783443b3eb906f902c3f1e8662fa2833b6845d40674c0efa251d64ae02d
5
5
  SHA512:
6
- metadata.gz: 50ef3104c577f850c1b4dc8b7bbe9da6030eab510f413c9cec5934da88f0b80232a97b77b7a50f5997925b53601f8796089ab7587c011bb28f2cf593171f37ea
7
- data.tar.gz: 8f4735b8955070ea7cbec12fd9260fe0a6f0647c0702837e7e74691e05b8f8bebaf2e7be92b3065b89e865cc2d2b4f100cf8ff2b6a2a1e57dceafbd9e9746da4
6
+ metadata.gz: 6bc52a99df66952372a72f157e1aace46eeaa167f31f3156639b1ad41637180e2b649352020b32a66cfcaa660c6dae59148e68bc6112491af4de89246333ad08
7
+ data.tar.gz: 21e637f7efa756f846a4ca847b673d947804aa6446821782ad60eed3bf75862170470b1e6e51f7e7475916728838b1bb2de933c9f1a894e963a56b74488773ce
@@ -1,5 +1,14 @@
1
1
  # Release History
2
2
 
3
+ ### 0.5.0 / 2019-10-14
4
+
5
+ This update brings experimental support for the OpenCensus Stats API. Note that
6
+ Stats support is currently partial and not well-tested.
7
+
8
+ Other changes:
9
+
10
+ * Attributes in the Trace API can now be floats.
11
+
3
12
  ### 0.4.0 / 2018-10-22
4
13
 
5
14
  This is an important update that includes a number of fixes and brings the
data/README.md CHANGED
@@ -8,7 +8,8 @@ the core OpenCensus APIs and basic integrations with Rails, Faraday, and GRPC.
8
8
  Additional integrations, including exporters to popular analytics services,
9
9
  will be available in separate gems.
10
10
 
11
- The library is in alpha stage, and the API is subject to change.
11
+ The library is in alpha stage, and the API is subject to change. In particular,
12
+ support for the Stats API is currently incomplete and experimental.
12
13
 
13
14
  ## Quick Start
14
15
 
@@ -13,6 +13,13 @@
13
13
  # limitations under the License.
14
14
 
15
15
 
16
+ require "opencensus/stats/config"
17
+ require "opencensus/stats/recorder"
18
+ require "opencensus/stats/view"
19
+ require "opencensus/stats/aggregation"
20
+ require "opencensus/stats/measure_registry"
21
+ require "opencensus/stats/exporters"
22
+
16
23
  module OpenCensus
17
24
  ##
18
25
  # The Stats module contains support for OpenCensus stats collection.
@@ -20,8 +27,143 @@ module OpenCensus
20
27
  # OpenCensus allows users to create typed measures, record measurements,
21
28
  # aggregate the collected data, and export the aggregated data.
22
29
  #
23
- # TODO: implement stats
24
30
  #
25
31
  module Stats
32
+ ##
33
+ # Internal key for storing the current stats recorder in the thread local
34
+ # context.
35
+ #
36
+ # @private
37
+ RECORDER_CONTEXT_KEY = :__recorder_context__
38
+
39
+ class << self
40
+ ##
41
+ # Sets the current thread-local Recorder, which governs the behavior
42
+ # of the recorder creation methods of OpenCensus::Stats::Recorder.
43
+ #
44
+ # @param [Recorder] context
45
+ def recorder_context= context
46
+ OpenCensus::Context.set RECORDER_CONTEXT_KEY, context
47
+ end
48
+
49
+ ##
50
+ # Unsets the current thread-local SpanContext, disabling stats recorder
51
+ # creation methods of OpenCensus::Stats::Recorder
52
+ def unset_recorder_context
53
+ OpenCensus::Context.unset RECORDER_CONTEXT_KEY
54
+ end
55
+
56
+ # Get the current thread-local stats recorder context/
57
+ # Returns `nil` if there is no current SpanContext.
58
+ #
59
+ # @return [Recorder, nil]
60
+ def recorder_context
61
+ OpenCensus::Context.get RECORDER_CONTEXT_KEY
62
+ end
63
+
64
+ # Get recorder from the stats context. If stats context nil then create
65
+ # new recorder and set into stats context.
66
+ # @return [Recorder]
67
+ def ensure_recorder
68
+ self.recorder_context ||= Recorder.new
69
+ end
70
+
71
+ # Create and register int64 type measure into measure registry.
72
+ #
73
+ # @param [String] name Name of the measure.
74
+ # @param [String] unit Unit of the measure. i.e "kb", "s", "ms"
75
+ # @param [String] description Detail description
76
+ # @return [Measure]
77
+ def create_measure_int name:, unit:, description: nil
78
+ MeasureRegistry.register(
79
+ name: name,
80
+ unit: unit,
81
+ type: Measure::INT64_TYPE,
82
+ description: description
83
+ )
84
+ end
85
+
86
+ # Create and register double type measure into measure registry.
87
+ #
88
+ # @param [String] name Name of the measure.
89
+ # @param [String] unit Unit of the measure. i.e "kb", "s", "ms"
90
+ # @param [String] description Detail description
91
+ # @return [Measure]
92
+ def create_measure_double name:, unit:, description: nil
93
+ MeasureRegistry.register(
94
+ name: name,
95
+ unit: unit,
96
+ type: Measure::DOUBLE_TYPE,
97
+ description: description
98
+ )
99
+ end
100
+
101
+ # Get list of registered measures
102
+ # @return [Array<Measure>]
103
+ def registered_measures
104
+ MeasureRegistry.measures
105
+ end
106
+
107
+ # Create measurement value for registered measure.
108
+ #
109
+ # @param [String] name Name of the registered measure
110
+ # @param [Integer, Float] value Value of the measurement
111
+ # @param [Hash<String,String>] tags Tags to which the value is recorded
112
+ # @raise [ArgumentError] if givem measure is not register
113
+ def create_measurement name:, value:, tags:
114
+ measure = MeasureRegistry.get name
115
+ return measure.create_measurement(value: value, tags: tags) if measure
116
+ raise ArgumentError, "#{name} measure is not registered"
117
+ end
118
+
119
+ # Create and register a view to current stats recorder context.
120
+ #
121
+ # @param [String] name
122
+ # @param [Measure] measure
123
+ # @param [Aggregation] aggregation
124
+ # @param [Array<String>] columns
125
+ # @param [String] description
126
+ def create_and_register_view \
127
+ name:,
128
+ measure:,
129
+ aggregation:,
130
+ columns: nil,
131
+ description: nil
132
+ view = View.new(
133
+ name: name,
134
+ measure: measure,
135
+ aggregation: aggregation,
136
+ description: description,
137
+ columns: columns
138
+ )
139
+ ensure_recorder.register_view view
140
+ end
141
+
142
+ # Create aggregation defination instance with type sum.
143
+ # @return [Aggregation]
144
+ def create_sum_aggregation
145
+ Aggregation::Sum.new
146
+ end
147
+
148
+ # Create aggregation defination instance with type count.
149
+ # @return [Aggregation]
150
+ def create_count_aggregation
151
+ Aggregation::Count.new
152
+ end
153
+
154
+ # Create aggregation defination instance with type distribution.
155
+ # @param [Array<Integer>,Array<Float>] buckets Value boundries for
156
+ # distribution.
157
+ # @return [Aggregation]
158
+ def create_distribution_aggregation buckets
159
+ Aggregation::Distribution.new buckets
160
+ end
161
+
162
+ # Create aggregation defination instance with type last value.
163
+ # @return [Aggregation]
164
+ def create_last_value_aggregation
165
+ Aggregation::LastValue.new
166
+ end
167
+ end
26
168
  end
27
169
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ require "opencensus/stats/aggregation/sum"
5
+ require "opencensus/stats/aggregation/count"
6
+ require "opencensus/stats/aggregation/last_value"
7
+ require "opencensus/stats/aggregation/distribution"
8
+ require "opencensus/stats/aggregation_data"
9
+ require "opencensus/stats/exemplar"
10
+
11
+ module OpenCensus
12
+ module Stats
13
+ # # Aggregation
14
+ #
15
+ # Aggregation types to describes how the data collected based on aggregation
16
+ # type.
17
+ # Aggregation types are.
18
+ # - Sum
19
+ # - Count
20
+ # - Last Value
21
+ # - Distribution - calcualate min, max, mean, sum, count,
22
+ # sum of squared deviation
23
+ #
24
+ module Aggregation
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ module OpenCensus
5
+ module Stats
6
+ module Aggregation
7
+ # Count aggregation type
8
+ class Count
9
+ # Create new aggregation data container to store count value.
10
+ # values.
11
+ # @return [AggregationData::Count]
12
+ def create_aggregation_data
13
+ AggregationData::Count.new
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ module OpenCensus
5
+ module Stats
6
+ module Aggregation
7
+ # Distribution aggregation type
8
+ class Distribution
9
+ # Invalid bucket types.
10
+ class InvalidBucketsError < StandardError; end
11
+
12
+ # @return [Array<Integer>,Array<Float>] Bucket boundries.
13
+ attr_reader :buckets
14
+
15
+ # @private
16
+ # @param [Array<Integer>,Array<Float>,] buckets Buckets boundries
17
+ # for distribution
18
+ # aggregation.
19
+ # @raise [InvalidBucketsError] If any bucket value is nil.
20
+ def initialize buckets
21
+ if buckets.nil? || buckets.empty?
22
+ raise InvalidBucketsError, "buckets should not be nil or empty"
23
+ end
24
+
25
+ if buckets.any?(&:nil?)
26
+ raise InvalidBucketsError, "buckets value should not be nil"
27
+ end
28
+
29
+ @buckets = buckets.reject { |v| v < 0 }
30
+ end
31
+
32
+ # Create new aggregation data container to store distribution values.
33
+ # values.
34
+ # @return [AggregationData::Distribution]
35
+ def create_aggregation_data
36
+ AggregationData::Distribution.new @buckets
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ module OpenCensus
5
+ module Stats
6
+ module Aggregation
7
+ # Last value aggregation type
8
+ class LastValue
9
+ # Create new aggregation data container to store last value.
10
+ # values.
11
+ # @return [AggregationData::LastValue]
12
+ def create_aggregation_data
13
+ AggregationData::LastValue.new
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ module OpenCensus
5
+ module Stats
6
+ module Aggregation
7
+ # Sum aggregation type
8
+ class Sum
9
+ # Create new aggregation data container to store sum value
10
+ # values.
11
+ # @return [AggregationData::Sum]
12
+ def create_aggregation_data
13
+ AggregationData::Sum.new
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ require "opencensus/stats/aggregation_data/sum"
5
+ require "opencensus/stats/aggregation_data/count"
6
+ require "opencensus/stats/aggregation_data/last_value"
7
+ require "opencensus/stats/aggregation_data/distribution"
8
+
9
+ module OpenCensus
10
+ module Stats
11
+ # # AggregationData
12
+ #
13
+ # AggregationData to store collected stats data.
14
+ # Aggregation data container type:
15
+ # - Sum
16
+ # - Count
17
+ # - Last Value
18
+ # - Distribution - calcualate sum, count, min, max, mean,
19
+ # sum of squared deviation
20
+ #
21
+ module AggregationData
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ module OpenCensus
5
+ module Stats
6
+ module AggregationData
7
+ # # Count
8
+ #
9
+ # Counts number of measurements recorded.
10
+ class Count
11
+ # @return [Integer,Float] Current count value.
12
+ attr_reader :value
13
+
14
+ # @return [Time] The latest timestamp a new data point was recorded
15
+ attr_reader :time
16
+
17
+ # @private
18
+ def initialize
19
+ @value = 0
20
+ end
21
+
22
+ # rubocop:disable Lint/UnusedMethodArgument
23
+
24
+ # Increment counter.
25
+ # @param [Value] value
26
+ # @param [Time] time Time of data point was recorded
27
+ # @param [Hash<String,String>] attachments Attachments are not in use.
28
+ def add value, time, attachments: nil
29
+ @time = time
30
+ @value += 1
31
+ end
32
+
33
+ # rubocop:enable Lint/UnusedMethodArgument
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ module OpenCensus
5
+ module Stats
6
+ module AggregationData
7
+ # # Distribution
8
+ #
9
+ # This AggregationData contains a histogram of the collected values
10
+ class Distribution
11
+ # @return [Array<Integer>,Array<Float>] Buckets boundries
12
+ attr_reader :buckets
13
+
14
+ # @return [Integer] Count of recorded values
15
+ attr_reader :count
16
+
17
+ # @return [Integer,Float] Sum of recorded values
18
+ attr_reader :sum
19
+
20
+ # @return [Integer,Float] Maximum recorded value
21
+ attr_reader :max
22
+
23
+ # @return [Integer,Float] Minimum recorded value
24
+ attr_reader :min
25
+
26
+ # @return [Integer,Float] Mean of recorded values
27
+ attr_reader :mean
28
+
29
+ # @return [Integer,Float] Sum of squared deviation of recorded values
30
+ attr_reader :sum_of_squared_deviation
31
+
32
+ # @return [Array<Integer>] Count of number of recorded values in buckets
33
+ attr_reader :bucket_counts
34
+
35
+ # @return [Time] Time of first recorded value
36
+ attr_reader :start_time
37
+
38
+ # @return [Time] The latest time a new value was recorded
39
+ attr_reader :time
40
+
41
+ # @return [Array<Exemplar>] Exemplars are points associated with each
42
+ # bucket in the distribution giving an example of what was aggregated
43
+ # into the bucket.
44
+ attr_reader :exemplars
45
+
46
+ # @private
47
+ # @param [Array<Integer>,Array<Float>] buckets Buckets boundries
48
+ # for distribution
49
+ def initialize buckets
50
+ @buckets = buckets
51
+ @count = 0
52
+ @sum = 0
53
+ @max = -Float::INFINITY
54
+ @min = Float::INFINITY
55
+ @mean = 0
56
+ @sum_of_squared_deviation = 0
57
+ @bucket_counts = Array.new(buckets.length + 1, 0)
58
+ @exemplars = []
59
+ @start_time = Time.now.utc
60
+ end
61
+
62
+ # @private
63
+ # Add value to distribution
64
+ # @param [Integer,Float] value
65
+ # @param [Time] time Time of data point was recorded
66
+ # @param [Hash<String,String>,nil] attachments Attachments are key-value
67
+ # pairs that describe the context in which the exemplar was recored.
68
+ def add value, time, attachments: nil
69
+ @time = time
70
+ @count += 1
71
+ @sum += value
72
+ @max = value if value > @max
73
+ @min = value if value < @min
74
+
75
+ delta_from_mean = (value - @mean).to_f
76
+ @mean += delta_from_mean / @count
77
+ @sum_of_squared_deviation += delta_from_mean * (value - @mean)
78
+
79
+ bucket_index = @buckets.find_index { |b| b > value } ||
80
+ @buckets.length
81
+ @bucket_counts[bucket_index] += 1
82
+
83
+ if attachments
84
+ @exemplars[bucket_index] = Exemplar.new(
85
+ value: value,
86
+ time: time,
87
+ attachments: attachments
88
+ )
89
+ end
90
+ end
91
+
92
+ # Get distribution result values.
93
+ # @return [Hash]
94
+ def value
95
+ {
96
+ start_time: @start_time,
97
+ count: @count,
98
+ sum: @sum,
99
+ max: @max,
100
+ min: @min,
101
+ sum_of_squared_deviation: @sum_of_squared_deviation,
102
+ buckets: @buckets,
103
+ bucket_counts: @bucket_counts
104
+ }
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end