datadog-ci 1.14.0 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -2
- data/lib/datadog/ci/async_writer.rb +112 -0
- data/lib/datadog/ci/configuration/components.rb +36 -6
- data/lib/datadog/ci/configuration/settings.rb +17 -0
- data/lib/datadog/ci/contrib/activesupport/configuration/settings.rb +25 -0
- data/lib/datadog/ci/contrib/activesupport/ext.rb +14 -0
- data/lib/datadog/ci/contrib/activesupport/integration.rb +43 -0
- data/lib/datadog/ci/contrib/activesupport/logs_formatter.rb +41 -0
- data/lib/datadog/ci/contrib/activesupport/patcher.rb +50 -0
- data/lib/datadog/ci/contrib/lograge/configuration/settings.rb +25 -0
- data/lib/datadog/ci/contrib/lograge/ext.rb +14 -0
- data/lib/datadog/ci/contrib/lograge/integration.rb +43 -0
- data/lib/datadog/ci/contrib/lograge/log_subscriber.rb +41 -0
- data/lib/datadog/ci/contrib/lograge/patcher.rb +32 -0
- data/lib/datadog/ci/contrib/minitest/runner.rb +4 -1
- data/lib/datadog/ci/contrib/parallel_tests/cli.rb +84 -0
- data/lib/datadog/ci/contrib/parallel_tests/configuration/settings.rb +32 -0
- data/lib/datadog/ci/contrib/parallel_tests/ext.rb +16 -0
- data/lib/datadog/ci/contrib/parallel_tests/integration.rb +42 -0
- data/lib/datadog/ci/contrib/parallel_tests/patcher.rb +23 -0
- data/lib/datadog/ci/contrib/rspec/example.rb +7 -0
- data/lib/datadog/ci/contrib/rspec/example_group.rb +18 -8
- data/lib/datadog/ci/contrib/rspec/helpers.rb +18 -0
- data/lib/datadog/ci/contrib/rspec/runner.rb +2 -0
- data/lib/datadog/ci/contrib/semantic_logger/configuration/settings.rb +25 -0
- data/lib/datadog/ci/contrib/semantic_logger/ext.rb +14 -0
- data/lib/datadog/ci/contrib/semantic_logger/integration.rb +42 -0
- data/lib/datadog/ci/contrib/semantic_logger/logger.rb +32 -0
- data/lib/datadog/ci/contrib/semantic_logger/patcher.rb +32 -0
- data/lib/datadog/ci/ext/settings.rb +3 -0
- data/lib/datadog/ci/ext/test.rb +23 -2
- data/lib/datadog/ci/ext/transport.rb +2 -0
- data/lib/datadog/ci/git/local_repository.rb +1 -1
- data/lib/datadog/ci/git/tree_uploader.rb +9 -0
- data/lib/datadog/ci/logs/component.rb +46 -0
- data/lib/datadog/ci/logs/transport.rb +73 -0
- data/lib/datadog/ci/readonly_test_module.rb +28 -0
- data/lib/datadog/ci/readonly_test_session.rb +31 -0
- data/lib/datadog/ci/remote/component.rb +43 -16
- data/lib/datadog/ci/test.rb +10 -0
- data/lib/datadog/ci/test_management/component.rb +34 -1
- data/lib/datadog/ci/test_management/tests_properties.rb +2 -1
- data/lib/datadog/ci/test_optimisation/component.rb +31 -5
- data/lib/datadog/ci/test_retries/driver/retry_new.rb +1 -1
- data/lib/datadog/ci/test_session.rb +7 -1
- data/lib/datadog/ci/test_visibility/component.rb +82 -28
- data/lib/datadog/ci/test_visibility/context.rb +77 -29
- data/lib/datadog/ci/test_visibility/null_component.rb +7 -1
- data/lib/datadog/ci/test_visibility/store/{local.rb → fiber_local.rb} +1 -1
- data/lib/datadog/ci/test_visibility/store/{global.rb → process.rb} +23 -18
- data/lib/datadog/ci/test_visibility/transport.rb +1 -2
- data/lib/datadog/ci/transport/api/agentless.rb +8 -1
- data/lib/datadog/ci/transport/api/base.rb +4 -0
- data/lib/datadog/ci/transport/api/builder.rb +5 -1
- data/lib/datadog/ci/transport/api/evp_proxy.rb +4 -0
- data/lib/datadog/ci/transport/http.rb +1 -1
- data/lib/datadog/ci/utils/file_storage.rb +57 -0
- data/lib/datadog/ci/utils/stateful.rb +52 -0
- data/lib/datadog/ci/version.rb +1 -1
- data/lib/datadog/ci.rb +7 -3
- metadata +32 -6
- data/lib/datadog/ci/test_optimisation/coverage/writer.rb +0 -116
- data/lib/datadog/ci/test_visibility/capabilities.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4f7cf7ed07d7a4543498333996a19347f64010eef7900f53d5790ad6e4fe2aaf
|
4
|
+
data.tar.gz: 7b3ebdaaf30c557ac23f3720f72ef56ab1b9c1f9686e8f62dc597e3c938cfe35
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9412f518c4bba62d062448950f10b956abebe22e33680341454f60f67fd48c25b155d9e0ed3f7d378bcb33f21ee0fa586bee2ff03f3a2ad3f4b753a8a24bb36c
|
7
|
+
data.tar.gz: eb8710ab135550d9c26e1742aefb5ebb05b2c8a1f91e9175e44b0181c4934f1ff5453749820b8720e1febe5c79502e2489d46442f80c4836e56a394c931f7143
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,28 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.16.0] - 2025-04-15
|
4
|
+
|
5
|
+
|
6
|
+
### Added
|
7
|
+
|
8
|
+
* agentless logs submission for tests ([#306][])
|
9
|
+
* lograge support for agentless logs feature ([#308][])
|
10
|
+
* semantic_logger instrumentation for agentless logs feature ([#311][])
|
11
|
+
* retry reason "external" ([#312][])
|
12
|
+
|
13
|
+
## [1.15.0] - 2025-03-25
|
14
|
+
|
15
|
+
|
16
|
+
### Added
|
17
|
+
|
18
|
+
* parallel tests gem support ([#299][])
|
19
|
+
* implemented attempt to fix flow V2 ([#298][])
|
20
|
+
|
21
|
+
### Fixed
|
22
|
+
|
23
|
+
* Fix: prevent test impact analysis from skipping flaky tests that are attempted to be fixed ([#301][])
|
24
|
+
* Fix git commit message extraction to extract multiline commit messages correctly ([#300][])
|
25
|
+
|
3
26
|
## [1.14.0] - 2025-03-11
|
4
27
|
|
5
28
|
### Added
|
@@ -404,7 +427,9 @@ Currently test suite level visibility is not used by our instrumentation: it wil
|
|
404
427
|
|
405
428
|
- Ruby versions < 2.7 no longer supported ([#8][])
|
406
429
|
|
407
|
-
[Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v1.
|
430
|
+
[Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v1.16.0...main
|
431
|
+
[1.16.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.15.0...v1.16.0
|
432
|
+
[1.15.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.14.0...v1.15.0
|
408
433
|
[1.14.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.13.0...v1.14.0
|
409
434
|
[1.13.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.12.0...v1.13.0
|
410
435
|
[1.12.0]: https://github.com/DataDog/datadog-ci-rb/compare/v1.11.0...v1.12.0
|
@@ -579,4 +604,12 @@ Currently test suite level visibility is not used by our instrumentation: it wil
|
|
579
604
|
[#289]: https://github.com/DataDog/datadog-ci-rb/issues/289
|
580
605
|
[#292]: https://github.com/DataDog/datadog-ci-rb/issues/292
|
581
606
|
[#294]: https://github.com/DataDog/datadog-ci-rb/issues/294
|
582
|
-
[#295]: https://github.com/DataDog/datadog-ci-rb/issues/295
|
607
|
+
[#295]: https://github.com/DataDog/datadog-ci-rb/issues/295
|
608
|
+
[#298]: https://github.com/DataDog/datadog-ci-rb/issues/298
|
609
|
+
[#299]: https://github.com/DataDog/datadog-ci-rb/issues/299
|
610
|
+
[#300]: https://github.com/DataDog/datadog-ci-rb/issues/300
|
611
|
+
[#301]: https://github.com/DataDog/datadog-ci-rb/issues/301
|
612
|
+
[#306]: https://github.com/DataDog/datadog-ci-rb/issues/306
|
613
|
+
[#308]: https://github.com/DataDog/datadog-ci-rb/issues/308
|
614
|
+
[#311]: https://github.com/DataDog/datadog-ci-rb/issues/311
|
615
|
+
[#312]: https://github.com/DataDog/datadog-ci-rb/issues/312
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "datadog/core/workers/async"
|
4
|
+
require "datadog/core/workers/queue"
|
5
|
+
require "datadog/core/workers/polling"
|
6
|
+
|
7
|
+
require "datadog/core/buffer/cruby"
|
8
|
+
require "datadog/core/buffer/thread_safe"
|
9
|
+
|
10
|
+
require "datadog/core/environment/ext"
|
11
|
+
|
12
|
+
module Datadog
|
13
|
+
module CI
|
14
|
+
class AsyncWriter
|
15
|
+
include Core::Workers::Queue
|
16
|
+
include Core::Workers::Polling
|
17
|
+
|
18
|
+
attr_reader :transport
|
19
|
+
|
20
|
+
DEFAULT_BUFFER_MAX_SIZE = 10_000
|
21
|
+
DEFAULT_SHUTDOWN_TIMEOUT = 60
|
22
|
+
|
23
|
+
DEFAULT_INTERVAL = 3
|
24
|
+
|
25
|
+
def initialize(transport:, options: {})
|
26
|
+
@transport = transport
|
27
|
+
|
28
|
+
# Workers::Polling settings
|
29
|
+
self.enabled = options.fetch(:enabled, true)
|
30
|
+
|
31
|
+
# Workers::Async::Thread settings
|
32
|
+
self.fork_policy = Core::Workers::Async::Thread::FORK_POLICY_RESTART
|
33
|
+
|
34
|
+
# Workers::IntervalLoop settings
|
35
|
+
self.loop_base_interval = options[:interval] || DEFAULT_INTERVAL
|
36
|
+
self.loop_back_off_ratio = options[:back_off_ratio] if options.key?(:back_off_ratio)
|
37
|
+
self.loop_back_off_max = options[:back_off_max] if options.key?(:back_off_max)
|
38
|
+
|
39
|
+
@buffer_size = options.fetch(:buffer_size, DEFAULT_BUFFER_MAX_SIZE)
|
40
|
+
|
41
|
+
self.buffer = buffer_klass.new(@buffer_size)
|
42
|
+
|
43
|
+
@shutdown_timeout = options.fetch(:shutdown_timeout, DEFAULT_SHUTDOWN_TIMEOUT)
|
44
|
+
|
45
|
+
@stopped = false
|
46
|
+
end
|
47
|
+
|
48
|
+
def write(event)
|
49
|
+
return if @stopped
|
50
|
+
|
51
|
+
# Start worker thread. If the process has forked, it will trigger #after_fork to
|
52
|
+
# reconfigure the worker accordingly.
|
53
|
+
perform
|
54
|
+
|
55
|
+
enqueue(event)
|
56
|
+
end
|
57
|
+
|
58
|
+
def perform(*events)
|
59
|
+
responses = transport.send_events(events)
|
60
|
+
|
61
|
+
if responses.find(&:server_error?)
|
62
|
+
loop_back_off!
|
63
|
+
Datadog.logger.warn { "Encountered server error while sending events: #{responses}" }
|
64
|
+
end
|
65
|
+
|
66
|
+
nil
|
67
|
+
rescue => e
|
68
|
+
Datadog.logger.warn { "Error while sending events: #{e}" }
|
69
|
+
loop_back_off!
|
70
|
+
end
|
71
|
+
|
72
|
+
def stop(force_stop = false, timeout = @shutdown_timeout)
|
73
|
+
@stopped = true
|
74
|
+
|
75
|
+
buffer.close if running?
|
76
|
+
|
77
|
+
super
|
78
|
+
end
|
79
|
+
|
80
|
+
def enqueue(event)
|
81
|
+
buffer.push(event)
|
82
|
+
end
|
83
|
+
|
84
|
+
def dequeue
|
85
|
+
buffer.pop
|
86
|
+
end
|
87
|
+
|
88
|
+
def work_pending?
|
89
|
+
!buffer.empty?
|
90
|
+
end
|
91
|
+
|
92
|
+
def async?
|
93
|
+
true
|
94
|
+
end
|
95
|
+
|
96
|
+
def after_fork
|
97
|
+
# In multiprocess environments, forks will share the same buffer until its written to.
|
98
|
+
# A.K.A. copy-on-write. We don't want forks to write events generated from another process.
|
99
|
+
# Instead, we reset it after the fork. (Make sure any enqueue operations happen after this.)
|
100
|
+
self.buffer = buffer_klass.new(@buffer_size)
|
101
|
+
end
|
102
|
+
|
103
|
+
def buffer_klass
|
104
|
+
if Core::Environment::Ext::RUBY_ENGINE == "ruby"
|
105
|
+
Core::Buffer::CRuby
|
106
|
+
else
|
107
|
+
Core::Buffer::ThreadSafe
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -4,6 +4,8 @@ require "datadog/core/telemetry/ext"
|
|
4
4
|
|
5
5
|
require_relative "../ext/settings"
|
6
6
|
require_relative "../git/tree_uploader"
|
7
|
+
require_relative "../logs/component"
|
8
|
+
require_relative "../logs/transport"
|
7
9
|
require_relative "../remote/component"
|
8
10
|
require_relative "../remote/library_settings_client"
|
9
11
|
require_relative "../test_management/component"
|
@@ -11,7 +13,6 @@ require_relative "../test_management/null_component"
|
|
11
13
|
require_relative "../test_management/tests_properties"
|
12
14
|
require_relative "../test_optimisation/component"
|
13
15
|
require_relative "../test_optimisation/coverage/transport"
|
14
|
-
require_relative "../test_optimisation/coverage/writer"
|
15
16
|
require_relative "../test_retries/component"
|
16
17
|
require_relative "../test_retries/null_component"
|
17
18
|
require_relative "../test_visibility/component"
|
@@ -20,12 +21,13 @@ require_relative "../test_visibility/known_tests"
|
|
20
21
|
require_relative "../test_visibility/null_component"
|
21
22
|
require_relative "../test_visibility/serializers/factories/test_level"
|
22
23
|
require_relative "../test_visibility/serializers/factories/test_suite_level"
|
24
|
+
require_relative "../test_visibility/null_transport"
|
23
25
|
require_relative "../test_visibility/transport"
|
24
26
|
require_relative "../transport/adapters/telemetry_webmock_safe_adapter"
|
25
|
-
require_relative "../test_visibility/null_transport"
|
26
27
|
require_relative "../transport/api/builder"
|
27
28
|
require_relative "../utils/parsing"
|
28
29
|
require_relative "../utils/test_run"
|
30
|
+
require_relative "../async_writer"
|
29
31
|
require_relative "../worker"
|
30
32
|
|
31
33
|
module Datadog
|
@@ -33,7 +35,8 @@ module Datadog
|
|
33
35
|
module Configuration
|
34
36
|
# Adds CI behavior to Datadog trace components
|
35
37
|
module Components
|
36
|
-
attr_reader :test_visibility, :test_optimisation, :git_tree_upload_worker, :ci_remote, :test_retries,
|
38
|
+
attr_reader :test_visibility, :test_optimisation, :git_tree_upload_worker, :ci_remote, :test_retries,
|
39
|
+
:test_management, :agentless_logs_submission
|
37
40
|
|
38
41
|
def initialize(settings)
|
39
42
|
@test_optimisation = nil
|
@@ -56,6 +59,7 @@ module Datadog
|
|
56
59
|
|
57
60
|
@test_visibility&.shutdown!
|
58
61
|
@test_optimisation&.shutdown!
|
62
|
+
@agentless_logs_submission&.shutdown!
|
59
63
|
@git_tree_upload_worker&.stop
|
60
64
|
end
|
61
65
|
|
@@ -129,8 +133,11 @@ module Datadog
|
|
129
133
|
@test_visibility = TestVisibility::Component.new(
|
130
134
|
test_suite_level_visibility_enabled: !settings.ci.force_test_level_visibility,
|
131
135
|
logical_test_session_name: settings.ci.test_session_name,
|
132
|
-
known_tests_client: build_known_tests_client(settings, test_visibility_api)
|
136
|
+
known_tests_client: build_known_tests_client(settings, test_visibility_api),
|
137
|
+
context_service_uri: settings.ci.test_visibility_drb_server_uri
|
133
138
|
)
|
139
|
+
|
140
|
+
@agentless_logs_submission = build_agentless_logs_component(settings, test_visibility_api)
|
134
141
|
end
|
135
142
|
|
136
143
|
def build_test_optimisation(settings, test_visibility_api)
|
@@ -223,7 +230,7 @@ module Datadog
|
|
223
230
|
# nil means that coverage event will be ignored
|
224
231
|
return nil if api.nil? || settings.ci.discard_traces
|
225
232
|
|
226
|
-
|
233
|
+
AsyncWriter.new(
|
227
234
|
transport: TestOptimisation::Coverage::Transport.new(api: api)
|
228
235
|
)
|
229
236
|
end
|
@@ -255,6 +262,29 @@ module Datadog
|
|
255
262
|
)
|
256
263
|
end
|
257
264
|
|
265
|
+
def build_agentless_logs_component(settings, api)
|
266
|
+
if settings.ci.agentless_logs_submission_enabled && !settings.ci.agentless_mode_enabled
|
267
|
+
Datadog.logger.warn(
|
268
|
+
"Agentless logs submission is enabled but agentless mode is not enabled. " \
|
269
|
+
"Logs will not be submitted. " \
|
270
|
+
"Please make sure to set DD_CIVISIBILITY_AGENTLESS_ENABLED to true if you want to submit logs in agentless mode. " \
|
271
|
+
"Otherwise, set DD_AGENTLESS_LOG_SUBMISSION_ENABLED to 0 and use Datadog Agent to submit logs."
|
272
|
+
)
|
273
|
+
settings.ci.agentless_logs_submission_enabled = false
|
274
|
+
end
|
275
|
+
|
276
|
+
Logs::Component.new(
|
277
|
+
enabled: settings.ci.agentless_logs_submission_enabled,
|
278
|
+
writer: build_logs_writer(settings, api)
|
279
|
+
)
|
280
|
+
end
|
281
|
+
|
282
|
+
def build_logs_writer(settings, api)
|
283
|
+
return nil if api.nil? || settings.ci.discard_traces
|
284
|
+
|
285
|
+
AsyncWriter.new(transport: Logs::Transport.new(api: api), options: {buffer_size: 1024})
|
286
|
+
end
|
287
|
+
|
258
288
|
# fetch custom tags provided by the user in DD_TAGS env var
|
259
289
|
# with prefix test.configuration.
|
260
290
|
def custom_configuration(settings)
|
@@ -297,7 +327,7 @@ module Datadog
|
|
297
327
|
|
298
328
|
# patch gem's telemetry transport layer to use Net::HTTP instead of WebMock's Net::HTTP
|
299
329
|
Core::Telemetry::Http::Adapters::Net.include(CI::Transport::Adapters::TelemetryWebmockSafeAdapter)
|
300
|
-
rescue => e
|
330
|
+
rescue LoadError, StandardError => e
|
301
331
|
Datadog.logger.warn("Failed to patch Datadog gem's telemetry layer: #{e}")
|
302
332
|
end
|
303
333
|
end
|
@@ -128,12 +128,29 @@ module Datadog
|
|
128
128
|
o.default 20
|
129
129
|
end
|
130
130
|
|
131
|
+
option :agentless_logs_submission_enabled do |o|
|
132
|
+
o.type :bool
|
133
|
+
o.env CI::Ext::Settings::ENV_AGENTLESS_LOGS_SUBMISSION_ENABLED
|
134
|
+
o.default false
|
135
|
+
end
|
136
|
+
|
137
|
+
option :agentless_logs_submission_url do |o|
|
138
|
+
o.type :string, nilable: true
|
139
|
+
o.env CI::Ext::Settings::ENV_AGENTLESS_LOGS_SUBMISSION_URL
|
140
|
+
end
|
141
|
+
|
131
142
|
# internal only
|
132
143
|
option :discard_traces do |o|
|
133
144
|
o.type :bool
|
134
145
|
o.default false
|
135
146
|
end
|
136
147
|
|
148
|
+
# internal only
|
149
|
+
option :test_visibility_drb_server_uri do |o|
|
150
|
+
o.type :string, nilable: true
|
151
|
+
o.env CI::Ext::Settings::ENV_TEST_VISIBILITY_DRB_SERVER_URI
|
152
|
+
end
|
153
|
+
|
137
154
|
define_method(:instrument) do |integration_name, options = {}, &block|
|
138
155
|
return unless enabled
|
139
156
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../ext"
|
4
|
+
require_relative "../../settings"
|
5
|
+
require_relative "../../../utils/configuration"
|
6
|
+
|
7
|
+
module Datadog
|
8
|
+
module CI
|
9
|
+
module Contrib
|
10
|
+
module ActiveSupport
|
11
|
+
module Configuration
|
12
|
+
# Custom settings for the ActiveSupport integration
|
13
|
+
# @public_api
|
14
|
+
class Settings < Datadog::CI::Contrib::Settings
|
15
|
+
option :enabled do |o|
|
16
|
+
o.type :bool
|
17
|
+
o.env Ext::ENV_ENABLED
|
18
|
+
o.default true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../integration"
|
4
|
+
require_relative "configuration/settings"
|
5
|
+
require_relative "patcher"
|
6
|
+
|
7
|
+
module Datadog
|
8
|
+
module CI
|
9
|
+
module Contrib
|
10
|
+
module ActiveSupport
|
11
|
+
# Description of ActiveSupport integration
|
12
|
+
class Integration < Datadog::CI::Contrib::Integration
|
13
|
+
MINIMUM_VERSION = Gem::Version.new("5.0")
|
14
|
+
|
15
|
+
def version
|
16
|
+
Gem.loaded_specs["activesupport"]&.version
|
17
|
+
end
|
18
|
+
|
19
|
+
def loaded?
|
20
|
+
!defined?(::Rails).nil? && !defined?(::ActiveSupport).nil? && !defined?(::ActiveSupport::TaggedLogging).nil? &&
|
21
|
+
!defined?(::ActiveSupport::TaggedLogging::Formatter).nil?
|
22
|
+
end
|
23
|
+
|
24
|
+
def compatible?
|
25
|
+
super && version >= MINIMUM_VERSION
|
26
|
+
end
|
27
|
+
|
28
|
+
def late_instrument?
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
def new_configuration
|
33
|
+
Configuration::Settings.new
|
34
|
+
end
|
35
|
+
|
36
|
+
def patcher
|
37
|
+
Patcher
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module CI
|
5
|
+
module Contrib
|
6
|
+
module ActiveSupport
|
7
|
+
module LogsFormatter
|
8
|
+
def call(severity, timestamp, progname, msg)
|
9
|
+
# don't even construct an object for every log message if agentless logs submission is not enabled
|
10
|
+
return super unless datadog_logs_component.enabled
|
11
|
+
return super unless datadog_configuration[:enabled]
|
12
|
+
|
13
|
+
# additional precaution because we cannot use targeted prepend in Ruby 2.7, so method :tags_text might
|
14
|
+
# not be available (highly unlikely, but not unimaginable)
|
15
|
+
#
|
16
|
+
# (see Datadog::CI::Contrib::ActiveSupport::Patcher for explanation)
|
17
|
+
return super unless respond_to?(:tags_text)
|
18
|
+
|
19
|
+
message = "#{msg} #{tags_text}"
|
20
|
+
return super unless message.include?("dd.trace_id")
|
21
|
+
|
22
|
+
datadog_logs_component.write({
|
23
|
+
message: message,
|
24
|
+
level: severity
|
25
|
+
})
|
26
|
+
|
27
|
+
super
|
28
|
+
end
|
29
|
+
|
30
|
+
def datadog_logs_component
|
31
|
+
Datadog.send(:components).agentless_logs_submission
|
32
|
+
end
|
33
|
+
|
34
|
+
def datadog_configuration
|
35
|
+
Datadog.configuration.ci[:activesupport]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../patcher"
|
4
|
+
require_relative "logs_formatter"
|
5
|
+
|
6
|
+
module Datadog
|
7
|
+
module CI
|
8
|
+
module Contrib
|
9
|
+
module ActiveSupport
|
10
|
+
# Patcher enables patching of activesupport module
|
11
|
+
module Patcher
|
12
|
+
include Datadog::CI::Contrib::Patcher
|
13
|
+
|
14
|
+
module_function
|
15
|
+
|
16
|
+
def patch
|
17
|
+
unless datadog_logs_component.enabled
|
18
|
+
Datadog.logger.debug("Datadog logs submission is disabled, skipping activesupport patching")
|
19
|
+
return
|
20
|
+
end
|
21
|
+
|
22
|
+
unless ::Rails.logger.formatter.is_a?(::ActiveSupport::TaggedLogging::Formatter)
|
23
|
+
Datadog.logger.debug {
|
24
|
+
"Rails logger formatter is not an instance of ActiveSupport::TaggedLogging::Formatter, skipping activesupport patching. " \
|
25
|
+
"Formatter: #{::Rails.logger.formatter.class}"
|
26
|
+
}
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
30
|
+
# Before Ruby 3.0, prepending to a module did not change existing instances where this module was included
|
31
|
+
# It means that for Ruby 2.7 we have to patch formatter's class directly
|
32
|
+
#
|
33
|
+
# Context:
|
34
|
+
# - https://bugs.ruby-lang.org/issues/9573
|
35
|
+
# - https://rubyreferences.github.io/rubychanges/3.0.html#include-and-prepend-now-affects-modules-including-the-receiver
|
36
|
+
if RUBY_VERSION.start_with?("2.7")
|
37
|
+
Rails.logger.formatter.class.prepend(LogsFormatter)
|
38
|
+
else
|
39
|
+
::ActiveSupport::TaggedLogging::Formatter.prepend(LogsFormatter)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def datadog_logs_component
|
44
|
+
Datadog.send(:components).agentless_logs_submission
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../ext"
|
4
|
+
require_relative "../../settings"
|
5
|
+
require_relative "../../../utils/configuration"
|
6
|
+
|
7
|
+
module Datadog
|
8
|
+
module CI
|
9
|
+
module Contrib
|
10
|
+
module Lograge
|
11
|
+
module Configuration
|
12
|
+
# Custom settings for the Lograge integration
|
13
|
+
# @public_api
|
14
|
+
class Settings < Datadog::CI::Contrib::Settings
|
15
|
+
option :enabled do |o|
|
16
|
+
o.type :bool
|
17
|
+
o.env Ext::ENV_ENABLED
|
18
|
+
o.default true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../integration"
|
4
|
+
require_relative "configuration/settings"
|
5
|
+
require_relative "patcher"
|
6
|
+
|
7
|
+
module Datadog
|
8
|
+
module CI
|
9
|
+
module Contrib
|
10
|
+
module Lograge
|
11
|
+
# Description of Lograge integration
|
12
|
+
class Integration < Datadog::CI::Contrib::Integration
|
13
|
+
MINIMUM_VERSION = Gem::Version.new("0.14.0")
|
14
|
+
|
15
|
+
def version
|
16
|
+
Gem.loaded_specs["lograge"]&.version
|
17
|
+
end
|
18
|
+
|
19
|
+
def loaded?
|
20
|
+
!defined?(::Lograge).nil? && !defined?(::Lograge::LogSubscribers).nil? &&
|
21
|
+
!defined?(::Lograge::LogSubscribers::Base).nil?
|
22
|
+
end
|
23
|
+
|
24
|
+
def compatible?
|
25
|
+
super && version && version >= MINIMUM_VERSION
|
26
|
+
end
|
27
|
+
|
28
|
+
def late_instrument?
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
def new_configuration
|
33
|
+
Configuration::Settings.new
|
34
|
+
end
|
35
|
+
|
36
|
+
def patcher
|
37
|
+
Patcher
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module CI
|
5
|
+
module Contrib
|
6
|
+
module Lograge
|
7
|
+
module LogSubscriber
|
8
|
+
def self.included(base)
|
9
|
+
base.prepend(InstanceMethods)
|
10
|
+
end
|
11
|
+
|
12
|
+
module InstanceMethods
|
13
|
+
private
|
14
|
+
|
15
|
+
def before_format(data, payload)
|
16
|
+
return super unless datadog_logs_component.enabled
|
17
|
+
return super unless datadog_configuration[:enabled]
|
18
|
+
|
19
|
+
result = super
|
20
|
+
|
21
|
+
if result.fetch(:dd, {}).fetch(:trace_id, nil).nil?
|
22
|
+
Datadog.logger.debug { "Discarding uncorrelated log event: #{result.inspect}" }
|
23
|
+
return result
|
24
|
+
end
|
25
|
+
datadog_logs_component.write(result)
|
26
|
+
result
|
27
|
+
end
|
28
|
+
|
29
|
+
def datadog_logs_component
|
30
|
+
Datadog.send(:components).agentless_logs_submission
|
31
|
+
end
|
32
|
+
|
33
|
+
def datadog_configuration
|
34
|
+
Datadog.configuration.ci[:lograge]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../patcher"
|
4
|
+
require_relative "log_subscriber"
|
5
|
+
|
6
|
+
module Datadog
|
7
|
+
module CI
|
8
|
+
module Contrib
|
9
|
+
module Lograge
|
10
|
+
# Patcher enables patching of lograge module
|
11
|
+
module Patcher
|
12
|
+
include Datadog::CI::Contrib::Patcher
|
13
|
+
|
14
|
+
module_function
|
15
|
+
|
16
|
+
def patch
|
17
|
+
unless datadog_logs_component.enabled
|
18
|
+
Datadog.logger.debug("Datadog logs submission is disabled, skipping lograge patching")
|
19
|
+
return
|
20
|
+
end
|
21
|
+
|
22
|
+
::Lograge::LogSubscribers::Base.include(LogSubscriber)
|
23
|
+
end
|
24
|
+
|
25
|
+
def datadog_logs_component
|
26
|
+
Datadog.send(:components).agentless_logs_submission
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -27,7 +27,10 @@ module Datadog
|
|
27
27
|
CI::Ext::Test::TAG_FRAMEWORK_VERSION => datadog_integration.version.to_s
|
28
28
|
},
|
29
29
|
service: datadog_configuration[:service_name],
|
30
|
-
estimated_total_tests_count: tests_count
|
30
|
+
estimated_total_tests_count: tests_count,
|
31
|
+
# if minitest is being used with a parallel runner, then tests split will happen by example, not by test suite
|
32
|
+
# we need to always start/stop test suites in the parent process in this case
|
33
|
+
local_test_suites_mode: false
|
31
34
|
)
|
32
35
|
test_visibility_component.start_test_module(Ext::FRAMEWORK)
|
33
36
|
end
|