Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEBUG-2334 Add Debugger component #3640

Merged
merged 4 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/datadog.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
# Load other products (must follow tracing)
require_relative 'datadog/profiling'
require_relative 'datadog/appsec'
require_relative 'datadog/debugger'
require_relative 'datadog/kit'
3 changes: 3 additions & 0 deletions lib/datadog/core/configuration/components.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
require_relative '../../tracing/component'
require_relative '../../profiling/component'
require_relative '../../appsec/component'
require_relative '../../debugger/component'

module Datadog
module Core
Expand Down Expand Up @@ -80,6 +81,7 @@ def build_telemetry(settings, agent_settings, logger)
:runtime_metrics,
:telemetry,
:tracer,
:debugger,
:appsec

def initialize(settings)
Expand All @@ -105,6 +107,7 @@ def initialize(settings)
@health_metrics = self.class.build_health_metrics(settings)
@telemetry = self.class.build_telemetry(settings, agent_settings, logger)
@appsec = Datadog::AppSec::Component.build_appsec_component(settings)
@debugger = Datadog::Debugger::Component.build(settings)

self.class.configure_tracing(settings)
end
Expand Down
19 changes: 19 additions & 0 deletions lib/datadog/debugger.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

require_relative 'debugger/component'
require_relative 'debugger/configuration'
require_relative 'debugger/extensions'

module Datadog
# Namespace for Datadog Debugger instrumentation
module Debugger
class << self
def enabled?
Datadog.configuration.debugger.enabled
end
end

# Expose Debugger to global shared objects
Extensions.activate!
end
end
18 changes: 18 additions & 0 deletions lib/datadog/debugger/component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

module Datadog
module Debugger
# Core-pluggable component for Debugger
class Component
class << self
def build(settings)
return unless settings.respond_to?(:debugger) && settings.debugger.enabled

new
end
end

def shutdown!(replacement = nil); end
end
end
end
11 changes: 11 additions & 0 deletions lib/datadog/debugger/configuration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

module Datadog
module Debugger
# Configuration for Debugger
module Configuration
end
end
end

require_relative 'configuration/settings'
27 changes: 27 additions & 0 deletions lib/datadog/debugger/configuration/settings.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

module Datadog
module Debugger
module Configuration
# Settings
module Settings
def self.extended(base)
base = base.singleton_class unless base.is_a?(Class)
add_settings!(base)
end

def self.add_settings!(base)
base.class_eval do
settings :debugger do
option :enabled do |o|
o.type :bool
o.env 'DD_DYNAMIC_INSTRUMENTATION_ENABLED'
o.default false
end
end
end
end
end
end
end
end
15 changes: 15 additions & 0 deletions lib/datadog/debugger/extensions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

require_relative 'configuration'

module Datadog
module Debugger
# Extends Datadog tracing with Debugger features
module Extensions
# Inject Debugger into global objects.
def self.activate!
Core::Configuration::Settings.extend(Configuration::Settings)
end
end
end
end
8 changes: 8 additions & 0 deletions sig/datadog/core/configuration/settings.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ module Datadog
def templates: () -> _TemplatesBlock
end

interface _Debugger
def enabled: () -> bool

def enabled=: (bool) -> void
end

interface _TemplatesBlock
def html=: (::String) -> void

Expand Down Expand Up @@ -82,6 +88,8 @@ module Datadog

def appsec: (?untyped? options) -> Datadog::Core::Configuration::Settings::_AppSec

def debugger: (?untyped? options) -> Datadog::Core::Configuration::Settings::_Debugger

def remote: (?untyped? options) -> Datadog::Core::Configuration::Settings::_Remote
end
end
Expand Down
5 changes: 5 additions & 0 deletions sig/datadog/debugger.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module Datadog
module Debugger
def self.enabled?: () -> bool
end
end
11 changes: 11 additions & 0 deletions sig/datadog/debugger/component.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module Datadog
module Debugger
class Component
def self.build: (Datadog::Core::Configuration::Settings settings) -> Datadog::Debugger::Component?

private

def shutdown!: () -> untyped
end
end
end
6 changes: 6 additions & 0 deletions sig/datadog/debugger/configuration.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module Datadog
module Debugger
module Configuration
end
end
end
19 changes: 19 additions & 0 deletions sig/datadog/debugger/configuration/settings.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module Datadog
module Debugger
module Configuration
# Settings
module Settings
extend Datadog::Core::Configuration::Base::ClassMethods
include Datadog::Core::Configuration::Base::InstanceMethods
extend Datadog::Core::Configuration::Options::ClassMethods
include Datadog::Core::Configuration::Options::InstanceMethods

def self.extended: (untyped base) -> untyped

def self.add_settings!: (untyped base) -> untyped

def self.enabled: -> bool
end
end
end
end
7 changes: 7 additions & 0 deletions sig/datadog/debugger/extensions.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module Datadog
module Debugger
module Extensions
def self.activate!: () -> untyped
end
end
end
4 changes: 4 additions & 0 deletions spec/datadog/core/configuration/components_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,7 @@
expect(components.tracer).to receive(:shutdown!)
expect(components.remote).to receive(:shutdown!) unless components.remote.nil?
expect(components.profiler).to receive(:shutdown!) unless components.profiler.nil?
expect(components.debugger).to receive(:shutdown!) unless components.debugger.nil?
expect(components.appsec).to receive(:shutdown!) unless components.appsec.nil?
expect(components.runtime_metrics).to receive(:stop)
.with(true, close_metrics: false)
Expand All @@ -1104,6 +1105,7 @@
let(:profiler) { Datadog::Profiling.supported? ? instance_double(Datadog::Profiling::Profiler) : nil }
let(:remote) { instance_double(Datadog::Core::Remote::Component) }
let(:appsec) { instance_double(Datadog::AppSec::Component) }
let(:debugger) { instance_double(Datadog::Debugger::Component) }
let(:runtime_metrics_worker) { instance_double(Datadog::Core::Workers::RuntimeMetrics, metrics: runtime_metrics) }
let(:runtime_metrics) { instance_double(Datadog::Core::Runtime::Metrics, statsd: statsd) }
let(:health_metrics) { instance_double(Datadog::Core::Diagnostics::Health::Metrics, statsd: statsd) }
Expand All @@ -1114,6 +1116,7 @@
allow(replacement).to receive(:tracer).and_return(tracer)
allow(replacement).to receive(:profiler).and_return(profiler)
allow(replacement).to receive(:appsec).and_return(appsec)
allow(replacement).to receive(:debugger).and_return(debugger)
allow(replacement).to receive(:remote).and_return(remote)
allow(replacement).to receive(:runtime_metrics).and_return(runtime_metrics_worker)
allow(replacement).to receive(:health_metrics).and_return(health_metrics)
Expand All @@ -1128,6 +1131,7 @@
expect(components.tracer).to receive(:shutdown!)
expect(components.profiler).to receive(:shutdown!) unless components.profiler.nil?
expect(components.appsec).to receive(:shutdown!) unless components.appsec.nil?
expect(components.debugger).to receive(:shutdown!) unless components.debugger.nil?
expect(components.runtime_metrics).to receive(:stop)
.with(true, close_metrics: false)
expect(components.runtime_metrics.metrics.statsd).to receive(:close)
Expand Down
29 changes: 29 additions & 0 deletions spec/datadog/debugger/component_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require 'datadog/debugger/component'

RSpec.describe Datadog::Debugger::Component do
describe '.build' do
let(:settings) do
settings = Datadog::Core::Configuration::Settings.new
settings.debugger.enabled = debugger_enabled
settings
end

context 'when debugger is enabled' do
let(:debugger_enabled) { true }

it 'returns a Datadog::Debugger::Component instance' do
component = described_class.build(settings)
expect(component).to be_a(described_class)
end
end

context 'when debugger is disabled' do
let(:debugger_enabled) { false }

it 'returns nil' do
component = described_class.build(settings)
expect(component).to be nil
end
end
end
end
45 changes: 45 additions & 0 deletions spec/datadog/debugger/configuration/settings_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
require 'spec_helper'

RSpec.describe Datadog::Debugger::Configuration::Settings do
subject(:settings) { Datadog::Core::Configuration::Settings.new }

describe 'debugger' do
describe '#enabled' do
subject(:enabled) { settings.debugger.enabled }

context 'when DD_DYNAMIC_INSTRUMENTATION_ENABLED' do
around do |example|
ClimateControl.modify('DD_DYNAMIC_INSTRUMENTATION_ENABLED' => debugger_enabled) do
example.run
end
end

context 'is not defined' do
let(:debugger_enabled) { nil }

it { is_expected.to eq false }
end

context 'is defined' do
let(:debugger_enabled) { 'true' }

it { is_expected.to eq(true) }
end
end
end

describe '#enabled=' do
subject(:set_debugger_enabled) { settings.debugger.enabled = debugger_enabled }

[true, false].each do |value|
context "when given #{value}" do
let(:debugger_enabled) { value }

before { set_debugger_enabled }

it { expect(settings.debugger.enabled).to eq(value) }
end
end
end
end
end
Loading