diff --git a/examples/metrics_sdk/README.md b/examples/metrics_sdk/README.md index 3ba206d783..427a39fb24 100644 --- a/examples/metrics_sdk/README.md +++ b/examples/metrics_sdk/README.md @@ -36,8 +36,8 @@ receivers: # Default endpoints: 0.0.0.0:4317 for gRPC and 0.0.0.0:4318 for HTTP exporters: - logging: - loglevel: debug + debug: + verbosity: detailed processors: batch: @@ -47,11 +47,11 @@ service: traces: receivers: [otlp] processors: [batch] - exporters: [logging] + exporters: [debug] metrics: receivers: [otlp] processors: [batch] - exporters: [logging] + exporters: [debug] ``` 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/). diff --git a/examples/otel-collector/.env b/examples/otel-collector/.env index d9c19232cd..2a845851e9 100644 --- a/examples/otel-collector/.env +++ b/examples/otel-collector/.env @@ -1,2 +1,2 @@ -OTELCOL_IMG=otel/opentelemetry-collector-contrib:0.35.0 +OTELCOL_IMG=otel/opentelemetry-collector-contrib:0.109.0 OTELCOL_ARGS= diff --git a/examples/otel-collector/otel-collector-config.yaml b/examples/otel-collector/otel-collector-config.yaml index 997fc86aa6..9484b84b91 100644 --- a/examples/otel-collector/otel-collector-config.yaml +++ b/examples/otel-collector/otel-collector-config.yaml @@ -3,17 +3,19 @@ receivers: otlp: protocols: http: + endpoint: 0.0.0.0:4318 exporters: - logging: + debug: zipkin: endpoint: "http://zipkin-all-in-one:9411/api/v2/spans" format: proto - jaeger: - endpoint: jaeger-all-in-one:14250 - insecure: true + otlp: + endpoint: jaeger-all-in-one:4317 + tls: + insecure: true processors: batch: @@ -23,8 +25,8 @@ service: traces: receivers: [otlp] processors: [batch] - exporters: [logging, zipkin, jaeger] + exporters: [debug, zipkin, otlp] metrics: receivers: [otlp] processors: [batch] - exporters: [logging] + exporters: [debug] 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 64e81477a3..a7ed0c3620 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 @@ -188,19 +188,19 @@ def to_log_record_data it 'removes the older log records from the batch if full' do processor = BatchLogRecordProcessor.new(TestExporter.new, max_queue_size: 1, max_export_batch_size: 1) - older_log_record = TestLogRecord.new - newer_log_record = TestLogRecord.new - newest_log_record = TestLogRecord.new + # Don't actually try to export, we're looking at the log records array + processor.stub(:work, nil) do + older_log_record = TestLogRecord.new + newest_log_record = TestLogRecord.new - processor.on_emit(older_log_record, mock_context) - processor.on_emit(newer_log_record, mock_context) - processor.on_emit(newest_log_record, mock_context) + processor.on_emit(older_log_record, mock_context) + processor.on_emit(newest_log_record, mock_context) - records = processor.instance_variable_get(:@log_records) + records = processor.instance_variable_get(:@log_records) - assert_includes(records, newest_log_record) - refute_includes(records, newer_log_record) - refute_includes(records, older_log_record) + assert_includes(records, newest_log_record) + refute_includes(records, older_log_record) + end end it 'logs a warning if a log record was emitted after the buffer is full' do @@ -469,18 +469,21 @@ def shutdown(timeout: nil) let(:processor) { BatchLogRecordProcessor.new(exporter) } it 'reports export failures' do - mock_logger = Minitest::Mock.new - mock_logger.expect(:error, nil, [/Unable to export/]) - mock_logger.expect(:error, nil, [/Result code: 1/]) - mock_logger.expect(:error, nil, [/unexpected error in .*\#export_batch/]) - - OpenTelemetry.stub(:logger, mock_logger) do - log_records = [TestLogRecord.new, TestLogRecord.new, TestLogRecord.new, TestLogRecord.new] - log_records.each { |log_record| processor.on_emit(log_record, mock_context) } - processor.shutdown - end + # skip the work method's behavior, we rely on shutdown to get us to the failures + processor.stub(:work, nil) do + mock_logger = Minitest::Mock.new + mock_logger.expect(:error, nil, [/Unable to export/]) + mock_logger.expect(:error, nil, [/Result code: 1/]) + mock_logger.expect(:error, nil, [/unexpected error in .*\#export_batch/]) + + OpenTelemetry.stub(:logger, mock_logger) do + log_records = [TestLogRecord.new, TestLogRecord.new, TestLogRecord.new, TestLogRecord.new] + log_records.each { |log_record| processor.on_emit(log_record, mock_context) } + processor.shutdown + end - mock_logger.verify + mock_logger.verify + end end end diff --git a/sdk/lib/opentelemetry/sdk/trace/span.rb b/sdk/lib/opentelemetry/sdk/trace/span.rb index 274ac4c24d..c1f32657f8 100644 --- a/sdk/lib/opentelemetry/sdk/trace/span.rb +++ b/sdk/lib/opentelemetry/sdk/trace/span.rb @@ -271,6 +271,9 @@ def finish(end_timestamp: nil) return self end @end_timestamp = relative_timestamp(end_timestamp) + @span_processors.each do |processor| + processor.on_finishing(self) if processor.respond_to?(:on_finishing) + end @attributes = validated_attributes(@attributes).freeze @events.freeze @links.freeze diff --git a/sdk/lib/opentelemetry/sdk/trace/span_processor.rb b/sdk/lib/opentelemetry/sdk/trace/span_processor.rb index f1874f6504..2a60c3ba53 100644 --- a/sdk/lib/opentelemetry/sdk/trace/span_processor.rb +++ b/sdk/lib/opentelemetry/sdk/trace/span_processor.rb @@ -23,6 +23,24 @@ class SpanProcessor # started span. def on_start(span, parent_context); end + # The on_finishing method is an experimental feature and may have breaking changes. + # The OpenTelemetry specification defines it as "On Ending". As `end` is a reserved + # keyword in Ruby, we are using `on_finishing` instead. + # + # Called when a {Span} is ending, after the end timestamp has been set + # but before span becomes immutable. This allows for updating the span + # by setting attributes or adding links and events. + # + # This method is called synchronously and should not block the current + # thread nor throw exceptions. + # + # This method is optional on the Span Processor interface. It will only + # get called if it exists within the processor. + # + # @param [Span] span the {Span} that just is ending (still mutable). + # @return [void] + def on_finishing(span); end + # Called when a {Span} is ended, if the {Span#recording?} # returns true. # diff --git a/sdk/test/opentelemetry/sdk/trace/span_processor_test.rb b/sdk/test/opentelemetry/sdk/trace/span_processor_test.rb index 262ad53b92..2bfc1532ba 100644 --- a/sdk/test/opentelemetry/sdk/trace/span_processor_test.rb +++ b/sdk/test/opentelemetry/sdk/trace/span_processor_test.rb @@ -15,6 +15,10 @@ processor.on_start(span, context) end + it 'implements #on_finishing' do + processor.on_finishing(span) + end + it 'implements #on_finish' do processor.on_finish(span) end