Class: Dtrace::Provider
- Inherits:
-
Object
- Object
- Dtrace::Provider
- Defined in:
- lib/dtrace/provider.rb,
lib/dtrace/provider/osx.rb,
lib/dtrace/provider/solaris.rb
Overview
A DTrace provider. Allows creation of USDT probes on a running Ruby program, by dynamically creating an extension module implementing the probes, and compiling and loading it. You can use this with a Ruby interpreter compiled with the core DTrace probes, but you don’t have to.
This requires the DTrace and Ruby toolchains to be available: dtrace(1M), and the compiler and linker used to build Ruby. The process is similar to RubyInline, but the actual RubyInline library is not required (the build process for DTrace USDT probes is sufficiently differnent to a standard Ruby extension that it’s not worth using it).
Both Solaris and OSX 10.5 are supported. Other DTrace-supporting platforms can be added by creating a new class under Dtrace::Provider and implementing or overriding the required steps in the build process.
Firing probes is explained in Dtrace::Probe.
There are some limitations:
You cannot choose all the components of the probe name: you can choose the provider and probe name, but the module and function components will be derived by DTrace, and won’t be meaningful (they’ll refer to the shim extension that gets created, not to anything in your Ruby program). It seems unlikely it’s possible to change this.
You cannot currently set D attributes: they’re hardcoded to a default set. This will change.
The extension will currently be rebuilt every time the provider is created, as there’s not yet any support for packaging the provider in some way. This will change, to something along the lines of what RubyInline does to allow a pre-built extension to be used.
Defined Under Namespace
Classes: BuildError, OSX, Solaris
Class Method Summary collapse
-
.create(name) {|provider| ... } ⇒ Object
Creates a DTrace provider.
Instance Method Summary collapse
- #enable ⇒ Object
-
#initialize(name) ⇒ Provider
constructor
A new instance of Provider.
-
#probe(name, *types) ⇒ Object
Creates a DTrace USDT probe.
Constructor Details
#initialize(name) ⇒ Provider
Returns a new instance of Provider.
104 105 106 107 108 |
# File 'lib/dtrace/provider.rb', line 104 def initialize(name) @name = name.to_s @class = camelize(name) @probes = {} end |
Class Method Details
.create(name) {|provider| ... } ⇒ Object
Creates a DTrace provider. Causes a shim extension to be built and loaded, implementing the probes.
Example:
Dtrace::Provider.create :action_controller do |p|
p.probe :process_start, :string
p.probe :process_finish, :string, :integer
end
The symbol passed to create becomes the name of the provider, and the class exposed under Dtrace::Probe in Ruby (camelized, so the above statement creates Dtrace::Probe::ActionController).
create yields a Provider for the current platform, on which you can call probe, to create the individual probes.
74 75 76 77 78 79 80 81 82 |
# File 'lib/dtrace/provider.rb', line 74 def self.create(name) if RUBY_PLATFORM =~ /darwin/ provider = Dtrace::Provider::OSX.new(name) else provider = Dtrace::Provider::Solaris.new(name) end yield provider provider.enable end |
Instance Method Details
#enable ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/dtrace/provider.rb', line 110 def enable Tempfile.open("dtrace_probe_#{@name}") do |f| p = Pathname.new(f.path) @tempdir = "#{p.dirname}/#{@name}" begin Dir.mkdir @tempdir rescue Errno::EEXIST nil end # Probe setup is split up for easy overriding definition header source ruby_object dtrace_object link load end end |
#probe(name, *types) ⇒ Object
Creates a DTrace USDT probe. Arguments are the probe name, and then the argument types it will accept. The following argument types are supported:
:string (char *) :integer (int)
The probe will be named based on the provider name and the probe’s name:
provider_name:provider_name.so:probe_name:probe-name
See the limitations explained elsewhere for an explanation of this redundancy in probe names.
99 100 101 102 |
# File 'lib/dtrace/provider.rb', line 99 def probe(name, *types) typemap = { :string => 'char *', :integer => 'int' } @probes[name] = types.map {|t| typemap[t]} end |