Module: Buildkite::TestCollector
- Defined in:
- lib/buildkite/test_collector.rb,
lib/buildkite/test_collector.rb,
lib/buildkite/test_collector/otel.rb,
lib/buildkite/test_collector/error.rb,
lib/buildkite/test_collector/trace.rb,
lib/buildkite/test_collector/object.rb,
lib/buildkite/test_collector/tracer.rb,
lib/buildkite/test_collector/network.rb,
lib/buildkite/test_collector/session.rb,
lib/buildkite/test_collector/version.rb,
lib/buildkite/test_collector/uploader.rb,
lib/buildkite/test_collector/http_client.rb,
lib/buildkite/test_collector/otel/span_filter.rb,
lib/buildkite/test_collector/otel/child_span_forwarder.rb,
lib/buildkite/test_collector/otel/span_metrics_reporter.rb,
lib/buildkite/test_collector/otel/test_span_metrics_reporter.rb,
lib/buildkite/test_collector/otel/child_span_metrics_reporter.rb
Defined Under Namespace
Modules: CucumberPlugin, MinitestPlugin, OTel, RSpecPlugin Classes: CI, Error, HTTPClient, MinDurationSpanFilter, Network, Object, Session, TimeoutError, Trace, Tracer, UUID, Uploader
Constant Summary collapse
- DEFAULT_URL =
"https://analytics-api.buildkite.com/v1/uploads"- DEFAULT_UPLOAD_BATCH_SIZE =
500- VERSION =
"2.16.0"- NAME =
"buildkite-test_collector"
Class Attribute Summary collapse
-
.api_token ⇒ Object
Returns the value of attribute api_token.
-
.artifact_path ⇒ Object
Returns the value of attribute artifact_path.
-
.batch_size ⇒ Object
Returns the value of attribute batch_size.
-
.env ⇒ Object
Returns the value of attribute env.
-
.location_prefix ⇒ Object
Returns the value of attribute location_prefix.
-
.otel_enabled ⇒ Object
Returns the value of attribute otel_enabled.
-
.session ⇒ Object
Returns the value of attribute session.
-
.span_filters ⇒ Object
Returns the value of attribute span_filters.
-
.tags ⇒ Object
Returns the value of attribute tags.
-
.test_runner ⇒ Object
Returns the value of attribute test_runner.
-
.trace_min_duration ⇒ Object
Returns the value of attribute trace_min_duration.
-
.tracing_enabled ⇒ Object
Returns the value of attribute tracing_enabled.
-
.uploader ⇒ Object
Returns the value of attribute uploader.
-
.url ⇒ Object
Returns the value of attribute url.
Class Method Summary collapse
- .annotate(content) ⇒ Object
- .configure(hook:, token: nil, url: nil, tracing_enabled: true, artifact_path: nil, location_prefix: nil, env: {}, tags: {}, otel_enabled: false, otel_span_filter: nil) ⇒ Object
- .enable_tracing! ⇒ Object
- .hook_into(hook) ⇒ Object
- .otel_enabled? ⇒ Boolean
- .start_otel ⇒ Object
-
.tag_execution(key, value) ⇒ Object
Set a key=value tag on the current test execution.
Class Attribute Details
.api_token ⇒ Object
Returns the value of attribute api_token.
34 35 36 |
# File 'lib/buildkite/test_collector.rb', line 34 def api_token @api_token end |
.artifact_path ⇒ Object
Returns the value of attribute artifact_path.
39 40 41 |
# File 'lib/buildkite/test_collector.rb', line 39 def artifact_path @artifact_path end |
.batch_size ⇒ Object
Returns the value of attribute batch_size.
45 46 47 |
# File 'lib/buildkite/test_collector.rb', line 45 def batch_size @batch_size end |
.env ⇒ Object
Returns the value of attribute env.
42 43 44 |
# File 'lib/buildkite/test_collector.rb', line 42 def env @env end |
.location_prefix ⇒ Object
Returns the value of attribute location_prefix.
40 41 42 |
# File 'lib/buildkite/test_collector.rb', line 40 def location_prefix @location_prefix end |
.otel_enabled ⇒ Object
Returns the value of attribute otel_enabled.
44 45 46 |
# File 'lib/buildkite/test_collector.rb', line 44 def otel_enabled @otel_enabled end |
.session ⇒ Object
Returns the value of attribute session.
37 38 39 |
# File 'lib/buildkite/test_collector.rb', line 37 def session @session end |
.span_filters ⇒ Object
Returns the value of attribute span_filters.
47 48 49 |
# File 'lib/buildkite/test_collector.rb', line 47 def span_filters @span_filters end |
.tags ⇒ Object
Returns the value of attribute tags.
43 44 45 |
# File 'lib/buildkite/test_collector.rb', line 43 def @tags end |
.test_runner ⇒ Object
Returns the value of attribute test_runner.
41 42 43 |
# File 'lib/buildkite/test_collector.rb', line 41 def test_runner @test_runner end |
.trace_min_duration ⇒ Object
Returns the value of attribute trace_min_duration.
46 47 48 |
# File 'lib/buildkite/test_collector.rb', line 46 def trace_min_duration @trace_min_duration end |
.tracing_enabled ⇒ Object
Returns the value of attribute tracing_enabled.
38 39 40 |
# File 'lib/buildkite/test_collector.rb', line 38 def tracing_enabled @tracing_enabled end |
.uploader ⇒ Object
Returns the value of attribute uploader.
36 37 38 |
# File 'lib/buildkite/test_collector.rb', line 36 def uploader @uploader end |
.url ⇒ Object
Returns the value of attribute url.
35 36 37 |
# File 'lib/buildkite/test_collector.rb', line 35 def url @url end |
Class Method Details
.annotate(content) ⇒ Object
156 157 158 159 160 161 162 |
# File 'lib/buildkite/test_collector.rb', line 156 def self.annotate(content) return Buildkite::TestCollector::OTel.annotate(content) if otel_enabled? tracer = Buildkite::TestCollector::Uploader.tracer tracer&.enter("annotation", **{ content: content }) tracer&.leave end |
.configure(hook:, token: nil, url: nil, tracing_enabled: true, artifact_path: nil, location_prefix: nil, env: {}, tags: {}, otel_enabled: false, otel_span_filter: nil) ⇒ Object
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/buildkite/test_collector.rb', line 50 def self.configure(hook:, token: nil, url: nil, tracing_enabled: true, artifact_path: nil, location_prefix: nil, env: {}, tags: {}, otel_enabled: false, otel_span_filter: nil) # A filter that raises at runtime fails open, but an object that cannot be # called at all is a configuration mistake worth surfacing immediately. unless otel_span_filter.nil? || otel_span_filter.respond_to?(:call) raise ArgumentError, "otel_span_filter must respond to #call" end self.api_token = (token || ENV["BUILDKITE_ANALYTICS_TOKEN"])&.strip self.url = url || ENV["BUILDKITE_ANALYTICS_ENDPOINT"] || DEFAULT_URL self.tracing_enabled = tracing_enabled self.artifact_path = artifact_path self.location_prefix = location_prefix || ENV["BUILDKITE_ANALYTICS_LOCATION_PREFIX"] self.test_runner = hook.to_s self.env = env self. = worker_id_tag.merge() if otel_enabled && test_runner != "rspec" warn "[buildkite-test_collector] otel_enabled is only supported with the rspec hook, " \ "not #{test_runner}; #{json_fallback_outcome}" otel_enabled = false end # Without a credential there is nothing to submit; stay quiet like the # JSON path (Uploader.upload skips the request without a token) rather # than warn a developer running the suite locally. if otel_enabled otel_token = Buildkite::TestCollector::OTel.api_token || api_token otel_enabled = false if otel_token.nil? end self.otel_enabled = otel_enabled self.batch_size = ENV.fetch("BUILDKITE_ANALYTICS_UPLOAD_BATCH_SIZE") { DEFAULT_UPLOAD_BATCH_SIZE }.to_i trace_min_ms_string = ENV["BUILDKITE_ANALYTICS_TRACE_MIN_MS"] self.trace_min_duration = if trace_min_ms_string && !trace_min_ms_string.empty? Float(trace_min_ms_string) / 1000 end self.span_filters = [] unless self.trace_min_duration.nil? self.span_filters << MinDurationSpanFilter.new(self.trace_min_duration) end # Defer OTel setup until RSpec's before(:suite), after application and support files have loaded. @otel_options = if otel_enabled? { endpoint: Buildkite::TestCollector::OTel.endpoint, api_token: otel_token, run_env: Buildkite::TestCollector::CI.env, span_filter: otel_span_filter, # Include the automatic worker tag alongside caller-supplied tags. tags: self., } end self.hook_into(hook) enable_tracing! if test_runner == "rspec" && !otel_enabled? end |
.enable_tracing! ⇒ Object
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/buildkite/test_collector.rb', line 176 def self.enable_tracing! return unless self.tracing_enabled Buildkite::TestCollector::Network.configure Buildkite::TestCollector::Object.configure return unless defined?(ActiveSupport) require "active_support/notifications" return if @active_support_tracing_enabled ActiveSupport::Notifications.subscribe("sql.active_record") do |name, start, finish, id, payload| Buildkite::TestCollector::Uploader.tracer&.backfill(:sql, finish - start, **{ query: payload[:sql] }) end @active_support_tracing_enabled = true end |
.hook_into(hook) ⇒ Object
137 138 139 140 141 142 |
# File 'lib/buildkite/test_collector.rb', line 137 def self.hook_into(hook) file = "test_collector/library_hooks/#{hook}" require_relative file rescue LoadError raise ArgumentError.new("#{hook.inspect} is not a supported Buildkite Analytics Test library hook.") end |
.otel_enabled? ⇒ Boolean
133 134 135 |
# File 'lib/buildkite/test_collector.rb', line 133 def self.otel_enabled? !!otel_enabled end |
.start_otel ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/buildkite/test_collector.rb', line 105 def self.start_otel = @otel_options @otel_options = nil return unless Buildkite::TestCollector::OTel.configure!(**) return if Buildkite::TestCollector::OTel.enabled? # Nothing has run yet, so the legacy path can still cover the whole # suite: the Reporter, per-example tracer, and artifact all read # otel_enabled? lazily. warn "[buildkite-test_collector] otel_enabled is set, but OpenTelemetry could not be configured " \ "(see the warning above); #{json_fallback_outcome}" self.otel_enabled = false enable_tracing! end |
.tag_execution(key, value) ⇒ Object
Set a key=value tag on the current test execution.
165 166 167 168 169 170 171 172 173 174 |
# File 'lib/buildkite/test_collector.rb', line 165 def self.tag_execution(key, value) = Thread.current[:_buildkite_tags] raise "_buildkite_tags not available" unless unless key.is_a?(String) && value.is_a?(String) raise ArgumentError, "tag key and value expected string" end [key] = value end |