opencensus 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +2 -1
- data/lib/opencensus/stats.rb +143 -1
- data/lib/opencensus/stats/aggregation.rb +27 -0
- data/lib/opencensus/stats/aggregation/count.rb +18 -0
- data/lib/opencensus/stats/aggregation/distribution.rb +41 -0
- data/lib/opencensus/stats/aggregation/last_value.rb +18 -0
- data/lib/opencensus/stats/aggregation/sum.rb +18 -0
- data/lib/opencensus/stats/aggregation_data.rb +24 -0
- data/lib/opencensus/stats/aggregation_data/count.rb +37 -0
- data/lib/opencensus/stats/aggregation_data/distribution.rb +109 -0
- data/lib/opencensus/stats/aggregation_data/last_value.rb +32 -0
- data/lib/opencensus/stats/aggregation_data/sum.rb +37 -0
- data/lib/opencensus/stats/config.rb +79 -0
- data/lib/opencensus/stats/exemplar.rb +40 -0
- data/lib/opencensus/stats/exporters.rb +31 -0
- data/lib/opencensus/stats/exporters/logger.rb +77 -0
- data/lib/opencensus/stats/exporters/multi.rb +57 -0
- data/lib/opencensus/stats/measure.rb +99 -0
- data/lib/opencensus/stats/measure_registry.rb +72 -0
- data/lib/opencensus/stats/measurement.rb +35 -0
- data/lib/opencensus/stats/recorder.rb +100 -0
- data/lib/opencensus/stats/view.rb +57 -0
- data/lib/opencensus/stats/view_data.rb +68 -0
- data/lib/opencensus/tags.rb +39 -2
- data/lib/opencensus/tags/config.rb +74 -0
- data/lib/opencensus/tags/formatters.rb +15 -0
- data/lib/opencensus/tags/formatters/binary.rb +141 -0
- data/lib/opencensus/tags/tag_map.rb +137 -0
- data/lib/opencensus/trace/annotation.rb +1 -1
- data/lib/opencensus/trace/link.rb +1 -1
- data/lib/opencensus/trace/span.rb +1 -1
- data/lib/opencensus/trace/span_builder.rb +5 -4
- data/lib/opencensus/version.rb +1 -1
- metadata +32 -8
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
|
4
|
+
require "singleton"
|
5
|
+
require "opencensus/stats/measure"
|
6
|
+
|
7
|
+
module OpenCensus
|
8
|
+
module Stats
|
9
|
+
# #MeasureRegistry
|
10
|
+
#
|
11
|
+
# Measure registry is a collection of uniq measures.
|
12
|
+
#
|
13
|
+
class MeasureRegistry
|
14
|
+
include Singleton
|
15
|
+
|
16
|
+
# @return [Hash<String, Measure>]
|
17
|
+
attr_reader :measures
|
18
|
+
|
19
|
+
# @private
|
20
|
+
def initialize
|
21
|
+
@measures = {}
|
22
|
+
end
|
23
|
+
|
24
|
+
class << self
|
25
|
+
# Register measure.
|
26
|
+
#
|
27
|
+
# @param [String] name Name of measure
|
28
|
+
# @param [String] unit Unit name of measure
|
29
|
+
# @param [String] type Date type unit of measure. integer or float.
|
30
|
+
# @param [String] description Description of measure
|
31
|
+
# @return [Measure, nil]
|
32
|
+
#
|
33
|
+
def register name:, unit:, type:, description: nil
|
34
|
+
return if instance.measures.key? name
|
35
|
+
|
36
|
+
measure = Measure.new(
|
37
|
+
name: name,
|
38
|
+
unit: unit,
|
39
|
+
type: type,
|
40
|
+
description: description
|
41
|
+
)
|
42
|
+
|
43
|
+
instance.measures[name] = measure
|
44
|
+
end
|
45
|
+
|
46
|
+
# Un register measure
|
47
|
+
#
|
48
|
+
# @param [String] name Name of the registered view
|
49
|
+
def unregister name
|
50
|
+
instance.measures.delete name
|
51
|
+
end
|
52
|
+
|
53
|
+
# Clear measures registry
|
54
|
+
def clear
|
55
|
+
instance.measures.clear
|
56
|
+
end
|
57
|
+
|
58
|
+
# Get registered measure
|
59
|
+
# @return [Measure]
|
60
|
+
def get name
|
61
|
+
instance.measures[name]
|
62
|
+
end
|
63
|
+
|
64
|
+
# List of registered measures
|
65
|
+
# @return [Array<Measure>]
|
66
|
+
def measures
|
67
|
+
instance.measures.values
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
|
4
|
+
module OpenCensus
|
5
|
+
module Stats
|
6
|
+
# Measurement
|
7
|
+
#
|
8
|
+
# Describes a data point to be collected for a Measure.
|
9
|
+
class Measurement
|
10
|
+
# @return [Measure] A measure to which the value is applied.
|
11
|
+
attr_reader :measure
|
12
|
+
|
13
|
+
# @return [Integer,Float] The recorded value
|
14
|
+
attr_reader :value
|
15
|
+
|
16
|
+
# @return [TagMap] The tags to which the value is applied
|
17
|
+
attr_reader :tags
|
18
|
+
|
19
|
+
# @return [Time] The time when measurement was created.
|
20
|
+
attr_reader :time
|
21
|
+
|
22
|
+
# Create a instance of measurement
|
23
|
+
#
|
24
|
+
# @param [Measure] measure A measure to which the value is applied.
|
25
|
+
# @param [Integer,Float] value Measurement value.
|
26
|
+
# @param [Hash<String,String>] tags The tags to which the value is applied
|
27
|
+
def initialize measure:, value:, tags:
|
28
|
+
@measure = measure
|
29
|
+
@value = value
|
30
|
+
@tags = Tags::TagMap.new tags
|
31
|
+
@time = Time.now.utc
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
|
4
|
+
require "opencensus/stats/view"
|
5
|
+
require "opencensus/stats/view_data"
|
6
|
+
|
7
|
+
module OpenCensus
|
8
|
+
module Stats
|
9
|
+
# Stats recorder.
|
10
|
+
#
|
11
|
+
# Recorder record measurement against measure for registered views.
|
12
|
+
class Recorder
|
13
|
+
# @private
|
14
|
+
# @return [Hash<String,View>] Hash of view name and View object.
|
15
|
+
attr_reader :views
|
16
|
+
|
17
|
+
# @private
|
18
|
+
# @return [Hash<String,Measure>] Hash of measure name and Measure object.
|
19
|
+
attr_reader :measures
|
20
|
+
|
21
|
+
# @private
|
22
|
+
# @return [Hash<String,Array<<ViewData>>]
|
23
|
+
# Hash of view name and View data objects array.
|
24
|
+
attr_reader :measure_views_data
|
25
|
+
|
26
|
+
# @private
|
27
|
+
# Create instance of the recorder.
|
28
|
+
def initialize
|
29
|
+
@views = {}
|
30
|
+
@measures = {}
|
31
|
+
@measure_views_data = {}
|
32
|
+
@time = Time.now.utc
|
33
|
+
end
|
34
|
+
|
35
|
+
# Register view
|
36
|
+
#
|
37
|
+
# @param [View] view
|
38
|
+
# @return [View]
|
39
|
+
def register_view view
|
40
|
+
return if @views.key? view.name
|
41
|
+
|
42
|
+
@views[view.name] = view
|
43
|
+
@measures[view.measure.name] = view.measure
|
44
|
+
|
45
|
+
unless @measure_views_data.key? view.measure.name
|
46
|
+
@measure_views_data[view.measure.name] = []
|
47
|
+
end
|
48
|
+
|
49
|
+
@measure_views_data[view.measure.name] << ViewData.new(
|
50
|
+
view,
|
51
|
+
start_time: @time,
|
52
|
+
end_time: @time
|
53
|
+
)
|
54
|
+
view
|
55
|
+
end
|
56
|
+
|
57
|
+
# Record measurements
|
58
|
+
#
|
59
|
+
# @param [Array<Measurement>, Measurement] measurements
|
60
|
+
# @param [Hash<String,String>] attachments
|
61
|
+
def record *measurements, attachments: nil
|
62
|
+
return if measurements.any? { |m| m.value < 0 }
|
63
|
+
|
64
|
+
measurements.each do |measurement|
|
65
|
+
views_data = @measure_views_data[measurement.measure.name]
|
66
|
+
next unless views_data
|
67
|
+
|
68
|
+
views_data.each do |view_data|
|
69
|
+
view_data.record measurement, attachments: attachments
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Get recorded data for given view name
|
75
|
+
#
|
76
|
+
# @param [String] view_name View name
|
77
|
+
# @return [ViewData]
|
78
|
+
def view_data view_name
|
79
|
+
view = @views[view_name]
|
80
|
+
return unless view
|
81
|
+
|
82
|
+
views_data = @measure_views_data[view.measure.name]
|
83
|
+
views_data.find { |view_data| view_data.view.name == view.name }
|
84
|
+
end
|
85
|
+
|
86
|
+
# Get all views data list
|
87
|
+
# @return [Array<ViewData>]
|
88
|
+
def views_data
|
89
|
+
@measure_views_data.values.flatten
|
90
|
+
end
|
91
|
+
|
92
|
+
# Clear recorded stats.
|
93
|
+
def clear_stats
|
94
|
+
@measure_views_data.each_value do |views_data|
|
95
|
+
views_data.each(&:clear)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
|
4
|
+
module OpenCensus
|
5
|
+
module Stats
|
6
|
+
# View
|
7
|
+
#
|
8
|
+
# A View specifies an aggregation and a set of tag keys.
|
9
|
+
# The aggregation will be broken down by the unique set of matching tag
|
10
|
+
# values for each measure.
|
11
|
+
class View
|
12
|
+
# @return [String] Name of the view
|
13
|
+
attr_reader :name
|
14
|
+
|
15
|
+
# @return [Measure] Associated measure definition instance.
|
16
|
+
attr_reader :measure
|
17
|
+
|
18
|
+
# @return [Aggregation] Associated aggregation definition instance.
|
19
|
+
attr_reader :aggregation
|
20
|
+
|
21
|
+
# Columns (a.k.a Tag Keys) to match with the
|
22
|
+
# associated Measure. Measure will be recorded in a "greedy" way.
|
23
|
+
# That is, every view aggregates every measure.
|
24
|
+
# This is similar to doing a GROUPBY on view columns. Columns must be
|
25
|
+
# unique.
|
26
|
+
# @return [Array<String>]
|
27
|
+
attr_reader :columns
|
28
|
+
|
29
|
+
# @return [String] Detailed description
|
30
|
+
attr_reader :description
|
31
|
+
|
32
|
+
# @return [Time] View creation time.
|
33
|
+
attr_reader :time
|
34
|
+
|
35
|
+
# Create instance of the view
|
36
|
+
#
|
37
|
+
# @param [String] name
|
38
|
+
# @param [Measure] measure
|
39
|
+
# @param [Aggregation] aggregation
|
40
|
+
# @param [Array<String>] columns
|
41
|
+
# @param [String] description
|
42
|
+
def initialize \
|
43
|
+
name:,
|
44
|
+
measure:,
|
45
|
+
aggregation:,
|
46
|
+
columns:,
|
47
|
+
description: nil
|
48
|
+
@name = name
|
49
|
+
@measure = measure
|
50
|
+
@aggregation = aggregation
|
51
|
+
@columns = columns
|
52
|
+
@description = description
|
53
|
+
@time = Time.now.utc
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
|
4
|
+
module OpenCensus
|
5
|
+
module Stats
|
6
|
+
# ViewData is a container to store stats.
|
7
|
+
class ViewData
|
8
|
+
# @return [View]
|
9
|
+
attr_reader :view
|
10
|
+
|
11
|
+
# @return [Time, nil]
|
12
|
+
attr_reader :start_time
|
13
|
+
|
14
|
+
# @return [Time, nil]
|
15
|
+
attr_reader :end_time
|
16
|
+
|
17
|
+
# @return [Hash<Array<String>>,AggregationData] Recorded stats data
|
18
|
+
# against view columns.
|
19
|
+
attr_reader :data
|
20
|
+
|
21
|
+
# @private
|
22
|
+
# Create instance of view
|
23
|
+
#
|
24
|
+
# @param [View] view
|
25
|
+
# @param [Time] start_time
|
26
|
+
# @param [Time] end_time
|
27
|
+
def initialize view, start_time: nil, end_time: nil
|
28
|
+
@view = view
|
29
|
+
@start_time = start_time
|
30
|
+
@end_time = end_time
|
31
|
+
@data = {}
|
32
|
+
end
|
33
|
+
|
34
|
+
# Set start time.
|
35
|
+
def start
|
36
|
+
@start_time = Time.now.utc
|
37
|
+
end
|
38
|
+
|
39
|
+
# Set stop time.
|
40
|
+
def stop
|
41
|
+
@end_time = Time.now.utc
|
42
|
+
end
|
43
|
+
|
44
|
+
# Record a measurement.
|
45
|
+
#
|
46
|
+
# @param [Measurement] measurement
|
47
|
+
# @param [Hash<String,String>] attachments
|
48
|
+
def record measurement, attachments: nil
|
49
|
+
tag_values = @view.columns.map { |column| measurement.tags[column] }
|
50
|
+
|
51
|
+
unless @data.key? tag_values
|
52
|
+
@data[tag_values] = @view.aggregation.create_aggregation_data
|
53
|
+
end
|
54
|
+
|
55
|
+
@data[tag_values].add(
|
56
|
+
measurement.value,
|
57
|
+
measurement.time,
|
58
|
+
attachments: attachments
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Clear recorded ata
|
63
|
+
def clear
|
64
|
+
data.clear
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/opencensus/tags.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2017 OpenCensus Authors
|
2
4
|
#
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -13,14 +15,49 @@
|
|
13
15
|
# limitations under the License.
|
14
16
|
|
15
17
|
|
18
|
+
require "opencensus/tags/config"
|
19
|
+
require "opencensus/tags/tag_map"
|
20
|
+
require "opencensus/tags/formatters"
|
21
|
+
|
16
22
|
module OpenCensus
|
17
23
|
##
|
18
24
|
# The Tags module contains support for OpenCensus tags. Tags are key-value
|
19
25
|
# pairs. Tags provide additional cardinality to the OpenCensus instrumentation
|
20
26
|
# data.
|
21
27
|
#
|
22
|
-
# TODO: implement tags
|
23
|
-
#
|
24
28
|
module Tags
|
29
|
+
##
|
30
|
+
# Internal key for storing the current TagMap in the thread local
|
31
|
+
# Context
|
32
|
+
#
|
33
|
+
# @private
|
34
|
+
#
|
35
|
+
TAG_MAP_CONTEXT_KEY = :__tag_map_context__
|
36
|
+
|
37
|
+
class << self
|
38
|
+
##
|
39
|
+
# Sets the current thread-local TagMap, which used in Stats data
|
40
|
+
# recording.
|
41
|
+
#
|
42
|
+
# @param [TagMap] context
|
43
|
+
#
|
44
|
+
def tag_map_context= context
|
45
|
+
OpenCensus::Context.set TAG_MAP_CONTEXT_KEY, context
|
46
|
+
end
|
47
|
+
|
48
|
+
# Unsets the current thread-local TagMap context
|
49
|
+
#
|
50
|
+
def unset_tag_map_context
|
51
|
+
OpenCensus::Context.unset TAG_MAP_CONTEXT_KEY
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns the current thread-local TagMap object.
|
55
|
+
#
|
56
|
+
# @return [TagMap, nil]
|
57
|
+
#
|
58
|
+
def tag_map_context
|
59
|
+
OpenCensus::Context.get TAG_MAP_CONTEXT_KEY
|
60
|
+
end
|
61
|
+
end
|
25
62
|
end
|
26
63
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# Copyright 2017 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
|
+
|
16
|
+
require "opencensus/config"
|
17
|
+
require "opencensus/tags/formatters"
|
18
|
+
|
19
|
+
module OpenCensus
|
20
|
+
module Tags
|
21
|
+
# Schema of the Tags configuration. See Tags#configure for more info.
|
22
|
+
@config = Common::Config.new do |config|
|
23
|
+
default_formatter = Formatters::Binary.new
|
24
|
+
config.add_option! :binary_formatter, default_formatter do |value|
|
25
|
+
value.respond_to?(:serialize) && value.respond_to?(:deserialize)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Expose the tags config as a subconfig under the main config.
|
30
|
+
OpenCensus.configure do |config|
|
31
|
+
config.add_alias! :tags, config: @config
|
32
|
+
end
|
33
|
+
|
34
|
+
class << self
|
35
|
+
##
|
36
|
+
# Configure OpenCensus Tags. These configuration fields include
|
37
|
+
# parameters formatter.
|
38
|
+
#
|
39
|
+
# This configuration is also available as the `tags` subconfig under the
|
40
|
+
# main configuration `OpenCensus.configure`. If the OpenCensus Railtie is
|
41
|
+
# installed in a Rails application, the configuration object is also
|
42
|
+
# exposed as `config.opencensus.tags`.
|
43
|
+
#
|
44
|
+
# Generally, you should configure this once at process initialization,
|
45
|
+
# but it can be modified at any time.
|
46
|
+
#
|
47
|
+
# Supported fields are:
|
48
|
+
#
|
49
|
+
# * `binary_formatter` The tags context propagation formatter to use.
|
50
|
+
# Must be a formatter, an object with `serialize`, `deserialize`,
|
51
|
+
# methods. See {OpenCensus::Tags::Formatters::Binary}.
|
52
|
+
#
|
53
|
+
# @example
|
54
|
+
#
|
55
|
+
# OpenCensus::Tags.configure do |config|
|
56
|
+
# config.binary_formatter = OpenCensus::Tags::Formatters::Binary.new
|
57
|
+
# end
|
58
|
+
#
|
59
|
+
def configure
|
60
|
+
if block_given?
|
61
|
+
yield @config
|
62
|
+
else
|
63
|
+
@config
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# Get the current configuration
|
69
|
+
# @private
|
70
|
+
#
|
71
|
+
attr_reader :config
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|