diff --git a/api/CHANGELOG.md b/api/CHANGELOG.md index 35c3e87ad..1cb9acd40 100644 --- a/api/CHANGELOG.md +++ b/api/CHANGELOG.md @@ -1,5 +1,9 @@ # Release History: opentelemetry-api +### v1.4.0 / 2024-08-27 + +* ADDED: Include backtrace first line for better debug info + ### v1.3.0 / 2024-07-24 * ADDED: Add add_link to span api/sdk diff --git a/api/lib/opentelemetry/version.rb b/api/lib/opentelemetry/version.rb index 009daf16b..86295b3a9 100644 --- a/api/lib/opentelemetry/version.rb +++ b/api/lib/opentelemetry/version.rb @@ -6,5 +6,5 @@ module OpenTelemetry ## Current OpenTelemetry version - VERSION = '1.3.0' + VERSION = '1.4.0' end diff --git a/exporter/otlp-http/lib/opentelemetry/exporter/otlp/http/trace_exporter.rb b/exporter/otlp-http/lib/opentelemetry/exporter/otlp/http/trace_exporter.rb index e71c1a945..f6f0ecd98 100644 --- a/exporter/otlp-http/lib/opentelemetry/exporter/otlp/http/trace_exporter.rb +++ b/exporter/otlp-http/lib/opentelemetry/exporter/otlp/http/trace_exporter.rb @@ -25,8 +25,7 @@ class TraceExporter # rubocop:disable Metrics/ClassLength # Default timeouts in seconds. KEEP_ALIVE_TIMEOUT = 30 RETRY_COUNT = 5 - WRITE_TIMEOUT_SUPPORTED = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.6') - private_constant(:KEEP_ALIVE_TIMEOUT, :RETRY_COUNT, :WRITE_TIMEOUT_SUPPORTED) + private_constant(:KEEP_ALIVE_TIMEOUT, :RETRY_COUNT) ERROR_MESSAGE_INVALID_HEADERS = 'headers must be a String with comma-separated URL Encoded UTF-8 k=v pairs or a Hash' private_constant(:ERROR_MESSAGE_INVALID_HEADERS) @@ -153,7 +152,7 @@ def send_bytes(bytes, timeout:) # rubocop:disable Metrics/MethodLength @http.open_timeout = remaining_timeout @http.read_timeout = remaining_timeout - @http.write_timeout = remaining_timeout if WRITE_TIMEOUT_SUPPORTED + @http.write_timeout = remaining_timeout @http.start unless @http.started? response = measure_request_duration { @http.request(request) } @@ -209,7 +208,7 @@ def send_bytes(bytes, timeout:) # rubocop:disable Metrics/MethodLength # Reset timeouts to defaults for the next call. @http.open_timeout = @timeout @http.read_timeout = @timeout - @http.write_timeout = @timeout if WRITE_TIMEOUT_SUPPORTED + @http.write_timeout = @timeout end def handle_redirect(location) diff --git a/exporter/otlp-metrics/CHANGELOG.md b/exporter/otlp-metrics/CHANGELOG.md index 94a2c1972..b42812d56 100644 --- a/exporter/otlp-metrics/CHANGELOG.md +++ b/exporter/otlp-metrics/CHANGELOG.md @@ -1 +1,5 @@ # Release History: opentelemetry-exporter-otlp-metrics + +### v0.1.0 / 2024-08-27 + +Initial release. diff --git a/exporter/otlp-metrics/opentelemetry-exporter-otlp-metrics.gemspec b/exporter/otlp-metrics/opentelemetry-exporter-otlp-metrics.gemspec index 571b3b203..0729f3e37 100644 --- a/exporter/otlp-metrics/opentelemetry-exporter-otlp-metrics.gemspec +++ b/exporter/otlp-metrics/opentelemetry-exporter-otlp-metrics.gemspec @@ -29,8 +29,8 @@ Gem::Specification.new do |spec| spec.add_dependency 'google-protobuf', '>= 3.18', '< 5.0' spec.add_dependency 'opentelemetry-api', '~> 1.1' spec.add_dependency 'opentelemetry-common', '~> 0.20' - spec.add_dependency 'opentelemetry-metrics-api', '~> 0.1.0' - spec.add_dependency 'opentelemetry-metrics-sdk', '~> 0.1.0' + spec.add_dependency 'opentelemetry-metrics-api', '~> 0.1' + spec.add_dependency 'opentelemetry-metrics-sdk', '~> 0.2' spec.add_dependency 'opentelemetry-sdk', '~> 1.2' spec.add_dependency 'opentelemetry-semantic_conventions' diff --git a/exporter/otlp/CHANGELOG.md b/exporter/otlp/CHANGELOG.md index 88ee03a7d..bd86c0313 100644 --- a/exporter/otlp/CHANGELOG.md +++ b/exporter/otlp/CHANGELOG.md @@ -1,5 +1,9 @@ # Release History: opentelemetry-exporter-otlp +### v0.29.0 / 2024-08-27 + +* ADDED: Add support for mutual TLS. + ### v0.28.1 / 2024-07-24 * ADDED: Improve SSL error logging. diff --git a/exporter/otlp/lib/opentelemetry/exporter/otlp/exporter.rb b/exporter/otlp/lib/opentelemetry/exporter/otlp/exporter.rb index 6083692ff..35754f1e9 100644 --- a/exporter/otlp/lib/opentelemetry/exporter/otlp/exporter.rb +++ b/exporter/otlp/lib/opentelemetry/exporter/otlp/exporter.rb @@ -28,8 +28,7 @@ class Exporter # rubocop:disable Metrics/ClassLength # Default timeouts in seconds. KEEP_ALIVE_TIMEOUT = 30 RETRY_COUNT = 5 - WRITE_TIMEOUT_SUPPORTED = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.6') - private_constant(:KEEP_ALIVE_TIMEOUT, :RETRY_COUNT, :WRITE_TIMEOUT_SUPPORTED) + private_constant(:KEEP_ALIVE_TIMEOUT, :RETRY_COUNT) ERROR_MESSAGE_INVALID_HEADERS = 'headers must be a String with comma-separated URL Encoded UTF-8 k=v pairs or a Hash' private_constant(:ERROR_MESSAGE_INVALID_HEADERS) @@ -153,7 +152,7 @@ def send_bytes(bytes, timeout:) # rubocop:disable Metrics/CyclomaticComplexity, @http.open_timeout = remaining_timeout @http.read_timeout = remaining_timeout - @http.write_timeout = remaining_timeout if WRITE_TIMEOUT_SUPPORTED + @http.write_timeout = remaining_timeout @http.start unless @http.started? response = measure_request_duration { @http.request(request) } @@ -213,7 +212,7 @@ def send_bytes(bytes, timeout:) # rubocop:disable Metrics/CyclomaticComplexity, # Reset timeouts to defaults for the next call. @http.open_timeout = @timeout @http.read_timeout = @timeout - @http.write_timeout = @timeout if WRITE_TIMEOUT_SUPPORTED + @http.write_timeout = @timeout end def handle_redirect(location) diff --git a/exporter/otlp/lib/opentelemetry/exporter/otlp/version.rb b/exporter/otlp/lib/opentelemetry/exporter/otlp/version.rb index b12e7e7de..fd3718066 100644 --- a/exporter/otlp/lib/opentelemetry/exporter/otlp/version.rb +++ b/exporter/otlp/lib/opentelemetry/exporter/otlp/version.rb @@ -8,7 +8,7 @@ module OpenTelemetry module Exporter module OTLP ## Current OpenTelemetry OTLP exporter version - VERSION = '0.28.1' + VERSION = '0.29.0' end end end diff --git a/exporter/zipkin/lib/opentelemetry/exporter/zipkin/exporter.rb b/exporter/zipkin/lib/opentelemetry/exporter/zipkin/exporter.rb index 43efbee2c..779df0022 100644 --- a/exporter/zipkin/lib/opentelemetry/exporter/zipkin/exporter.rb +++ b/exporter/zipkin/lib/opentelemetry/exporter/zipkin/exporter.rb @@ -24,8 +24,7 @@ class Exporter # rubocop:disable Metrics/ClassLength # Default timeouts in seconds. KEEP_ALIVE_TIMEOUT = 30 RETRY_COUNT = 5 - WRITE_TIMEOUT_SUPPORTED = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.6') - private_constant(:KEEP_ALIVE_TIMEOUT, :RETRY_COUNT, :WRITE_TIMEOUT_SUPPORTED) + private_constant(:KEEP_ALIVE_TIMEOUT, :RETRY_COUNT) def initialize(endpoint: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_ZIPKIN_ENDPOINT', default: 'http://localhost:9411/api/v2/spans'), headers: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPORTER_ZIPKIN_TRACES_HEADERS', 'OTEL_EXPORTER_ZIPKIN_HEADERS'), @@ -130,7 +129,7 @@ def send_spans(zipkin_spans, timeout: nil) # rubocop:disable Metrics/MethodLengt @http.open_timeout = remaining_timeout @http.read_timeout = remaining_timeout - @http.write_timeout = remaining_timeout if WRITE_TIMEOUT_SUPPORTED + @http.write_timeout = remaining_timeout @http.start unless @http.started? response = measure_request_duration { @http.request(request) } diff --git a/logs_sdk/lib/opentelemetry/sdk/logs/export.rb b/logs_sdk/lib/opentelemetry/sdk/logs/export.rb index 2565dbf85..414670e86 100644 --- a/logs_sdk/lib/opentelemetry/sdk/logs/export.rb +++ b/logs_sdk/lib/opentelemetry/sdk/logs/export.rb @@ -24,6 +24,8 @@ module Export end end +require_relative 'export/console_log_record_exporter' +require_relative 'export/in_memory_log_record_exporter' require_relative 'export/log_record_exporter' require_relative 'export/simple_log_record_processor' require_relative 'export/batch_log_record_processor' diff --git a/logs_sdk/lib/opentelemetry/sdk/logs/export/console_log_record_exporter.rb b/logs_sdk/lib/opentelemetry/sdk/logs/export/console_log_record_exporter.rb new file mode 100644 index 000000000..9f1af854d --- /dev/null +++ b/logs_sdk/lib/opentelemetry/sdk/logs/export/console_log_record_exporter.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module SDK + module Logs + module Export + # Outputs {LogRecordData} to the console. + # + # Potentially useful for exploratory purposes. + class ConsoleLogRecordExporter + def initialize + @stopped = false + end + + def export(log_records, timeout: nil) + return FAILURE if @stopped + + Array(log_records).each { |s| pp s } + + SUCCESS + end + + def force_flush(timeout: nil) + SUCCESS + end + + def shutdown(timeout: nil) + @stopped = true + SUCCESS + end + end + end + end + end +end diff --git a/logs_sdk/lib/opentelemetry/sdk/logs/export/in_memory_log_record_exporter.rb b/logs_sdk/lib/opentelemetry/sdk/logs/export/in_memory_log_record_exporter.rb new file mode 100644 index 000000000..10c181e12 --- /dev/null +++ b/logs_sdk/lib/opentelemetry/sdk/logs/export/in_memory_log_record_exporter.rb @@ -0,0 +1,104 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module SDK + module Logs + module Export + # A LogRecordExporter implementation that can be used to test OpenTelemetry integration. + # + # @example Usage in a test suite: + # class MyClassTest + # def setup + # @logger_provider = LoggerProvider.new + # @exporter = InMemoryLogRecordExporter.new + # @logger_provider.add_log_record_processor(SimpleLogRecordProcessor.new(@exporter)) + # end + # + # def test_emitted_log_records + # log_record = OpenTelemetry::SDK::Logs::LogRecord.new(body: 'log') + # @logger_provider.logger.on_emit(log_record, context) + # + # log_records = @exporter.emitted_log_records + + # refute_nil(log_records) + # assert_equal(1, log_records.size) + # assert_equal(log_records[0].body, 'log') + # end + # end + class InMemoryLogRecordExporter + # Returns a new instance of the {InMemoryLogRecordExporter}. + # + # @return a new instance of the {InMemoryLogRecordExporter}. + def initialize + @emitted_log_records = [] + @stopped = false + @mutex = Mutex.new + end + + # Returns a frozen array of the emitted {LogRecordData}s, represented by + # {io.opentelemetry.proto.trace.v1.LogRecord}. + # + # @return [Array] a frozen array of the emitted {LogRecordData}s. + def emitted_log_records + @mutex.synchronize do + @emitted_log_records.clone.freeze + end + end + + # Clears the internal collection of emitted {LogRecord}s. + # + # Does not reset the state of this exporter if already shutdown. + def reset + @mutex.synchronize do + @emitted_log_records.clear + end + end + + # Called to export {LogRecordData}s. + # + # @param [Enumerable] log_record_datas the list of {LogRecordData}s to be + # exported. + # @param [optional Numeric] timeout An optional timeout in seconds. + # @return [Integer] the result of the export, SUCCESS or + # FAILURE + def export(log_record_datas, timeout: nil) + @mutex.synchronize do + return FAILURE if @stopped + + @emitted_log_records.concat(log_record_datas.to_a) + end + SUCCESS + end + + # Called when {LoggerProvider#force_flush} is called, if this exporter is + # registered to a {LoggerProvider} object. + # + # @param [optional Numeric] timeout An optional timeout in seconds. + # @return [Integer] SUCCESS if no error occurred, FAILURE if a + # non-specific failure occurred, TIMEOUT if a timeout occurred. + def force_flush(timeout: nil) + SUCCESS + end + + # Called when {LoggerProvider#shutdown} is called, if this exporter is + # registered to a {LoggerProvider} object. + # + # @param [optional Numeric] timeout An optional timeout in seconds. + # @return [Integer] SUCCESS if no error occurred, FAILURE if a + # non-specific failure occurred, TIMEOUT if a timeout occurred. + def shutdown(timeout: nil) + @mutex.synchronize do + @emitted_log_records.clear + @stopped = true + end + SUCCESS + end + end + end + end + end +end diff --git a/logs_sdk/test/opentelemetry/sdk/logs/export/console_log_record_exporter_test.rb b/logs_sdk/test/opentelemetry/sdk/logs/export/console_log_record_exporter_test.rb new file mode 100644 index 000000000..b549bc944 --- /dev/null +++ b/logs_sdk/test/opentelemetry/sdk/logs/export/console_log_record_exporter_test.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require 'test_helper' + +describe OpenTelemetry::SDK::Logs::Export::ConsoleLogRecordExporter do + export = OpenTelemetry::SDK::Logs::Export + + let(:captured_stdout) { StringIO.new } + let(:log_record_data1) { Logs::LogRecordData.new } + let(:log_record_data2) { Logs::LogRecordData.new } + let(:log_records) { [log_record_data1, log_record_data2] } + let(:exporter) { export::ConsoleLogRecordExporter.new } + + before do + @original_stdout = $stdout + $stdout = captured_stdout + end + + after do + $stdout = @original_stdout + end + + it 'accepts an Array of LogRecordData as arg to #export and succeeds' do + assert_equal(export::SUCCESS, exporter.export(log_records)) + end + + it 'accepts an Enumerable of LogRecordData as arg to #export and succeeds' do + enumerable = Struct.new(:log_record0, :log_record1).new(log_records[0], log_records[1]) + + assert_equal(export::SUCCESS, exporter.export(enumerable)) + end + + it 'outputs to console (stdout)' do + exporter.export(log_records) + + assert_match(/#