Module: Datadog::DI Private

Defined in:
lib/datadog/di.rb,
lib/datadog/di/error.rb,
lib/datadog/di/probe.rb,
lib/datadog/di/utils.rb,
lib/datadog/di/remote.rb,
lib/datadog/di/redactor.rb,
lib/datadog/di/component.rb,
lib/datadog/di/transport.rb,
lib/datadog/di/extensions.rb,
lib/datadog/di/serializer.rb,
lib/datadog/di/code_tracker.rb,
lib/datadog/di/instrumenter.rb,
lib/datadog/di/configuration.rb,
lib/datadog/di/probe_builder.rb,
lib/datadog/di/probe_manager.rb,
lib/datadog/di/probe_notifier_worker.rb,
lib/datadog/di/configuration/settings.rb,
lib/datadog/di/probe_notification_builder.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Namespace for Datadog dynamic instrumentation.

Defined Under Namespace

Modules: Configuration, Extensions, ProbeBuilder, Remote, Utils Classes: CodeTracker, Component, Error, Instrumenter, Probe, ProbeManager, ProbeNotificationBuilder, ProbeNotifierWorker, Redactor, Serializer, Transport

Constant Summary collapse

LOCK =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Mutex.new

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.code_trackerObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



52
53
54
# File 'lib/datadog/di.rb', line 52

def code_tracker
  @code_tracker
end

Class Method Details

.activate_trackingObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Activates code tracking if possible.

This method does nothing if invoked in an environment that does not implement required trace points for code tracking (MRI Ruby < 2.6, JRuby) and rescues any exceptions that may be raised by downstream DI code.



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/datadog/di.rb', line 73

def activate_tracking
  # :script_compiled trace point was added in Ruby 2.6.
  return unless RUBY_VERSION >= '2.6'

  begin
    # Activate code tracking by default because line trace points will not work
    # without it.
    Datadog::DI.activate_tracking!
  rescue => exc
    if defined?(Datadog.logger)
      Datadog.logger.warn("Failed to activate code tracking for DI: #{exc.class}: #{exc}")
    else
      # We do not have Datadog logger potentially because DI code tracker is
      # being loaded early in application boot process and the rest of datadog
      # wasn't loaded yet. Output to standard error.
      warn("Failed to activate code tracking for DI: #{exc.class}: #{exc}")
    end
  end
end

.activate_tracking!Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Activates code tracking. Normally this method should be called when the application starts. If instrumenting third-party code, code tracking needs to be enabled before the third-party libraries are loaded. If you definitely will not be instrumenting third-party libraries, activating tracking after third-party libraries have been loaded may improve lookup performance.

TODO test that activating tracker multiple times preserves existing mappings in the registry



63
64
65
# File 'lib/datadog/di.rb', line 63

def activate_tracking!
  (@code_tracker ||= CodeTracker.new).start
end

.add_current_component(component) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

To avoid potential races with DI::Component being added and removed, we maintain a list of the components. Normally the list should contain either zero or one component depending on whether DI is enabled in Datadog configuration. However, if a new instance of DI::Component is created while the previous instance is still running, we are guaranteed to not end up with no component when one is running.



144
145
146
147
148
149
# File 'lib/datadog/di.rb', line 144

def add_current_component(component)
  LOCK.synchronize do
    @current_components ||= []
    @current_components << component
  end
end

.code_tracking_active?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns whether code tracking is available. This method should be used instead of querying #code_tracker because the latter one may be nil.

Returns:

  • (Boolean)


107
108
109
# File 'lib/datadog/di.rb', line 107

def code_tracking_active?
  code_tracker&.active? || false
end

.componentObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method is called from DI Remote handler to issue DI operations to the probe manager (add or remove probes).

When DI Remote is executing, Datadog.components should be initialized and we should be able to reference it to get to the DI component.

Given that we need the current_component anyway for code tracker, perhaps we should delete the component method and just use current_component in all cases.



120
121
122
# File 'lib/datadog/di.rb', line 120

def component
  Datadog.send(:components).dynamic_instrumentation
end

.current_componentObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

DI code tracker is instantiated globally before the regular set of components is created, but the code tracker needs to call out to the “current” DI component to perform instrumentation when application code is loaded. Because this call may happen prior to Datadog components having been initialized, we maintain the “current component” which contains a reference to the most recently instantiated DI::Component. This way, if a DI component hasn’t been instantiated, we do not try to reference Datadog.components.



132
133
134
135
136
# File 'lib/datadog/di.rb', line 132

def current_component
  LOCK.synchronize do
    @current_components&.last
  end
end

.deactivate_tracking!Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Deactivates code tracking. In normal usage of DI this method should never be called, however it is used by DI’s test suite to reset state for individual tests.

Note that deactivating tracking clears out the registry, losing the ability to look up files that have been loaded into the process already.



100
101
102
# File 'lib/datadog/di.rb', line 100

def deactivate_tracking!
  code_tracker&.stop
end

.enabled?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


41
42
43
# File 'lib/datadog/di.rb', line 41

def enabled?
  Datadog.configuration.dynamic_instrumentation.enabled
end

.remove_current_component(component) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



151
152
153
154
155
# File 'lib/datadog/di.rb', line 151

def remove_current_component(component)
  LOCK.synchronize do
    @current_components&.delete(component)
  end
end