diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..2e774171f0 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,91 @@ +--- +version: 2 +updates: +- package-ecosystem: github-actions + directory: "/" + schedule: + interval: daily +- package-ecosystem: bundler + directory: "/" + schedule: + interval: weekly +- package-ecosystem: bundler + directory: "/api" + schedule: + interval: weekly +- package-ecosystem: bundler + directory: "/common" + schedule: + interval: weekly +- package-ecosystem: bundler + directory: "/exporter/jaeger" + schedule: + interval: weekly +- package-ecosystem: bundler + directory: "/exporter/otlp" + schedule: + interval: weekly +- package-ecosystem: bundler + directory: "/exporter/otlp-common" + schedule: + interval: weekly +- package-ecosystem: bundler + directory: "/exporter/otlp-grpc" + schedule: + interval: weekly +- package-ecosystem: bundler + directory: "/exporter/otlp-http" + schedule: + interval: weekly +- package-ecosystem: bundler + directory: "/exporter/otlp-metrics" + schedule: + interval: weekly +- package-ecosystem: bundler + directory: "/exporter/zipkin" + schedule: + interval: weekly +- package-ecosystem: bundler + directory: "/logs_api" + schedule: + interval: weekly +- package-ecosystem: bundler + directory: "/logs_sdk" + schedule: + interval: weekly +- package-ecosystem: bundler + directory: "/metrics_api" + schedule: + interval: weekly +- package-ecosystem: bundler + directory: "/metrics_sdk" + schedule: + interval: weekly +- package-ecosystem: bundler + directory: "/propagator/b3" + schedule: + interval: weekly +- package-ecosystem: bundler + directory: "/propagator/jaeger" + schedule: + interval: weekly +- package-ecosystem: bundler + directory: "/registry" + schedule: + interval: weekly +- package-ecosystem: bundler + directory: "/sdk" + schedule: + interval: weekly +- package-ecosystem: bundler + directory: "/sdk_experimental" + schedule: + interval: weekly +- package-ecosystem: bundler + directory: "/semantic_conventions" + schedule: + interval: weekly +- package-ecosystem: bundler + directory: "/" + schedule: + interval: weekly diff --git a/.github/workflows/ci-markdown-link.yml b/.github/workflows/ci-markdown-link.yml new file mode 100644 index 0000000000..7b42be0c1e --- /dev/null +++ b/.github/workflows/ci-markdown-link.yml @@ -0,0 +1,17 @@ +name: Markdown Link Check + +on: + pull_request: + +jobs: + markdown-link-check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: "Markdown Link Check" + uses: gaurav-nelson/github-action-markdown-link-check@v1 + with: + config-file: '.markdown-link-check.json' + use-quiet-mode: 'yes' + use-verbose-mode: 'yes' diff --git a/.github/workflows/ci-markdownlint.yml b/.github/workflows/ci-markdownlint.yml new file mode 100644 index 0000000000..f91609fdb9 --- /dev/null +++ b/.github/workflows/ci-markdownlint.yml @@ -0,0 +1,20 @@ +name: Markdown Lint Check + +on: + pull_request: + +jobs: + markdownlint-check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + # equivalent cli: markdownlint-cli2 "**/*.md" "#**/CHANGELOG.md" --config .markdownlint.json + - name: "Markdown Lint Check" + uses: DavidAnson/markdownlint-cli2-action@v16 + with: + fix: false + globs: | + **/*.md + !**/CHANGELOG.md + continue-on-error: true diff --git a/.markdown-link-check.json b/.markdown-link-check.json new file mode 100644 index 0000000000..12284d673f --- /dev/null +++ b/.markdown-link-check.json @@ -0,0 +1,10 @@ +{ + "ignorePatterns": [ + { + "pattern": "^http://localhost" + } + ], + "timeout": "5s", + "retryOn429": true, + "aliveStatusCodes": [200, 206, 429] +} diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 0000000000..10b3203b8a --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,13 @@ +{ + "emphasis-style": false, + "line-length": false, + "link-fragments": false, + "list-marker-space": false, + "no-emphasis-as-heading": false, + "no-hard-tabs": false, + "no-inline-html": false, + "no-trailing-punctuation": false, + "no-trailing-spaces": true, + "custom-rules-below-this-point": false, + "trim-code-block-and-unindent": true +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0e0bf8446a..496bd15304 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,7 +24,7 @@ conforms to the specification, but the interface and structure are flexible. It is preferable to have contributions follow the idioms of the language rather than conform to specific API names or argument patterns in the spec. -For a deeper discussion, see: https://github.com/open-telemetry/opentelemetry-specification/issues/165 +For a deeper discussion, see: ## Getting started @@ -40,6 +40,7 @@ git clone git@github.com:YOUR_GITHUB_NAME/opentelemetry-ruby.git ``` or + ```sh git clone https://github.com/YOUR_GITHUB_NAME/opentelemetry-ruby.git ``` @@ -66,11 +67,11 @@ _Setting up a running Ruby environment is outside the scope of this document._ This repository contains multiple Ruby gems: - * `opentelemetry-api` located in the `api` directory - * `opentelemetry-sdk` located in the `sdk` directory - * Various instrumentation gems located in subdirectories of `instrumentation` - * Various exporter gems located in subdirectories of `exporter` - * `opentelemetry-resource_detectors` located in the `resource_detectors` directory +* `opentelemetry-api` located in the `api` directory +* `opentelemetry-sdk` located in the `sdk` directory +* Various instrumentation gems located in subdirectories of `instrumentation` +* Various exporter gems located in subdirectories of `exporter` +* `opentelemetry-resource_detectors` located in the `resource_detectors` directory Each of these gems has its configuration and tests. @@ -89,10 +90,10 @@ configuration details. The services provided include: - * `app` - main container environment scoped to the `/app` directory. Used +* `app` - main container environment scoped to the `/app` directory. Used primarily to build and tag the `opentelemetry/opentelemetry-ruby:latest` image. - * `api` - convenience environment scoped to the `api` gem in the `/app/api` directory. - * `sdk` - convenience environment scoped to the `sdk` gem in the `/app/sdk` directory. +* `api` - convenience environment scoped to the `api` gem in the `/app/api` directory. +* `sdk` - convenience environment scoped to the `sdk` gem in the `/app/sdk` directory. To test using Docker: @@ -154,8 +155,8 @@ to ensure that your code complies before opening a pull request. We also use Yard to generate class documentation automatically. Among other things, this means: - * Methods and arguments should include the appropriate type annotations - * You can use markdown formatting in your documentation comments +* Methods and arguments should include the appropriate type annotations +* You can use markdown formatting in your documentation comments You can generate the docs locally to see the results, by running: @@ -249,7 +250,7 @@ Releases are normally performed using GitHub Actions. * For each gem, it will create a release tag and a GitHub release. * It will build and push the gems to rubygems. * It will build the docs and push them to - https://open-telemetry.github.io/opentelemetry-ruby + * If the releases succeed, the script will update the release pull request with the results and change its label to `release: complete`. If something went wrong, the script will, if possible, report the error @@ -269,15 +270,15 @@ review the release logs for the GitHub Actions workflows. There are four GitHub actions workflows related to releases. - * `Open release request` is the main release entrypoint, and is used to open +* `Open release request` is the main release entrypoint, and is used to open a release pull request. If something goes wrong with this process, the logs will appear in the workflow run. - * `Force release` is generally used only to restart a failed release. - * `[release hook] Update open releases` is run on pushes to the main branch, +* `Force release` is generally used only to restart a failed release. +* `[release hook] Update open releases` is run on pushes to the main branch, and pushes warnings to open release pull requests if you make modifications before triggering the release (i.e. because you might need to update the changelogs.) - * `[release hook] Process release` is the main release automation script and +* `[release hook] Process release` is the main release automation script and is run when a pull request is closed. If it determines that a release pull request was merged, it kicks off the release process for the affected gems. It also updates the label on a closed release pull request. Finally, it @@ -320,7 +321,7 @@ changed gems. To force-release, assuming the version and changelog are already modified: -``` +```sh toys release perform --rubygems-api-key=$API_KEY $GEM_NAME $GEM_VERSION ``` @@ -338,17 +339,17 @@ not correspond exactly to the gem name. For releases to succeed, new gems MUST include the following: - * The above configuration entry. - * The `*.gemspec` file, with the name matching the gem name. - * A `version.rb` file in the standard location, or in a location listed in +* The above configuration entry. +* The `*.gemspec` file, with the name matching the gem name. +* A `version.rb` file in the standard location, or in a location listed in the configuration. - * A `CHANGELOG.md` file. - * A `yard` rake task. +* A `CHANGELOG.md` file. +* A `yard` rake task. [cncf-cla]: https://identity.linuxfoundation.org/projects/cncf [github-draft]: https://github.blog/2019-02-14-introducing-draft-pull-requests/ [kube-github-workflow-pr]: https://github.com/kubernetes/community/blob/master/contributors/guide/github-workflow.md#7-create-a-pull-request -[otel-contributor-guide]: https://github.com/open-telemetry/community/blob/master/CONTRIBUTING.md -[otel-github-workflow]: https://github.com/open-telemetry/community/blob/master/CONTRIBUTING.md#github-workflow +[otel-contributor-guide]: https://github.com/open-telemetry/community/blob/main/guides/contributor/README.md +[otel-github-workflow]: https://github.com/open-telemetry/community/blob/main/guides/contributor/processes.md#workflows [otel-lib-guidelines]: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/library-guidelines.md [otel-specification]: https://github.com/open-telemetry/opentelemetry-specification diff --git a/README.md b/README.md index 93c256a470..76c7b82084 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ the [Ruby language](https://www.ruby-lang.org/en/downloads/branches/). - For more information on OpenTelemetry, visit: - For help or feedback on this project, join us in [GitHub Discussions][discussions-url]. +- For more examples, check [SDK example][examples-github]. ## License diff --git a/api/README.md b/api/README.md index b44d1ff8a0..966295ed9e 100644 --- a/api/README.md +++ b/api/README.md @@ -21,7 +21,7 @@ data should depend only on `opentelemetry-api`, deferring the choice of concrete Install the gem using: -``` +```sh gem install opentelemetry-api ``` @@ -58,7 +58,6 @@ The OpenTelemetry Ruby gems are maintained by the OpenTelemetry-Ruby special int The `opentelemetry-api` gem is distributed under the Apache 2.0 license. See [LICENSE][license-github] for more information. - [opentelemetry-home]: https://opentelemetry.io [bundler-home]: https://bundler.io [repo-github]: https://github.com/open-telemetry/opentelemetry-ruby diff --git a/common/README.md b/common/README.md index 8e1535ea3d..ab0b0aeae1 100644 --- a/common/README.md +++ b/common/README.md @@ -16,7 +16,7 @@ The `opentelemetry-common` gem provides common helpers for semantic conventions, Install the gem using: -``` +```sh gem install opentelemetry-common ``` diff --git a/examples/http/README.md b/examples/http/README.md index ca69a2a146..0c79d228be 100644 --- a/examples/http/README.md +++ b/examples/http/README.md @@ -11,19 +11,21 @@ This is a simple example that demonstrates tracing an HTTP request from client t ### Running the example Install gems + ```sh bundle install ``` Start the server + ```sh ruby server.rb ``` In a separate terminal window, run the client to make a single request: + ```sh ruby client.rb ``` You should see console exporter output for both the client and server sessions. - diff --git a/examples/metrics_sdk/README.md b/examples/metrics_sdk/README.md index 46f7b94efa..3ba206d783 100644 --- a/examples/metrics_sdk/README.md +++ b/examples/metrics_sdk/README.md @@ -1,6 +1,6 @@ # OpenTelemetry Ruby Metrics SDK Example -### metrics_collect.rb +## metrics_collect.rb Run the script to see the metric data from console @@ -8,7 +8,7 @@ Run the script to see the metric data from console ruby metrics_collect.rb ``` -### metrics_collect_otlp.rb +## metrics_collect_otlp.rb **WARN: this example doesn't work on alpine aarch64 container due to grpc installation issues.** @@ -16,7 +16,7 @@ This example tests both the metrics sdk and the metrics otlp http exporter. You can view the metrics in your favored backend (e.g. jaeger). -#### 1. Set up the local opentelemetry-collector. +### 1. Set up the local opentelemetry-collector. Given you have a `config.yml` file in your current directory and Docker is installed on your machine, run the following commands to pull the collector image and run the collector. @@ -56,9 +56,9 @@ service: More information on how to setup the OTel collector can be found in the in [quick start docs](https://opentelemetry.io/docs/collector/quick-start/). -#### 2. Assign the endpoint value to your destination address +### 2. Assign the endpoint value to your destination address -``` +```sh # Using environment variable ENV['OTEL_EXPORTER_OTLP_METRICS_ENDPOINT'] = 'http://host.docker.internal:4318/v1/metrics' @@ -66,7 +66,7 @@ ENV['OTEL_EXPORTER_OTLP_METRICS_ENDPOINT'] = 'http://host.docker.internal:4318/v export OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://host.docker.internal:4318/v1/metrics ``` -#### 3. Run the script to send metric data to OTLP collector +### 3. Run the script to send metric data to OTLP collector ```sh ruby metrics_collect_otlp.rb diff --git a/exporter/jaeger/README.md b/exporter/jaeger/README.md index 657d2f21f1..72a4a45f77 100644 --- a/exporter/jaeger/README.md +++ b/exporter/jaeger/README.md @@ -18,7 +18,7 @@ Generally, *libraries* that produce telemetry data should avoid depending direct Install the gem using: -``` +```sh gem install opentelemetry-sdk gem install opentelemetry-exporter-jaeger ``` @@ -104,7 +104,6 @@ The OpenTelemetry Ruby gems are maintained by the OpenTelemetry-Ruby special int The `opentelemetry-exporter-jaeger` gem is distributed under the Apache 2.0 license. See [LICENSE][license-github] for more information. - [jaeger-home]: https://www.jaegertracing.io [opentelemetry-home]: https://opentelemetry.io [bundler-home]: https://bundler.io diff --git a/exporter/otlp-common/README.md b/exporter/otlp-common/README.md index ec52cea0e6..48310702a1 100644 --- a/exporter/otlp-common/README.md +++ b/exporter/otlp-common/README.md @@ -26,12 +26,9 @@ The OpenTelemetry Ruby gems are maintained by the OpenTelemetry-Ruby special int The `opentelemetry-exporter-otlp-common` gem is distributed under the Apache 2.0 license. See [LICENSE][license-github] for more information. -[opentelemetry-collector-home]: https://opentelemetry.io/docs/collector/about/ [opentelemetry-home]: https://opentelemetry.io -[bundler-home]: https://bundler.io [repo-github]: https://github.com/open-telemetry/opentelemetry-ruby [license-github]: https://github.com/open-telemetry/opentelemetry-ruby/blob/main/LICENSE -[examples-github]: https://github.com/open-telemetry/opentelemetry-ruby/tree/main/examples [ruby-sig]: https://github.com/open-telemetry/community#ruby-sig [community-meetings]: https://github.com/open-telemetry/community#community-meetings [discussions-url]: https://github.com/open-telemetry/opentelemetry-ruby/discussions diff --git a/exporter/otlp-grpc/README.md b/exporter/otlp-grpc/README.md index ddb20bd8dd..fd8a40e2bc 100644 --- a/exporter/otlp-grpc/README.md +++ b/exporter/otlp-grpc/README.md @@ -22,7 +22,7 @@ This gem supports the [v0.11.0 release](https://github.com/open-telemetry/opente Install the gem using: -``` +```sh gem install opentelemetry-sdk gem install opentelemetry-exporter-otlp-grpc ``` @@ -82,7 +82,6 @@ The OpenTelemetry Ruby gems are maintained by the OpenTelemetry-Ruby special int The `opentelemetry-exporter-otlp-grpc` gem is distributed under the Apache 2.0 license. See [LICENSE][license-github] for more information. - [opentelemetry-collector-home]: https://opentelemetry.io/docs/collector/about/ [opentelemetry-home]: https://opentelemetry.io [bundler-home]: https://bundler.io diff --git a/exporter/otlp-http/README.md b/exporter/otlp-http/README.md index 79514b946a..7b1597b9b4 100644 --- a/exporter/otlp-http/README.md +++ b/exporter/otlp-http/README.md @@ -22,7 +22,7 @@ This gem supports the [v0.11.0 release](https://github.com/open-telemetry/opente Install the gem using: -``` +```sh gem install opentelemetry-sdk gem install opentelemetry-exporter-otlp-http ``` @@ -92,7 +92,6 @@ The OpenTelemetry Ruby gems are maintained by the OpenTelemetry-Ruby special int The `opentelemetry-exporter-otlp-http` gem is distributed under the Apache 2.0 license. See [LICENSE][license-github] for more information. - [opentelemetry-collector-home]: https://opentelemetry.io/docs/collector/about/ [opentelemetry-home]: https://opentelemetry.io [bundler-home]: https://bundler.io diff --git a/exporter/otlp-metrics/README.md b/exporter/otlp-metrics/README.md index 3bbca793dd..4d8986546f 100644 --- a/exporter/otlp-metrics/README.md +++ b/exporter/otlp-metrics/README.md @@ -18,6 +18,41 @@ Generally, *libraries* that produce telemetry data should avoid depending direct This gem supports the [v0.20.0 release][otel-proto-release] of OTLP. +## Prerequisite + +The exporter-oltp-metrics depends on two gems that have not been officially released: opentelemetry-metrics-sdk and opentelemetry-metrics-api. + +Within the .gemspec file, these gems are not listed as dependencies. However, for users who need utilize this metrics exporter, they must first install and load these two gems before they can use the exporter. + +To facilitate this, there are couple recommended approaches: + +### 1. Download the source code + +1. Download the [opentelemetry-ruby](https://github.com/open-telemetry/opentelemetry-ruby). +2. Navigate to subfolder, then build the [metrics_sdk](https://github.com/open-telemetry/opentelemetry-ruby/tree/main/metrics_sdk) and [metrics_api](https://github.com/open-telemetry/opentelemetry-ruby/tree/main/metrics_api). +3. Execute `gem build *.gemspec`. +4. Lastly, install the built gem into the system. + +### 2. Using `path:` option in Gemfile with downloaded source code + +git clone [opentelemetry-ruby](https://github.com/open-telemetry/opentelemetry-ruby) first, then use Gemfile + +```ruby +# Gemfile +source 'https://rubygems.org' +gem 'opentelemetry-metrics-api', path: "opentelemetry-ruby/metrics_api" +gem 'opentelemetry-metrics-sdk', path: "opentelemetry-ruby/metrics_sdk" +``` + +### 3. Using `git:` option in Gemfile + +```ruby +# Gemfile +source 'https://rubygems.org' +gem 'opentelemetry-metrics-api', git: "https://github.com/open-telemetry/opentelemetry-ruby", glob: 'metrics_api/*.gemspec' +gem 'opentelemetry-metrics-sdk', git: "https://github.com/open-telemetry/opentelemetry-ruby", glob: 'metrics_sdk/*.gemspec' +``` + ## How do I get started? Install the gem using: @@ -66,7 +101,7 @@ The collector exporter can be configured explicitly in code, or via environment | Parameter | Environment variable | Default | | ------------------- | -------------------------------------------- | ----------------------------------- | | `endpoint:` | `OTEL_EXPORTER_OTLP_ENDPOINT` | `"http://localhost:4318/v1/metrics"` | -| `certificate_file: `| `OTEL_EXPORTER_OTLP_CERTIFICATE` | | +| `certificate_file:`| `OTEL_EXPORTER_OTLP_CERTIFICATE` | | | `headers:` | `OTEL_EXPORTER_OTLP_HEADERS` | | | `compression:` | `OTEL_EXPORTER_OTLP_COMPRESSION` | `"gzip"` | | `timeout:` | `OTEL_EXPORTER_OTLP_TIMEOUT` | `10` | @@ -75,7 +110,6 @@ The collector exporter can be configured explicitly in code, or via environment `ssl_verify_mode:` parameter values should be flags for server certificate verification: `OpenSSL::SSL:VERIFY_PEER` and `OpenSSL::SSL:VERIFY_NONE` are acceptable. These values can also be set using the appropriately named environment variables as shown where `VERIFY_PEER` will take precedence over `VERIFY_NONE`. Please see [the Net::HTTP docs](https://ruby-doc.org/stdlib-2.7.6/libdoc/net/http/rdoc/Net/HTTP.html#verify_mode) for more information about these flags. - ## How can I get involved? The `opentelemetry-exporter-otlp-metrics` gem source is [on github][repo-github], along with related gems including `opentelemetry-metrics-sdk`. diff --git a/exporter/otlp-metrics/lib/opentelemetry/exporter/otlp/metrics/metrics_exporter.rb b/exporter/otlp-metrics/lib/opentelemetry/exporter/otlp/metrics/metrics_exporter.rb index a1b0bf415f..44302e0e92 100644 --- a/exporter/otlp-metrics/lib/opentelemetry/exporter/otlp/metrics/metrics_exporter.rb +++ b/exporter/otlp-metrics/lib/opentelemetry/exporter/otlp/metrics/metrics_exporter.rb @@ -115,7 +115,7 @@ def send_bytes(bytes, timeout:) @http.read_timeout = remaining_timeout @http.write_timeout = remaining_timeout @http.start unless @http.started? - response = measure_request_duration { @http.request(request) } + response = @http.request(request) case response when Net::HTTPOK response.body # Read and discard body diff --git a/exporter/otlp-metrics/lib/opentelemetry/exporter/otlp/metrics/util.rb b/exporter/otlp-metrics/lib/opentelemetry/exporter/otlp/metrics/util.rb index 264b1e19bf..37f1896da0 100644 --- a/exporter/otlp-metrics/lib/opentelemetry/exporter/otlp/metrics/util.rb +++ b/exporter/otlp-metrics/lib/opentelemetry/exporter/otlp/metrics/util.rb @@ -9,7 +9,7 @@ module Exporter module OTLP module Metrics # Util module provide essential functionality for exporter - module Util # rubocop:disable Metrics/ModuleLength + module Util KEEP_ALIVE_TIMEOUT = 30 RETRY_COUNT = 5 ERROR_MESSAGE_INVALID_HEADERS = 'headers must be a String with comma-separated URL Encoded UTF-8 k=v pairs or a Hash' @@ -67,16 +67,6 @@ def prepare_headers(config_headers) headers end - def measure_request_duration - start = Process.clock_gettime(Process::CLOCK_MONOTONIC) - begin - yield - ensure - stop = Process.clock_gettime(Process::CLOCK_MONOTONIC) - 1000.0 * (stop - start) - end - end - def parse_headers(raw) entries = raw.split(',') raise ArgumentError, ERROR_MESSAGE_INVALID_HEADERS if entries.empty? diff --git a/exporter/otlp-metrics/lib/opentelemetry/exporter/otlp/metrics_exporter.rb b/exporter/otlp-metrics/lib/opentelemetry/exporter/otlp/metrics_exporter.rb deleted file mode 100644 index 3d86f9e979..0000000000 --- a/exporter/otlp-metrics/lib/opentelemetry/exporter/otlp/metrics_exporter.rb +++ /dev/null @@ -1,309 +0,0 @@ -# frozen_string_literal: true - -# Copyright The OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -require 'opentelemetry/common' -require 'opentelemetry/sdk' -require 'net/http' -require 'csv' -require 'zlib' - -require 'google/rpc/status_pb' - -require 'opentelemetry/proto/common/v1/common_pb' -require 'opentelemetry/proto/resource/v1/resource_pb' -require 'opentelemetry/proto/metrics/v1/metrics_pb' -require 'opentelemetry/proto/collector/metrics/v1/metrics_service_pb' - -require 'opentelemetry/metrics' -require 'opentelemetry/sdk/metrics' - -require_relative './util' - -module OpenTelemetry - module Exporter - module OTLP - # An OpenTelemetry metrics exporter that sends metrics over HTTP as Protobuf encoded OTLP ExportMetricsServiceRequest. - class MetricsExporter < ::OpenTelemetry::SDK::Metrics::Export::MetricReader - include Util - - attr_reader :metric_snapshots - - SUCCESS = OpenTelemetry::SDK::Metrics::Export::SUCCESS - FAILURE = OpenTelemetry::SDK::Metrics::Export::FAILURE - private_constant(:SUCCESS, :FAILURE) - - WRITE_TIMEOUT_SUPPORTED = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.6') - private_constant(:WRITE_TIMEOUT_SUPPORTED) - - def self.ssl_verify_mode - if ENV.key?('OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_PEER') - OpenSSL::SSL::VERIFY_PEER - elsif ENV.key?('OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_NONE') - OpenSSL::SSL::VERIFY_NONE - else - OpenSSL::SSL::VERIFY_PEER - end - end - - def initialize(endpoint: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_METRICS_ENDPOINT', 'OTEL_EXPORTER_OTLP_ENDPOINT', default: 'http://localhost:4318/v1/metrics'), - certificate_file: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE', 'OTEL_EXPORTER_OTLP_CERTIFICATE'), - ssl_verify_mode: MetricsExporter.ssl_verify_mode, - headers: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_METRICS_HEADERS', 'OTEL_EXPORTER_OTLP_HEADERS', default: {}), - compression: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_METRICS_COMPRESSION', 'OTEL_EXPORTER_OTLP_COMPRESSION', default: 'gzip'), - timeout: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_OTLP_METRICS_TIMEOUT', 'OTEL_EXPORTER_OTLP_TIMEOUT', default: 10)) - raise ArgumentError, "invalid url for OTLP::MetricsExporter #{endpoint}" unless OpenTelemetry::Common::Utilities.valid_url?(endpoint) - raise ArgumentError, "unsupported compression key #{compression}" unless compression.nil? || %w[gzip none].include?(compression) - - # create the MetricStore object - super() - - @uri = if endpoint == ENV['OTEL_EXPORTER_OTLP_ENDPOINT'] - URI.join(endpoint, 'v1/metrics') - else - URI(endpoint) - end - - @http = http_connection(@uri, ssl_verify_mode, certificate_file) - - @path = @uri.path - @headers = prepare_headers(headers) - @timeout = timeout.to_f - @compression = compression - @mutex = Mutex.new - @shutdown = false - end - - # consolidate the metrics data into the form of MetricData - # - # return MetricData - def pull - export(collect) - end - - # metrics Array[MetricData] - def export(metrics, timeout: nil) - @mutex.synchronize do - send_bytes(encode(metrics), timeout: timeout) - end - end - - def send_bytes(bytes, timeout:) - return FAILURE if bytes.nil? - - request = Net::HTTP::Post.new(@path) - - if @compression == 'gzip' - request.add_field('Content-Encoding', 'gzip') - body = Zlib.gzip(bytes) - else - body = bytes - end - - request.body = body - request.add_field('Content-Type', 'application/x-protobuf') - @headers.each { |key, value| request.add_field(key, value) } - - retry_count = 0 - timeout ||= @timeout - start_time = OpenTelemetry::Common::Utilities.timeout_timestamp - - around_request do - remaining_timeout = OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time) - return FAILURE if remaining_timeout.zero? - - @http.open_timeout = remaining_timeout - @http.read_timeout = remaining_timeout - @http.write_timeout = remaining_timeout if WRITE_TIMEOUT_SUPPORTED - @http.start unless @http.started? - response = measure_request_duration { @http.request(request) } - case response - when Net::HTTPOK - response.body # Read and discard body - SUCCESS - when Net::HTTPServiceUnavailable, Net::HTTPTooManyRequests - response.body # Read and discard body - redo if backoff?(retry_after: response['Retry-After'], retry_count: retry_count += 1, reason: response.code) - OpenTelemetry.logger.warn('Net::HTTPServiceUnavailable/Net::HTTPTooManyRequests in MetricsExporter#send_bytes') - FAILURE - when Net::HTTPRequestTimeOut, Net::HTTPGatewayTimeOut, Net::HTTPBadGateway - response.body # Read and discard body - redo if backoff?(retry_count: retry_count += 1, reason: response.code) - OpenTelemetry.logger.warn('Net::HTTPRequestTimeOut/Net::HTTPGatewayTimeOut/Net::HTTPBadGateway in MetricsExporter#send_bytes') - FAILURE - when Net::HTTPNotFound - OpenTelemetry.handle_error(message: "OTLP metrics_exporter received http.code=404 for uri: '#{@path}'") - FAILURE - when Net::HTTPBadRequest, Net::HTTPClientError, Net::HTTPServerError - log_status(response.body) - OpenTelemetry.logger.warn('Net::HTTPBadRequest/Net::HTTPClientError/Net::HTTPServerError in MetricsExporter#send_bytes') - FAILURE - when Net::HTTPRedirection - @http.finish - handle_redirect(response['location']) - redo if backoff?(retry_after: 0, retry_count: retry_count += 1, reason: response.code) - else - @http.finish - OpenTelemetry.logger.warn("Unexpected error in OTLP::MetricsExporter#send_bytes - #{response.message}") - FAILURE - end - rescue Net::OpenTimeout, Net::ReadTimeout - retry if backoff?(retry_count: retry_count += 1, reason: 'timeout') - OpenTelemetry.logger.warn('Net::OpenTimeout/Net::ReadTimeout in MetricsExporter#send_bytes') - return FAILURE - rescue OpenSSL::SSL::SSLError - retry if backoff?(retry_count: retry_count += 1, reason: 'openssl_error') - OpenTelemetry.logger.warn('OpenSSL::SSL::SSLError in MetricsExporter#send_bytes') - return FAILURE - rescue SocketError - retry if backoff?(retry_count: retry_count += 1, reason: 'socket_error') - OpenTelemetry.logger.warn('SocketError in MetricsExporter#send_bytes') - return FAILURE - rescue SystemCallError => e - retry if backoff?(retry_count: retry_count += 1, reason: e.class.name) - OpenTelemetry.logger.warn('SystemCallError in MetricsExporter#send_bytes') - return FAILURE - rescue EOFError - retry if backoff?(retry_count: retry_count += 1, reason: 'eof_error') - OpenTelemetry.logger.warn('EOFError in MetricsExporter#send_bytes') - return FAILURE - rescue Zlib::DataError - retry if backoff?(retry_count: retry_count += 1, reason: 'zlib_error') - OpenTelemetry.logger.warn('Zlib::DataError in MetricsExporter#send_bytes') - return FAILURE - rescue StandardError => e - OpenTelemetry.handle_error(exception: e, message: 'unexpected error in OTLP::MetricsExporter#send_bytes') - return FAILURE - end - ensure - # Reset timeouts to defaults for the next call. - @http.open_timeout = @timeout - @http.read_timeout = @timeout - @http.write_timeout = @timeout if WRITE_TIMEOUT_SUPPORTED - end - - def encode(metrics_data) - Opentelemetry::Proto::Collector::Metrics::V1::ExportMetricsServiceRequest.encode( - Opentelemetry::Proto::Collector::Metrics::V1::ExportMetricsServiceRequest.new( - resource_metrics: metrics_data - .group_by(&:resource) - .map do |resource, scope_metrics| - Opentelemetry::Proto::Metrics::V1::ResourceMetrics.new( - resource: Opentelemetry::Proto::Resource::V1::Resource.new( - attributes: resource.attribute_enumerator.map { |key, value| as_otlp_key_value(key, value) } - ), - scope_metrics: scope_metrics - .group_by(&:instrumentation_scope) - .map do |instrumentation_scope, metrics| - Opentelemetry::Proto::Metrics::V1::ScopeMetrics.new( - scope: Opentelemetry::Proto::Common::V1::InstrumentationScope.new( - name: instrumentation_scope.name, - version: instrumentation_scope.version - ), - metrics: metrics.map { |sd| as_otlp_metrics(sd) } - ) - end - ) - end - ) - ) - rescue StandardError => e - OpenTelemetry.handle_error(exception: e, message: 'unexpected error in OTLP::MetricsExporter#encode') - nil - end - - # metrics_pb has following type of data: :gauge, :sum, :histogram, :exponential_histogram, :summary - # current metric sdk only implements instrument: :counter -> :sum, :histogram -> :histogram - # - # metrics [MetricData] - def as_otlp_metrics(metrics) - case metrics.instrument_kind - when :observable_gauge - Opentelemetry::Proto::Metrics::V1::Metric.new( - name: metrics.name, - description: metrics.description, - unit: metrics.unit, - gauge: Opentelemetry::Proto::Metrics::V1::Gauge.new( - aggregation_temporality: as_otlp_aggregation_temporality(metrics.aggregation_temporality), - data_points: metrics.data_points.map do |ndp| - number_data_point(ndp) - end - ) - ) - - when :counter, :up_down_counter - Opentelemetry::Proto::Metrics::V1::Metric.new( - name: metrics.name, - description: metrics.description, - unit: metrics.unit, - sum: Opentelemetry::Proto::Metrics::V1::Sum.new( - aggregation_temporality: as_otlp_aggregation_temporality(metrics.aggregation_temporality), - data_points: metrics.data_points.map do |ndp| - number_data_point(ndp) - end - ) - ) - - when :histogram - Opentelemetry::Proto::Metrics::V1::Metric.new( - name: metrics.name, - description: metrics.description, - unit: metrics.unit, - histogram: Opentelemetry::Proto::Metrics::V1::Histogram.new( - aggregation_temporality: as_otlp_aggregation_temporality(metrics.aggregation_temporality), - data_points: metrics.data_points.map do |hdp| - histogram_data_point(hdp) - end - ) - ) - end - end - - def as_otlp_aggregation_temporality(type) - case type - when :delta then Opentelemetry::Proto::Metrics::V1::AggregationTemporality::AGGREGATION_TEMPORALITY_DELTA - when :cumulative then Opentelemetry::Proto::Metrics::V1::AggregationTemporality::AGGREGATION_TEMPORALITY_CUMULATIVE - else Opentelemetry::Proto::Metrics::V1::AggregationTemporality::AGGREGATION_TEMPORALITY_UNSPECIFIED - end - end - - def histogram_data_point(hdp) - Opentelemetry::Proto::Metrics::V1::HistogramDataPoint.new( - attributes: hdp.attributes.map { |k, v| as_otlp_key_value(k, v) }, - start_time_unix_nano: hdp.start_time_unix_nano, - time_unix_nano: hdp.time_unix_nano, - count: hdp.count, - sum: hdp.sum, - bucket_counts: hdp.bucket_counts, - explicit_bounds: hdp.explicit_bounds, - exemplars: hdp.exemplars, - min: hdp.min, - max: hdp.max - ) - end - - def number_data_point(ndp) - Opentelemetry::Proto::Metrics::V1::NumberDataPoint.new( - attributes: ndp.attributes.map { |k, v| as_otlp_key_value(k, v) }, - as_int: ndp.value, - start_time_unix_nano: ndp.start_time_unix_nano, - time_unix_nano: ndp.time_unix_nano, - exemplars: ndp.exemplars # exemplars not implemented yet from metrics sdk - ) - end - - # may not need this - def reset - SUCCESS - end - - def shutdown(timeout: nil) - @shutdown = true - SUCCESS - end - end - end - end -end diff --git a/exporter/otlp-metrics/lib/opentelemetry/exporter/otlp/util.rb b/exporter/otlp-metrics/lib/opentelemetry/exporter/otlp/util.rb deleted file mode 100644 index 85070a6f43..0000000000 --- a/exporter/otlp-metrics/lib/opentelemetry/exporter/otlp/util.rb +++ /dev/null @@ -1,139 +0,0 @@ -# frozen_string_literal: true - -# Copyright The OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -module OpenTelemetry - module Exporter - module OTLP - # Util module provide essential functionality for exporter - module Util # rubocop:disable Metrics/ModuleLength - KEEP_ALIVE_TIMEOUT = 30 - RETRY_COUNT = 5 - ERROR_MESSAGE_INVALID_HEADERS = 'headers must be a String with comma-separated URL Encoded UTF-8 k=v pairs or a Hash' - DEFAULT_USER_AGENT = "OTel-OTLP-MetricsExporter-Ruby/#{OpenTelemetry::Exporter::OTLP::VERSION} Ruby/#{RUBY_VERSION} (#{RUBY_PLATFORM}; #{RUBY_ENGINE}/#{RUBY_ENGINE_VERSION})".freeze - - def http_connection(uri, ssl_verify_mode, certificate_file) - http = Net::HTTP.new(uri.host, uri.port) - http.use_ssl = uri.scheme == 'https' - http.verify_mode = ssl_verify_mode - http.ca_file = certificate_file unless certificate_file.nil? - http.keep_alive_timeout = KEEP_ALIVE_TIMEOUT - http - end - - def around_request - OpenTelemetry::Common::Utilities.untraced { yield } # rubocop:disable Style/ExplicitBlockArgument - end - - def as_otlp_key_value(key, value) - Opentelemetry::Proto::Common::V1::KeyValue.new(key: key, value: as_otlp_any_value(value)) - rescue Encoding::UndefinedConversionError => e - encoded_value = value.encode('UTF-8', invalid: :replace, undef: :replace, replace: '�') - OpenTelemetry.handle_error(exception: e, message: "encoding error for key #{key} and value #{encoded_value}") - Opentelemetry::Proto::Common::V1::KeyValue.new(key: key, value: as_otlp_any_value('Encoding Error')) - end - - def as_otlp_any_value(value) - result = Opentelemetry::Proto::Common::V1::AnyValue.new - case value - when String - result.string_value = value - when Integer - result.int_value = value - when Float - result.double_value = value - when true, false - result.bool_value = value - when Array - values = value.map { |element| as_otlp_any_value(element) } - result.array_value = Opentelemetry::Proto::Common::V1::ArrayValue.new(values: values) - end - result - end - - def prepare_headers(config_headers) - headers = case config_headers - when String then parse_headers(config_headers) - when Hash then config_headers.dup - else - raise ArgumentError, ERROR_MESSAGE_INVALID_HEADERS - end - - headers['User-Agent'] = "#{headers.fetch('User-Agent', '')} #{DEFAULT_USER_AGENT}".strip - - headers - end - - def measure_request_duration - start = Process.clock_gettime(Process::CLOCK_MONOTONIC) - begin - yield - ensure - stop = Process.clock_gettime(Process::CLOCK_MONOTONIC) - 1000.0 * (stop - start) - end - end - - def parse_headers(raw) - entries = raw.split(',') - raise ArgumentError, ERROR_MESSAGE_INVALID_HEADERS if entries.empty? - - entries.each_with_object({}) do |entry, headers| - k, v = entry.split('=', 2).map(&CGI.method(:unescape)) - begin - k = k.to_s.strip - v = v.to_s.strip - rescue Encoding::CompatibilityError - raise ArgumentError, ERROR_MESSAGE_INVALID_HEADERS - rescue ArgumentError => e - raise e, ERROR_MESSAGE_INVALID_HEADERS - end - raise ArgumentError, ERROR_MESSAGE_INVALID_HEADERS if k.empty? || v.empty? - - headers[k] = v - end - end - - def backoff?(retry_count:, reason:, retry_after: nil) - return false if retry_count > RETRY_COUNT - - sleep_interval = nil - unless retry_after.nil? - sleep_interval = - begin - Integer(retry_after) - rescue ArgumentError - nil - end - sleep_interval ||= - begin - Time.httpdate(retry_after) - Time.now - rescue # rubocop:disable Style/RescueStandardError - nil - end - sleep_interval = nil unless sleep_interval&.positive? - end - sleep_interval ||= rand(2**retry_count) - - sleep(sleep_interval) - true - end - - def log_status(body) - status = Google::Rpc::Status.decode(body) - details = status.details.map do |detail| - klass_or_nil = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(detail.type_name).msgclass - detail.unpack(klass_or_nil) if klass_or_nil - end.compact - OpenTelemetry.handle_error(message: "OTLP metrics_exporter received rpc.Status{message=#{status.message}, details=#{details}}") - rescue StandardError => e - OpenTelemetry.handle_error(exception: e, message: 'unexpected error decoding rpc.Status in OTLP::MetricsExporter#log_status') - end - - def handle_redirect(location); end - end - end - end -end diff --git a/exporter/otlp-metrics/test/opentelemetry/exporter/otlp/metrics_exporter_test.rb b/exporter/otlp-metrics/test/opentelemetry/exporter/otlp/metrics/metrics_exporter_test.rb similarity index 100% rename from exporter/otlp-metrics/test/opentelemetry/exporter/otlp/metrics_exporter_test.rb rename to exporter/otlp-metrics/test/opentelemetry/exporter/otlp/metrics/metrics_exporter_test.rb diff --git a/exporter/zipkin/README.md b/exporter/zipkin/README.md index fd7cdde0a8..b568ba7374 100644 --- a/exporter/zipkin/README.md +++ b/exporter/zipkin/README.md @@ -18,7 +18,7 @@ Generally, *libraries* that produce telemetry data should avoid depending direct Install the gem using: -``` +```sh gem install opentelemetry-sdk gem install opentelemetry-exporter-zipkin ``` @@ -80,7 +80,6 @@ The OpenTelemetry Ruby gems are maintained by the OpenTelemetry-Ruby special int The `opentelemetry-exporter-zipkin` gem is distributed under the Apache 2.0 license. See [LICENSE][license-github] for more information. - [zipkin-home]: https://zipkin.io/ [opentelemetry-home]: https://opentelemetry.io [bundler-home]: https://bundler.io diff --git a/logs_api/test/opentelemetry/logs/logger_test.rb b/logs_api/test/opentelemetry/logs/logger_test.rb index 9fd35a651c..faf549f3d6 100644 --- a/logs_api/test/opentelemetry/logs/logger_test.rb +++ b/logs_api/test/opentelemetry/logs/logger_test.rb @@ -9,7 +9,7 @@ describe OpenTelemetry::Logs::Logger do let(:logger) { OpenTelemetry::Logs::Logger.new } - describe '#emit' do + describe '#on_emit' do it 'returns nil, as it is a no-op method' do assert_nil(logger.on_emit) end diff --git a/logs_api/test/test_helper.rb b/logs_api/test/test_helper.rb index 151c9213ec..a141bff9aa 100644 --- a/logs_api/test/test_helper.rb +++ b/logs_api/test/test_helper.rb @@ -5,7 +5,12 @@ # SPDX-License-Identifier: Apache-2.0 require 'simplecov' -SimpleCov.start { enable_coverage :branch } + +SimpleCov.start do + enable_coverage :branch + add_filter '/test/' +end + SimpleCov.minimum_coverage 85 require 'opentelemetry-logs-api' diff --git a/logs_sdk/lib/opentelemetry/sdk/logs/log_record_data.rb b/logs_sdk/lib/opentelemetry/sdk/logs/log_record_data.rb index 17d8b263fc..5a7e456d5c 100644 --- a/logs_sdk/lib/opentelemetry/sdk/logs/log_record_data.rb +++ b/logs_sdk/lib/opentelemetry/sdk/logs/log_record_data.rb @@ -13,7 +13,7 @@ module Logs :severity_text, # optional String :severity_number, # optional Integer :body, # optional String, Numeric, Boolean, Array, Hash{String => String, Numeric, Boolean, Array} - :attributes, # optional Hash{String => String, Numeric, Boolean, Array} + :attributes, # optional Hash{String => String, Numeric, Boolean, Array} :trace_id, # optional String (16-byte binary) :span_id, # optional String (8-byte binary) :trace_flags, # optional Integer (8-bit byte of bit flags) diff --git a/logs_sdk/lib/opentelemetry/sdk/logs/log_record_processor.rb b/logs_sdk/lib/opentelemetry/sdk/logs/log_record_processor.rb index 6b51b16915..6cca12ea14 100644 --- a/logs_sdk/lib/opentelemetry/sdk/logs/log_record_processor.rb +++ b/logs_sdk/lib/opentelemetry/sdk/logs/log_record_processor.rb @@ -26,7 +26,7 @@ def on_emit(log_record, context); end # the process after an invocation, but before the `Processor` exports # the completed spans. # - # @param [Numeric] timeout An optional timeout in seconds. + # @param [optional Numeric] timeout An optional timeout in seconds. # @return [Integer] Export::SUCCESS if no error occurred, Export::FAILURE if # a non-specific failure occurred, Export::TIMEOUT if a timeout occurred. def force_flush(timeout: nil) @@ -35,7 +35,7 @@ def force_flush(timeout: nil) # Called when {LoggerProvider#shutdown} is called. # - # @param [Numeric] timeout An optional timeout in seconds. + # @param [optional Numeric] timeout An optional timeout in seconds. # @return [Integer] Export::SUCCESS if no error occurred, Export::FAILURE if # a non-specific failure occurred, Export::TIMEOUT if a timeout occurred. def shutdown(timeout: nil) diff --git a/logs_sdk/lib/opentelemetry/sdk/logs/logger.rb b/logs_sdk/lib/opentelemetry/sdk/logs/logger.rb index 51f096c143..231999a33c 100644 --- a/logs_sdk/lib/opentelemetry/sdk/logs/logger.rb +++ b/logs_sdk/lib/opentelemetry/sdk/logs/logger.rb @@ -34,6 +34,8 @@ def initialize(name, version, logger_provider) # @param [optional OpenTelemetry::Trace::SpanContext] span_context The # OpenTelemetry::Trace::SpanContext to associate with the # {LogRecord}. + # @param [optional String] severity_text Original string representation of + # the severity as it is known at the source. Also known as log level. # @param severity_number [optional Integer] Numerical value of the # severity. Smaller numerical values correspond to less severe events # (such as debug events), larger numerical values correspond to more diff --git a/logs_sdk/test/opentelemetry/sdk/logs/export/batch_log_record_processor_test.rb b/logs_sdk/test/opentelemetry/sdk/logs/export/batch_log_record_processor_test.rb index 08aee76e85..64e81477a3 100644 --- a/logs_sdk/test/opentelemetry/sdk/logs/export/batch_log_record_processor_test.rb +++ b/logs_sdk/test/opentelemetry/sdk/logs/export/batch_log_record_processor_test.rb @@ -204,6 +204,10 @@ def to_log_record_data end it 'logs a warning if a log record was emitted after the buffer is full' do + # This will be fixed as part of Issue #1701 + # https://github.com/open-telemetry/opentelemetry-ruby/issues/1701 + skip if RUBY_ENGINE == 'jruby' + mock_otel_logger = Minitest::Mock.new mock_otel_logger.expect(:warn, nil, ['1 log record(s) dropped. Reason: buffer-full']) diff --git a/logs_sdk/test/opentelemetry/sdk/logs/log_record_processor_test.rb b/logs_sdk/test/opentelemetry/sdk/logs/log_record_processor_test.rb new file mode 100644 index 0000000000..9986b1915f --- /dev/null +++ b/logs_sdk/test/opentelemetry/sdk/logs/log_record_processor_test.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require 'test_helper' + +describe OpenTelemetry::SDK::Logs::LogRecordProcessor do + let(:processor) { OpenTelemetry::SDK::Logs::LogRecordProcessor.new } + let(:log_record) { nil } + let(:context) { nil } + + it 'implements #on_emit' do + processor.on_emit(log_record, context) + end + + it 'implements #force_flush' do + processor.force_flush + end + + it 'returns a success code when #force_flush is called' do + assert(OpenTelemetry::SDK::Logs::Export::SUCCESS, processor.force_flush) + end + + it 'implements #shutdown' do + processor.shutdown + end + + it 'returns a success code when #shutdown is called' do + assert(OpenTelemetry::SDK::Logs::Export::SUCCESS, processor.shutdown) + end +end diff --git a/logs_sdk/test/opentelemetry/sdk/logs/log_record_test.rb b/logs_sdk/test/opentelemetry/sdk/logs/log_record_test.rb index 7ba19048fe..ca38350e1f 100644 --- a/logs_sdk/test/opentelemetry/sdk/logs/log_record_test.rb +++ b/logs_sdk/test/opentelemetry/sdk/logs/log_record_test.rb @@ -15,7 +15,8 @@ describe '#initialize' do describe 'observed_timestamp' do describe 'when observed_timestamp is present' do - let(:observed_timestamp) { '1692661486.2841358' } + let(:current_time) { Time.now } + let(:observed_timestamp) { current_time + 1 } let(:args) { { observed_timestamp: observed_timestamp } } it 'is equal to observed_timestamp' do @@ -26,13 +27,8 @@ refute_equal(log_record.timestamp, log_record.observed_timestamp) end - # Process.clock_gettime is used to set the current time - # That method returns a Float. Since the stubbed value of - # observed_timestamp is a String, we can know the the - # observed_timestamp was not set to the value of Process.clock_gettime - # by making sure its value is not a Float. it 'is not equal to the current time' do - refute_instance_of(Float, log_record.observed_timestamp) + refute_equal(current_time, log_record.observed_timestamp) end end diff --git a/logs_sdk/test/test_helper.rb b/logs_sdk/test/test_helper.rb index 59d743987f..7f11ee9508 100644 --- a/logs_sdk/test/test_helper.rb +++ b/logs_sdk/test/test_helper.rb @@ -5,7 +5,12 @@ # SPDX-License-Identifier: Apache-2.0 require 'simplecov' -SimpleCov.start { enable_coverage :branch } + +SimpleCov.start do + enable_coverage :branch + add_filter '/test/' +end + SimpleCov.minimum_coverage 85 require 'opentelemetry-logs-api' diff --git a/metrics_api/README.md b/metrics_api/README.md index 8656711979..36bc4e39f8 100644 --- a/metrics_api/README.md +++ b/metrics_api/README.md @@ -24,7 +24,7 @@ This code is still under development and is not a complete implementation of the Install the gem using: -``` +```sh gem install opentelemetry-metrics-api ``` diff --git a/metrics_sdk/README.md b/metrics_sdk/README.md index feb8e89aa7..86a8e95b00 100644 --- a/metrics_sdk/README.md +++ b/metrics_sdk/README.md @@ -15,6 +15,7 @@ Metrics is one of the core signals in OpenTelemetry. This package allows you to This gem does not have a full implementation of the Metrics SDK specification. The work is in progress. At this time, you should be able to: + * Create synchronous: * counters * up down counters @@ -26,6 +27,7 @@ At this time, you should be able to: * Use delta aggregation temporality We do not yet have support for: + * Asynchronous instruments * Cumulative aggregation temporality * Metrics Views @@ -41,7 +43,7 @@ Until the Ruby implementation of OpenTelemetry Metrics becomes stable, the funct Install the gems using: -``` +```sh gem install opentelemetry-metrics-sdk gem install opentelemetry-sdk ``` @@ -97,7 +99,6 @@ During this experimental stage, we're looking for lots of community feedback abo The `opentelemetry-metrics-sdk` gem is distributed under the Apache 2.0 license. See [LICENSE][license-github] for more information. - [metrics-sdk]: https://opentelemetry.io/docs/specs/otel/metrics/sdk/ [opentelemetry-home]: https://opentelemetry.io [bundler-home]: https://bundler.io diff --git a/propagator/b3/README.md b/propagator/b3/README.md index 721899fae5..5f850bf68d 100644 --- a/propagator/b3/README.md +++ b/propagator/b3/README.md @@ -20,7 +20,7 @@ This gem can be used with any OpenTelemetry SDK implementation. This can be the Install the gem using: -``` +```sh gem install opentelemetry-propagator-b3 ``` diff --git a/propagator/jaeger/README.md b/propagator/jaeger/README.md index 66191bd177..b7ccf15f18 100644 --- a/propagator/jaeger/README.md +++ b/propagator/jaeger/README.md @@ -19,7 +19,7 @@ This gem can be used with any OpenTelemetry SDK implementation. This can be the Install the gem using: -``` +```sh gem install opentelemetry-propagator-jaeger ``` diff --git a/registry/README.md b/registry/README.md index f18dc59aba..90aa678b6a 100644 --- a/registry/README.md +++ b/registry/README.md @@ -4,7 +4,7 @@ The instrumentation Registry contains information about available instrumentatio The Registry allows for instrumentation to avoid depending directly on a specific SDK implementation. -The SDK depends on the Registry, the instrumentation Base class depends on the Registry, and auto instrumentation libraries extend the instrumentation Base class. +The SDK depends on the Registry, the instrumentation Base class depends on the Registry, and auto instrumentation libraries extend the instrumentation Base class. The motivation for decoupling the Registry (and by extension the instrumentation) from a specific SDK implementation means that anyone can implement their own OpenTelemetry API compatible SDK, and they could continue to use community made instrumentation. diff --git a/sdk/README.md b/sdk/README.md index 97da0a9884..4efbb220b5 100644 --- a/sdk/README.md +++ b/sdk/README.md @@ -24,7 +24,7 @@ produce telemetry data should generally depend only on Install the gem using: -``` +```sh gem install opentelemetry-sdk ``` @@ -59,7 +59,7 @@ OpenTelemetry::SDK.configure # c.use 'OpenTelemetry::Instrumentation::Net::HTTP' # end # -# Note that the SimpleSpanExporter is not recommended for use in production. +# Note that the SimpleSpanProcessor is not recommended for use in production. # To start a trace you need to get a Tracer from the TracerProvider @@ -91,7 +91,6 @@ The OpenTelemetry Ruby gems are maintained by the OpenTelemetry-Ruby special int The `opentelemetry-sdk` gem is distributed under the Apache 2.0 license. See [LICENSE][license-github] for more information. - [opentelemetry-home]: https://opentelemetry.io [bundler-home]: https://bundler.io [repo-github]: https://github.com/open-telemetry/opentelemetry-ruby diff --git a/sdk_experimental/README.md b/sdk_experimental/README.md index cd6c999f13..6dd7017193 100644 --- a/sdk_experimental/README.md +++ b/sdk_experimental/README.md @@ -5,4 +5,3 @@ here: * `traceresponse` propagator (in [w3c `trace-context` editor's draft](https://w3c.github.io/trace-context/)) * Consistent Probability Sampler (marked as `experimental` in [opentelemetry-specification)](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/tracestate-probability-sampling.md)) - diff --git a/semantic_conventions/README.md b/semantic_conventions/README.md index 72bad0149f..4344a61d28 100644 --- a/semantic_conventions/README.md +++ b/semantic_conventions/README.md @@ -16,7 +16,7 @@ The `opentelemetry-semantic_conventions` gem provides auto-generated constants t Install the gem using: -``` +```sh gem install opentelemetry-semantic_conventions ``` @@ -45,4 +45,4 @@ The OpenTelemetry Ruby gems are maintained by the OpenTelemetry-Ruby special int The `opentelemetry-semantic_conventions` gem is distributed under the Apache 2.0 license. See LICENSE for more information. [discussions-url]: https://github.com/open-telemetry/opentelemetry-ruby/discussions -[semantic-conventions]: https://github.com/open-telemetry/opentelemetry-specification/tree/main/semantic_conventions +[semantic-conventions]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.20.0/semantic_conventions diff --git a/test_helpers/README.md b/test_helpers/README.md index 9b675e26cd..44d697f210 100644 --- a/test_helpers/README.md +++ b/test_helpers/README.md @@ -16,13 +16,12 @@ The `opentelemetry-test-helpers` gem is home to commonly used snippets of test c Install the gem using: -``` +```sh gem install opentelemetry-test-helpers ``` Or, if you use [bundler][bundler-home], include `opentelemetry-test-helpers` in your `Gemfile`. - ## How can I get involved? The `opentelemetry-test-helpers` gem source is [on github][repo-github], along with related gems including `opentelemetry-api`. @@ -33,12 +32,10 @@ The OpenTelemetry Ruby gems are maintained by the OpenTelemetry-Ruby special int The `opentelemetry-test-helpers` gem is distributed under the Apache 2.0 license. See [LICENSE][license-github] for more information. - [opentelemetry-home]: https://opentelemetry.io [bundler-home]: https://bundler.io [repo-github]: https://github.com/open-telemetry/opentelemetry-ruby [license-github]: https://github.com/open-telemetry/opentelemetry-ruby/blob/main/LICENSE -[examples-github]: https://github.com/open-telemetry/opentelemetry-ruby/tree/main/examples [ruby-sig]: https://github.com/open-telemetry/community#ruby-sig [community-meetings]: https://github.com/open-telemetry/community#community-meetings [discussions-url]: https://github.com/open-telemetry/opentelemetry-ruby/discussions