Class: OpenTelemetry::SDK::Metrics::MeterProvider

Inherits:
Metrics::MeterProvider
  • Object
show all
Defined in:
lib/opentelemetry/sdk/metrics/meter_provider.rb

Overview

MeterProvider is the SDK implementation of Metrics::MeterProvider. rubocop:disable-next Metrics/ClassLength

Constant Summary collapse

EMPTY_ATTRIBUTES =
{}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(resource: OpenTelemetry::SDK::Resources::Resource.create) ⇒ MeterProvider

Returns a new instance of MeterProvider.



27
28
29
30
31
32
33
34
35
# File 'lib/opentelemetry/sdk/metrics/meter_provider.rb', line 27

def initialize(resource: OpenTelemetry::SDK::Resources::Resource.create)
  @mutex = Mutex.new
  @meter_registry = {}
  @stopped = false
  @metric_readers = []
  @resource = resource
  @registered_views = []
  exemplar_filter_setup
end

Instance Attribute Details

#exemplar_filter ⇒ Object (readonly)

Returns the value of attribute exemplar_filter.



25
26
27
# File 'lib/opentelemetry/sdk/metrics/meter_provider.rb', line 25

def exemplar_filter
  @exemplar_filter
end

#metric_readers ⇒ Object (readonly)

Returns the value of attribute metric_readers.



25
26
27
# File 'lib/opentelemetry/sdk/metrics/meter_provider.rb', line 25

def metric_readers
  @metric_readers
end

#registered_views ⇒ Object (readonly)

Returns the value of attribute registered_views.



25
26
27
# File 'lib/opentelemetry/sdk/metrics/meter_provider.rb', line 25

def registered_views
  @registered_views
end

#resource ⇒ Object (readonly)

Returns the value of attribute resource.



25
26
27
# File 'lib/opentelemetry/sdk/metrics/meter_provider.rb', line 25

def resource
  @resource
end

Instance Method Details

#add_metric_reader(metric_reader) ⇒ Object

Adds a new MetricReader to this OpenTelemetry::SDK::Metrics::MeterProvider.

Parameters:

  • metric_reader —

    the new MetricReader to be added.



121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/opentelemetry/sdk/metrics/meter_provider.rb', line 121

def add_metric_reader(metric_reader)
  @mutex.synchronize do
    if @stopped
      OpenTelemetry.logger.warn('calling MetricProvider#add_metric_reader after shutdown.')
    else
      register_metric_reader(metric_reader)
      @metric_readers.push(metric_reader)
      @meter_registry.each_value { |meter| meter.add_metric_reader(metric_reader) }
    end

    nil
  end
end

#add_view(name) ⇒ nil

A View provides SDK users with the flexibility to customize the metrics that are output by the SDK.

Example:

OpenTelemetry.meter_provider.add_view('test', :aggregation => Aggregation::Drop.new,
                                    :type => :counter, :unit => 'smidgen',
                                    :meter_name => 'test', :meter_version => '1.0')

Parameters:

  • name (String) —

    Name of the view.

  • options (optional Hash) —

    For more precise matching, View and MetricsStream options may include:

    aggregation: An instance of an aggregation class, e.g. {ExplicitBucketHistogram}, {Sum}, {LastValue}
    type: A Symbol representing the instrument kind, e.g. :observable_gauge, :counter
    unit: A String matching an instrumentation unit, e.g. 'smidgen'
    meter_name: A String matching a meter name, e.g. meter_provider.meter('sample_meter_name', version: '1.2.0'), would be 'sample_meter_name'
    meter_version: A String matching a meter version, e.g. meter_provider.meter('sample_meter_name', version: '1.2.0'), would be '1.2.0'

Returns:

  • (nil) —

    returns nil



205
206
207
208
209
# File 'lib/opentelemetry/sdk/metrics/meter_provider.rb', line 205

def add_view(name, **)
  # TODO: add schema_url as part of options
  @registered_views << View::RegisteredView.new(name, **)
  nil
end

#disable_exemplar_filter ⇒ Object

turn off exemplar_filter by setting the exemplar_fitler to AlwaysOffExemplarFilter



181
182
183
# File 'lib/opentelemetry/sdk/metrics/meter_provider.rb', line 181

def disable_exemplar_filter
  @exemplar_filter = Exemplar::AlwaysOffExemplarFilter
end

#enable_exemplar_filter(exemplar_filter: Exemplar::TraceBasedExemplarFilter) ⇒ Object

Adds a new exemplar_filter to replace exist exemplar_filter Default to TraceBasedExemplarFilter

Parameters:

  • exemplar_filter (defaults to: Exemplar::TraceBasedExemplarFilter) —

    the new ExemplarFilter to be added.



176
177
178
# File 'lib/opentelemetry/sdk/metrics/meter_provider.rb', line 176

def enable_exemplar_filter(exemplar_filter: Exemplar::TraceBasedExemplarFilter)
  @exemplar_filter = exemplar_filter
end

#exemplar_filter_setup ⇒ Object

Selects the exemplar filter class based on the OTEL_METRICS_EXEMPLAR_FILTER env var.



158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/opentelemetry/sdk/metrics/meter_provider.rb', line 158

def exemplar_filter_setup
  case ENV.fetch('OTEL_METRICS_EXEMPLAR_FILTER', nil)
  when 'always_on'
    @exemplar_filter = Exemplar::AlwaysOnExemplarFilter
  when nil, '', 'trace_based'
    @exemplar_filter = Exemplar::TraceBasedExemplarFilter
  when 'always_off'
    @exemplar_filter = Exemplar::AlwaysOffExemplarFilter
  else
    OpenTelemetry.logger.warn("OTEL_METRICS_EXEMPLAR_FILTER #{ENV.fetch('OTEL_METRICS_EXEMPLAR_FILTER', nil)} is not part of the provided exemplar filters. Using trace_based.")
    @exemplar_filter = Exemplar::TraceBasedExemplarFilter
  end
end

#force_flush(timeout: nil) ⇒ Integer

This method provides a way for provider to notify the registered MetricReader instances, so they can do as much as they could to consume or send the metrics. Note: unlike Push Metric Exporter which can send data on its own schedule, Pull Metric Exporter can only send the data when it is being asked by the scraper, so ForceFlush would not make much sense.

Parameters:

  • timeout (optional Numeric) (defaults to: nil) —

    An optional timeout in seconds.

Returns:

  • (Integer) —

    Export::SUCCESS if no error occurred, Export::FAILURE if a non-specific failure occurred, Export::TIMEOUT if a timeout occurred.



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/opentelemetry/sdk/metrics/meter_provider.rb', line 98

def force_flush(timeout: nil)
  @mutex.synchronize do
    if @stopped
      Export::SUCCESS
    else
      start_time = OpenTelemetry::Common::Utilities.timeout_timestamp
      results = @metric_readers.map do |metric_reader|
        remaining_timeout = OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time)
        if remaining_timeout&.zero?
          Export::TIMEOUT
        else
          metric_reader.force_flush(timeout: remaining_timeout)
        end
      end

      results.max || Export::SUCCESS
    end
  end
end

#meter(name, version: nil, attributes: nil) ⇒ Meter

Parameters:

  • name (String) —

    Instrumentation scope name

  • version (optional String) (defaults to: nil) —

    Instrumentation scope version

  • attributes (optional Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}) (defaults to: nil) —

    Instrumentation scope attributes

Returns:



45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/opentelemetry/sdk/metrics/meter_provider.rb', line 45

def meter(name, version: nil, attributes: nil)
  version ||= ''
  attributes = attributes&.dup&.freeze || EMPTY_ATTRIBUTES

  if @stopped
    OpenTelemetry.logger.warn 'calling MeterProvider#meter after shutdown, a noop meter will be returned.'
    OpenTelemetry::Metrics::Meter.new
  else
    OpenTelemetry.logger.warn "Invalid meter name provided: #{name.nil? ? 'nil' : 'empty'} value" if name.to_s.empty?
    @mutex.synchronize { @meter_registry[Key.new(name, version, attributes)] ||= Meter.new(name, version, self, attributes: attributes) }
  end
end

#register_synchronous_instrument(instrument) ⇒ Object Also known as: register_asynchronous_instrument

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



148
149
150
151
152
153
154
# File 'lib/opentelemetry/sdk/metrics/meter_provider.rb', line 148

def register_synchronous_instrument(instrument)
  @mutex.synchronize do
    @metric_readers.each do |mr|
      instrument.register_with_new_metric_store(mr.metric_store)
    end
  end
end

#shutdown(timeout: nil) ⇒ Integer

Attempts to stop all the activity for this OpenTelemetry::SDK::Metrics::MeterProvider.

Calls MetricReader#shutdown for all registered MetricReaders.

After this is called all the newly created OpenTelemetry::SDK::Metrics::Meters will be no-op.

Parameters:

  • timeout (optional Numeric) (defaults to: nil) —

    An optional timeout in seconds.

Returns:

  • (Integer) —

    Export::SUCCESS if no error occurred, Export::FAILURE if a non-specific failure occurred, Export::TIMEOUT if a timeout occurred.



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/opentelemetry/sdk/metrics/meter_provider.rb', line 67

def shutdown(timeout: nil)
  @mutex.synchronize do
    if @stopped
      OpenTelemetry.logger.warn('calling MetricProvider#shutdown multiple times.')
      Export::FAILURE
    else
      start_time = OpenTelemetry::Common::Utilities.timeout_timestamp
      results = @metric_readers.map do |metric_reader|
        remaining_timeout = OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time)
        if remaining_timeout&.zero?
          Export::TIMEOUT
        else
          metric_reader.shutdown(timeout: remaining_timeout)
        end
      end

      @stopped = true
      results.max || Export::SUCCESS
    end
  end
end