module Datadog::Profiling
Contains profiler for generating stack profiles, etc.
Constants
- EventGroup
Represents a collection of events of a specific type being flushed.
- Flush
Entity class used to represent metadata for a given profile
- GOOGLE_PROTOBUF_MINIMUM_VERSION
- SKIPPED_NATIVE_EXTENSION_ONLY_ONCE
Public Class Methods
supported?()
click to toggle source
# File lib/ddtrace/profiling.rb, line 14 def self.supported? unsupported_reason.nil? end
unsupported_reason()
click to toggle source
# File lib/ddtrace/profiling.rb, line 18 def self.unsupported_reason # NOTE: Only the first matching reason is returned, so try to keep a nice order on reasons -- e.g. tell users # first that they can't use this on JRuby before telling them that they are missing protobuf ruby_engine_unsupported? || native_library_failed_to_load? || protobuf_gem_unavailable? || protobuf_version_unsupported? || protobuf_failed_to_load? end
Private Class Methods
load_profiling()
click to toggle source
# File lib/ddtrace/profiling.rb, line 128 def self.load_profiling return false unless supported? require 'ddtrace/profiling/ext/cpu' require 'ddtrace/profiling/ext/forking' require 'ddtrace/profiling/collectors/stack' require 'ddtrace/profiling/exporter' require 'ddtrace/profiling/recorder' require 'ddtrace/profiling/scheduler' require 'ddtrace/profiling/tasks/setup' require 'ddtrace/profiling/transport/io' require 'ddtrace/profiling/transport/http' require 'ddtrace/profiling/profiler' require 'ddtrace/profiling/native_extension' require 'ddtrace/profiling/trace_identifiers/helper' require 'ddtrace/profiling/pprof/pprof_pb' true end
native_library_failed_to_load?()
click to toggle source
# File lib/ddtrace/profiling.rb, line 89 def self.native_library_failed_to_load? success, exception = try_loading_native_library unless success if exception 'There was an error loading the profiling native extension due to ' \ "'#{exception.message}' at '#{exception.backtrace.first}'" else 'The profiling native extension did not load correctly. ' \ 'If the error persists, please contact support via <https://docs.datadoghq.com/help/> or ' \ 'file a bug at <https://github.com/DataDog/dd-trace-rb/blob/master/CONTRIBUTING.md#found-a-bug>.' end end end
protobuf_failed_to_load?()
click to toggle source
# File lib/ddtrace/profiling.rb, line 52 def self.protobuf_failed_to_load? unless protobuf_loaded_successfully? 'There was an error loading the google-protobuf library; see previous warning message for details' end end
protobuf_loaded_successfully?()
click to toggle source
The `google-protobuf` gem depends on a native component, and its creators helpfully tried to provide precompiled versions of this extension on rubygems.org.
Unfortunately, for a long time, the supported Ruby versions metadata on these precompiled versions of the extension was not correctly set. (This is fixed in newer versions – but not all Ruby versions we want to support can use these.)
Thus, the gem can still be installed, but can be in a broken state. To avoid breaking customer applications, we use this helper to load it and gracefully handle failures.
# File lib/ddtrace/profiling.rb, line 67 def self.protobuf_loaded_successfully? return @protobuf_loaded if defined?(@protobuf_loaded) begin require 'google/protobuf' @protobuf_loaded = true rescue LoadError => e # NOTE: We use Kernel#warn here because this code gets run BEFORE Datadog.logger is actually set up. # In the future it'd be nice to shuffle the logger startup to happen first to avoid this special case. Kernel.warn( '[DDTRACE] Error while loading google-protobuf gem. ' \ "Cause: '#{e.message}' Location: '#{Array(e.backtrace).first}'. " \ 'This can happen when google-protobuf is missing its native components. ' \ 'To fix this, try removing and reinstalling the gem, forcing it to recompile the components: ' \ '`gem uninstall google-protobuf -a; BUNDLE_FORCE_RUBY_PLATFORM=true bundle install`. ' \ 'If the error persists, please contact support via <https://docs.datadoghq.com/help/> or ' \ 'file a bug at <https://github.com/DataDog/dd-trace-rb/blob/master/CONTRIBUTING.md#found-a-bug>.' ) @protobuf_loaded = false end end
protobuf_version_unsupported?()
click to toggle source
# File lib/ddtrace/profiling.rb, line 42 def self.protobuf_version_unsupported? # See above for why we skip the check when protobuf is already loaded; note that when protobuf was already loaded # we skip the version check to avoid the call to Gem.loaded_specs. Unfortunately, protobuf does not seem to # expose the gem version constant elsewhere, so in that setup we are not able to check the version. if !defined?(::Google::Protobuf) && Gem.loaded_specs['google-protobuf'].version < GOOGLE_PROTOBUF_MINIMUM_VERSION 'Your google-protobuf is too old; ensure that you have google-protobuf >= 3.0 by ' \ "adding `gem 'google-protobuf', '~> 3.0'` to your Gemfile or gems.rb file" end end
ruby_engine_unsupported?()
click to toggle source
# File lib/ddtrace/profiling.rb, line 29 def self.ruby_engine_unsupported? 'JRuby is not supported' if RUBY_ENGINE == 'jruby' end
try_loading_native_library()
click to toggle source
# File lib/ddtrace/profiling.rb, line 104 def self.try_loading_native_library if Datadog::Core::Environment::VariableHelpers.env_to_bool('DD_PROFILING_NO_EXTENSION', false) SKIPPED_NATIVE_EXTENSION_ONLY_ONCE.run do Kernel.warn( '[DDTRACE] Skipped loading of profiling native extension due to DD_PROFILING_NO_EXTENSION environment ' \ 'variable being set. ' \ 'This option is experimental and will lead to the profiler not working in future releases. ' \ 'If you needed to use this, please tell us why on <https://github.com/DataDog/dd-trace-rb/issues/new>.' ) end return [true, nil] end begin require "ddtrace_profiling_native_extension.#{RUBY_VERSION}_#{RUBY_PLATFORM}" success = defined?(Datadog::Profiling::NativeExtension) && Datadog::Profiling::NativeExtension.send(:native_working?) [success, nil] rescue StandardError, LoadError => e [false, e] end end