Module: Instana::Util
- Defined in:
- lib/instana/util.rb
Constant Summary collapse
- ID_RANGE =
-2**63..2**63-1
Class Method Summary collapse
-
.collect_process_info ⇒ Object
Used in class initialization and after a fork, this method collects up process information.
-
.generate_id ⇒ Integer
Generate a random 64bit ID.
-
.get_app_name ⇒ Object
Best effort to determine a name for the instrumented application on the dashboard.
-
.get_rb_source(file) ⇒ Object
Retrieves and returns the source code for any ruby files requested by the UI via the host agent.
-
.header_to_id(header_id) ⇒ Integer
Convert a received header value into a valid ID.
-
.id_to_header(id) ⇒ String
Convert an ID to a value appropriate to pass in a header.
-
.method_alias(klass, method) ⇒ Object
An agnostic approach to method aliasing.
-
.now_in_ms ⇒ Integer
(also: ts_now)
Get the current time in milliseconds from the epoch.
-
.pry! ⇒ Object
Debugging helper method.
-
.send_extend(target_cls, cls) ⇒ Object
Calls on target_class to ‘extend’ cls.
-
.send_include(target_cls, cls) ⇒ Object
Calls on <target_cls> to include <cls> into itself.
-
.take_snapshot ⇒ Object
Method to collect up process info for snapshots.
-
.time_to_ms(time) ⇒ Object
Convert a Time value to milliseconds.
Class Method Details
.collect_process_info ⇒ Object
Used in class initialization and after a fork, this method collects up process information
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/instana/util.rb', line 130 def collect_process_info process = {} cmdline_file = "/proc/#{Process.pid}/cmdline" # If there is a /proc filesystem, we read this manually so # we can split on embedded null bytes. Otherwise (e.g. OSX, Windows) # use ProcTable. if File.exist?(cmdline_file) cmdline = IO.read(cmdline_file).split(?\x00) else # Attempt to support older versions of sys-proctable and ffi. # # Alternatively we could use Sys::ProcTable::VERSION here but the # consistency across historical versions is unknown. Alternative # to the alternative, would be Ruby metaprogramming using the `arity` # and `parameters` methods. # e.g ProcTable.method(:ps).arity/parameters if Gem.loaded_specs.key?("sys-proctable") && (Gem.loaded_specs["sys-proctable"].version >= Gem::Version.new("1.2.0")) cmdline = ProcTable.ps(:pid => Process.pid).cmdline.split(' ') else cmdline = ProcTable.ps(Process.pid).cmdline.split(' ') end end if RUBY_PLATFORM =~ /darwin/i cmdline.delete_if{ |e| e.include?('=') } process[:name] = cmdline.join(' ') else process[:name] = cmdline.shift process[:arguments] = cmdline end process[:pid] = Process.pid # This is usually Process.pid but in the case of containers, the host agent # will return to us the true host pid in which we use to report data. process[:report_pid] = nil process end |
.generate_id ⇒ Integer
Generate a random 64bit ID
215 216 217 218 |
# File 'lib/instana/util.rb', line 215 def generate_id # Max value is 9223372036854775807 (signed long in Java) rand(ID_RANGE) end |
.get_app_name ⇒ Object
Best effort to determine a name for the instrumented application on the dashboard.
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/instana/util.rb', line 173 def get_app_name if ENV.key?('INSTANA_SERVICE_NAME') return ENV['INSTANA_SERVICE_NAME'] end if defined?(::Resque) && ($0 =~ /resque-#{Resque::Version}/) return "Resque Worker" end if defined?(::RailsLts) || defined?(::Rails) return Rails.application.class.to_s.split('::')[0] end return File.basename($0) rescue Exception => e Instana.logger.info "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.}" Instana.logger.debug { e.backtrace.join("\r\n") } end |
.get_rb_source(file) ⇒ Object
Retrieves and returns the source code for any ruby files requested by the UI via the host agent
74 75 76 77 78 79 80 81 82 |
# File 'lib/instana/util.rb', line 74 def get_rb_source(file) if (file =~ /.rb$/).nil? { :error => "Only Ruby source files are allowed. (*.rb)" } else { :data => File.read(file) } end rescue => e return { :error => e.inspect } end |
.header_to_id(header_id) ⇒ Integer
Convert a received header value into a valid ID
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'lib/instana/util.rb', line 243 def header_to_id(header_id) if !header_id.is_a?(String) Instana.logger.debug "header_to_id received a #{header_id.class}: returning 0" return 0 end if header_id.length < 16 # The header is less than 16 chars. Prepend # zeros so we can convert correctly missing = 16 - header_id.length header_id = ("0" * missing) + header_id end [header_id].pack("H*").unpack("q>")[0] rescue => e Instana.logger.info "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.}" Instana.logger.debug { e.backtrace.join("\r\n") } end |
.id_to_header(id) ⇒ String
Convert an ID to a value appropriate to pass in a header.
226 227 228 229 230 231 232 233 234 235 |
# File 'lib/instana/util.rb', line 226 def id_to_header(id) unless id.is_a?(Integer) || id.is_a?(String) Instana.logger.debug "id_to_header received a #{id.class}: returning empty string" return String.new end [id.to_i].pack('q>').unpack('H*')[0].gsub(/^0+/, '') rescue => e Instana.logger.info "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.}" Instana.logger.debug { e.backtrace.join("\r\n") } end |
.method_alias(klass, method) ⇒ Object
An agnostic approach to method aliasing.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/instana/util.rb', line 11 def method_alias(klass, method) if klass.method_defined?(method.to_sym) || klass.private_method_defined?(method.to_sym) with = "#{method}_with_instana" without = "#{method}_without_instana" klass.class_eval do alias_method without, method.to_s alias_method method.to_s, with end else ::Instana.logger.debug "No such method (#{method}) to alias on #{klass}" end end |
.now_in_ms ⇒ Integer Also known as: ts_now
Get the current time in milliseconds from the epoch
197 198 199 |
# File 'lib/instana/util.rb', line 197 def now_in_ms Process.clock_gettime(Process::CLOCK_REALTIME, :millisecond) end |
.pry! ⇒ Object
Debugging helper method
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/instana/util.rb', line 47 def pry! # Only valid for development or test environments #env = ENV['RACK_ENV'] || ENV['RAILS_ENV'] #return unless %w(development, test).include? env require 'pry-byebug' if defined?(PryByebug) Pry.commands.alias_command 'c', 'continue' Pry.commands.alias_command 's', 'step' Pry.commands.alias_command 'n', 'next' Pry.commands.alias_command 'f', 'finish' Pry::Commands.command(/^$/, 'repeat last command') do _pry_.run_command Pry.history.to_a.last end end binding.pry rescue LoadError ::Instana.logger.warn("No debugger in bundle. Couldn't load pry-byebug.") end |
.send_extend(target_cls, cls) ⇒ Object
Calls on target_class to ‘extend’ cls
32 33 34 |
# File 'lib/instana/util.rb', line 32 def send_extend(target_cls, cls) target_cls.send(:extend, cls) if defined?(target_cls) end |
.send_include(target_cls, cls) ⇒ Object
Calls on <target_cls> to include <cls> into itself.
41 42 43 |
# File 'lib/instana/util.rb', line 41 def send_include(target_cls, cls) target_cls.send(:include, cls) if defined?(target_cls) end |
.take_snapshot ⇒ Object
Method to collect up process info for snapshots. This is generally used once per process.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/instana/util.rb', line 87 def take_snapshot data = {} data[:sensorVersion] = ::Instana::VERSION data[:ruby_version] = RUBY_VERSION data[:rpl] = RUBY_PATCHLEVEL if defined?(RUBY_PATCHLEVEL) # Framework Detection if defined?(::RailsLts::VERSION) data[:framework] = "Rails on Rails LTS-#{::RailsLts::VERSION}" elsif defined?(::Rails.version) data[:framework] = "Ruby on Rails #{::Rails.version}" elsif defined?(::Grape::VERSION) data[:framework] = "Grape #{::Grape::VERSION}" elsif defined?(::Padrino::VERSION) data[:framework] = "Padrino #{::Padrino::VERSION}" elsif defined?(::Sinatra::VERSION) data[:framework] = "Sinatra #{::Sinatra::VERSION}" end # Report Bundle if defined?(::Gem) && Gem.respond_to?(:loaded_specs) data[:versions] = {} Gem.loaded_specs.each do |k, v| data[:versions][k] = v.version.to_s end end data rescue => e ::Instana.logger.debug { "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.}" } ::Instana.logger.debug { e.backtrace.join("\r\n") } return data end |
.time_to_ms(time) ⇒ Object
Convert a Time value to milliseconds
207 208 209 |
# File 'lib/instana/util.rb', line 207 def time_to_ms(time) (time.to_f * 1000).floor end |