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 |
# 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 cmdline = ProcTable.ps(:pid => Process.pid).cmdline.split(' ') 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
203 204 205 206 |
# File 'lib/instana/util.rb', line 203 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.
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/instana/util.rb', line 161 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
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/instana/util.rb', line 231 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.
214 215 216 217 218 219 220 221 222 223 |
# File 'lib/instana/util.rb', line 214 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
185 186 187 |
# File 'lib/instana/util.rb', line 185 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
195 196 197 |
# File 'lib/instana/util.rb', line 195 def time_to_ms(time) (time.to_f * 1000).floor end |