Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Redis metrics #1377

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions helpers/metrics-test-helpers/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
gemfiles
12 changes: 12 additions & 0 deletions helpers/metrics-test-helpers/Appraisals
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

appraise 'metrics-sdk' do
gem 'opentelemetry-metrics-sdk'
end

appraise 'metrics-api' do
gem 'opentelemetry-metrics-api'
end

appraise 'base' do # rubocop: disable Lint/EmptyBlock
end
11 changes: 11 additions & 0 deletions helpers/metrics-test-helpers/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

source 'https://rubygems.org'

# Specify your gem's dependencies in opentelemetry-metrics-test-helpers.gemspec
gemspec

gem 'rake', '~> 13.0'
gem 'minitest', '~> 5.16'
gem 'opentelemetry-sdk'
gem 'pry-byebug'
76 changes: 76 additions & 0 deletions helpers/metrics-test-helpers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# OpenTelemetry Instrumentation Test Helpers: Metrics

This Ruby gem facilitates testing instrumentation libraries with respect to the OpenTelemetry Metrics API and SDK.

## Usage

Add the gem to your instrumentation's Gemfile:

```ruby
# Gemfile

group :test, :development do
gem 'opentelemetry-metrics-test-helpers', path: '../../helpers/metrics-test-helpers', require: false
end
```

It's not necessary to add this gem as a development dependency in the gemspec.
`opentelemetry-metrics-test-helpers` is not currently published to RubyGems,
and it is expected that it will always be bundled from the source in this
repository.

Note that metrics-test-helpers makes no attempt to require
the metrics API or SDK. It is designed to work with or without the metrics API and SDK defined, but you may experience issues if the API or SDK gem is in the gemfile but not yet loaded when the test helpers are initialized.

## Examples

In a test_helper.rb, after the `configure` block,
require this library:

```ruby
OpenTelemetry::SDK.configure do |c|
c.error_handler = ->(exception:, message:) { raise(exception || message) }
c.add_span_processor span_processor
end
require 'opentelemetry-metrics-test-helpers'
```

If the library uses Appraisals, it is recommended to appraise with and without the metrics api and sdk gems. Note that any metrics implementation in instrumentation libraries should be written against the API only, but for testing the SDK is required to collect metrics data - testing under all three scenarios (no metrics at all, api only, and with the sdk) helps ensure compliance with this requirement.

In a test:

```ruby
with_metrics_sdk do
let(:metric_snapshots) do
metrics_exporter.tap(&:pull)
.metric_snapshots.select { |snapshot| snapshot.data_points.any? }
.group_by(&:name)
end

it "uses metrics", with_metrics_sdk: true do
# do something here ...
_(metric_snapshots).count.must_equal(4)
end
end
```

- `metrics_exporter` is automatically reset before each test.
- `#with_metrics_sdk` will only yield if the SDK is present.
- `#with_metrics_api` will only yield if the API is present

## How can I get involved?

The `opentelemetry-metrics-test-helpers` gem source is [on github][repo-github], along with related gems including `opentelemetry-instrumentation-pg` and `opentelemetry-instrumentation-trilogy`.

The OpenTelemetry Ruby gems are maintained by the OpenTelemetry Ruby special interest group (SIG). You can get involved by joining us on our [GitHub Discussions][discussions-url], [Slack Channel][slack-channel] or attending our weekly meeting. See the [meeting calendar][community-meetings] for dates and times. For more information on this and other language SIGs, see the OpenTelemetry [community page][ruby-sig].

## License

The `opentelemetry-helpers-sql-obfuscation` gem is distributed under the Apache 2.0 license. See [LICENSE][license-github] for more information.

[repo-github]: https://github.com/open-telemetry/opentelemetry-ruby
[license-github]: https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/LICENSE
[ruby-sig]: https://github.com/open-telemetry/community#ruby-sig
[community-meetings]: https://github.com/open-telemetry/community#community-meetings
[slack-channel]: https://cloud-native.slack.com/archives/C01NWKKMKMY
[discussions-url]: https://github.com/open-telemetry/opentelemetry-ruby/discussions
24 changes: 24 additions & 0 deletions helpers/metrics-test-helpers/Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

# Copyright The OpenTelemetry Authors
#
# SPDX-License-Identifier: Apache-2.0

require 'bundler/gem_tasks'
require 'rake/testtask'
require 'rubocop/rake_task'

RuboCop::RakeTask.new

Rake::TestTask.new do |t|
t.libs << 'test'
t.libs << 'lib'
t.test_files = FileList['test/**/*_test.rb']
t.warning = false
end

if RUBY_ENGINE == 'truffleruby'
task default: %i[test]
else
task default: %i[test rubocop]
end
11 changes: 11 additions & 0 deletions helpers/metrics-test-helpers/bin/console
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

require 'bundler/setup'
require 'opentelemetry/metrics/test/helpers'

# You can add fixtures and/or initialization code here to make experimenting
# with your gem easier. You can also use a different console, if you like.

require 'irb'
IRB.start(__FILE__)
8 changes: 8 additions & 0 deletions helpers/metrics-test-helpers/bin/setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
set -vx

bundle install

# Do any other automated setup that you need to do here
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

# Copyright The OpenTelemetry Authors
#
# SPDX-License-Identifier: Apache-2.0

require_relative 'opentelemetry/metrics_test_helpers'
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# frozen_string_literal: true

# Copyright The OpenTelemetry Authors
#
# SPDX-License-Identifier: Apache-2.0

require 'minitest/spec'

module OpenTelemetry
module MetricsTestHelpers
module LoadedMetricsFeatures
OTEL_METRICS_API_LOADED = !Gem.loaded_specs['opentelemetry-metrics-api'].nil?
OTEL_METRICS_SDK_LOADED = !Gem.loaded_specs['opentelemetry-metrics-sdk'].nil?

extend self

def api_loaded?
OTEL_METRICS_API_LOADED
end

def sdk_loaded?
OTEL_METRICS_SDK_LOADED
end
end

module MinitestExtensions
def self.prepended(base)
base.extend(self)
end

def self.included(base)
base.extend(self)
end

def before_setup
super
reset_metrics_exporter
end

def with_metrics_sdk
yield if LoadedMetricsFeatures.sdk_loaded?
end

def without_metrics_sdk
yield unless LoadedMetricsFeatures.sdk_loaded?
end

def metrics_exporter
with_metrics_sdk { METRICS_EXPORTER }
end

def reset_meter_provider
with_metrics_sdk do
resource = OpenTelemetry.meter_provider.resource
OpenTelemetry.meter_provider = OpenTelemetry::SDK::Metrics::MeterProvider.new(resource: resource)
OpenTelemetry.meter_provider.add_metric_reader(METRICS_EXPORTER)
end
end

def reset_metrics_exporter
with_metrics_sdk do
METRICS_EXPORTER.pull
METRICS_EXPORTER.reset
end
end

def it(desc = 'anonymous', with_metrics_sdk: false, without_metrics_sdk: false, &block)
return super(desc, &block) unless with_metrics_sdk || without_metrics_sdk

raise ArgumentError, 'without_metrics_sdk and with_metrics_sdk must be mutually exclusive' if without_metrics_sdk && with_metrics_sdk

return if with_metrics_sdk && !LoadedMetricsFeatures.sdk_loaded?
return if without_metrics_sdk && LoadedMetricsFeatures.sdk_loaded?

super(desc, &block)
end
end

if LoadedMetricsFeatures.sdk_loaded?
METRICS_EXPORTER = OpenTelemetry::SDK::Metrics::Export::InMemoryMetricPullExporter.new
OpenTelemetry.meter_provider.add_metric_reader(METRICS_EXPORTER)
end

Minitest::Spec.prepend(MinitestExtensions)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

# Copyright The OpenTelemetry Authors
#
# SPDX-License-Identifier: Apache-2.0

module OpenTelemetry
module MetricsTestHelpers
VERSION = '0.0.1'
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# frozen_string_literal: true

require_relative 'lib/opentelemetry/metrics_test_helpers/version'

Gem::Specification.new do |spec|
spec.name = 'opentelemetry-metrics-test-helpers'
spec.version = OpenTelemetry::MetricsTestHelpers::VERSION
spec.authors = ['OpenTelemetry Authors']
spec.email = ['cncf-opentelemetry-contributors@lists.cncf.io']

spec.summary = 'Test helpers for adding metrics to instrumentation libraries'
spec.homepage = 'https://github.com/open-telemetry/opentelemetry-ruby-contrib'
spec.required_ruby_version = '>= 2.7.0'
spec.license = 'Apache-2.0'

spec.metadata['homepage_uri'] = spec.homepage
spec.metadata['source_code_uri'] = spec.homepage

# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
gemspec = File.basename(__FILE__)
spec.files = IO.popen(%w[git ls-files -z], chdir: __dir__, err: IO::NULL) do |ls|
ls.readlines("\x0", chomp: true).reject do |f|
(f == gemspec) ||
f.start_with?(*%w[bin/ test/ spec/ features/ .git appveyor Gemfile])
end
end
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
spec.require_paths = ['lib']

# Uncomment to register a new dependency of your gem
# spec.add_dependency "example-gem", "~> 1.0"
spec.add_dependency 'minitest'
spec.add_development_dependency 'appraisal'
spec.add_development_dependency 'rubocop'
spec.add_development_dependency 'rubocop-performance'

# For more information and examples about making a new gem, check out our
# guide at: https://bundler.io/guides/creating_gem.html
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

# Copyright The OpenTelemetry Authors
#
# SPDX-License-Identifier: Apache-2.0

require 'test_helper'

describe OpenTelemetry::MetricsTestHelpers do
with_metrics_sdk do
it 'must be defined' do
_(!defined?(OpenTelemetry::SDK::Metrics).nil?).must_equal(true)
end
end

without_metrics_sdk do
it 'must not be defined' do
_(!defined?(OpenTelemetry::SDK::Metrics).nil?).must_equal(false)
end
end
end
24 changes: 24 additions & 0 deletions helpers/metrics-test-helpers/test/test_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

# Copyright The OpenTelemetry Authors
#
# SPDX-License-Identifier: Apache-2.0

require 'opentelemetry-sdk'

begin
require 'opentelemetry-metrics-sdk'
rescue LoadError # rubocop: disable Lint/SuppressedException
end

begin
require 'opentelemetry-metrics-api'
rescue LoadError # rubocop: disable Lint/SuppressedException
end

OpenTelemetry::SDK.configure

$LOAD_PATH.unshift File.expand_path('../lib', __dir__)
require 'opentelemetry-metrics-test-helpers'

require 'minitest/autorun'
13 changes: 13 additions & 0 deletions instrumentation/base/Appraisals
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

appraise 'base' do
remove_gem 'opentelemetry-metrics-api'
remove_gem 'opentelemetry-metrics-sdk'
end

appraise 'metrics-api' do
remove_gem 'opentelemetry-metrics-sdk'
end

appraise 'metrics-sdk' do # rubocop: disable Lint/EmptyBlock
end
3 changes: 3 additions & 0 deletions instrumentation/base/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@

source 'https://rubygems.org'

gem 'opentelemetry-metrics-api', '~> 0.2'
gem 'opentelemetry-metrics-sdk'

gemspec
Loading