Module: Instana::Util

Defined in:
lib/instana/util.rb

Class Method Summary collapse

Class Method Details

.collect_process_infoObject

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(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_idInteger

Generate a random 64bit ID

Returns:

  • (Integer)

    a random 64bit integer



178
179
180
181
# File 'lib/instana/util.rb', line 178

def generate_id
  # Max value is 9223372036854775807 (signed long in Java)
  rand(-2**63..2**63-1)
end

.get_rb_source(file) ⇒ Object

Retrieves and returns the source code for any ruby files requested by the UI via the host agent

Parameters:

  • file (String)

    The fully qualified path to a file



75
76
77
78
79
80
81
82
83
# File 'lib/instana/util.rb', line 75

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

Parameters:

  • header_id (String)

    the header value to be converted

Returns:

  • (Integer)


206
207
208
209
210
211
212
213
214
215
# File 'lib/instana/util.rb', line 206

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
  [header_id].pack("H*").unpack("q>")[0]
rescue => e
  Instana.logger.error "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
  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.

Parameters:

  • id (Integer)

    the id to be converted

Returns:

  • (String)


189
190
191
192
193
194
195
196
197
198
# File 'lib/instana/util.rb', line 189

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]
rescue => e
  Instana.logger.error "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
  Instana.logger.debug e.backtrace.join("\r\n")
end

.method_alias(klass, method) ⇒ Object

An agnostic approach to method aliasing.

Parameters:

  • klass (Object)

    The class or module that holds the method to be alias’d.

  • method (Symbol)

    The name of the method to be aliased.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/instana/util.rb', line 9

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

.pry!Object

Debugging helper method



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/instana/util.rb', line 45

def pry!
  # Only valid for development or test environments
  #env = ENV['RACK_ENV'] || ENV['RAILS_ENV']
  #return unless %w(development, test).include? env

  if RUBY_VERSION > '1.8.7'
    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
  else
    require 'ruby-debug'; debugger
  end
end

.send_extend(target_cls, cls) ⇒ Object

Calls on target_class to ‘extend’ cls

Parameters:

  • target_cls (Object)

    the class/module to do the ‘extending’

  • cls (Object)

    the class/module to be ‘extended’



30
31
32
# File 'lib/instana/util.rb', line 30

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.

Parameters:

  • target_cls (Object)

    the class/module to do the ‘including’

  • cls (Object)

    the class/module to be ‘included’



39
40
41
# File 'lib/instana/util.rb', line 39

def send_include(target_cls, cls)
  target_cls.send(:include, cls) if defined?(target_cls)
end

.take_snapshotObject

Method to collect up process info for snapshots. This is generally used once per process.



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 88

def take_snapshot
  data = {}

  data[:sensorVersion] = ::Instana::VERSION
  data[:ruby_version] = RUBY_VERSION

  # 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.error "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
  ::Instana.logger.debug e.backtrace.join("\r\n")
  return data
end

.time_to_ms(time = Time.now) ⇒ Object

Convert a Time value to milliseconds

Parameters:

  • time (Time) (defaults to: Time.now)


170
171
172
# File 'lib/instana/util.rb', line 170

def time_to_ms(time = Time.now)
  (time.to_f * 1000).floor
end

.ts_nowInteger

Get the current time in milliseconds

Returns:

  • (Integer)

    the current time in milliseconds



162
163
164
# File 'lib/instana/util.rb', line 162

def ts_now
  (Time.now.to_f * 1000).floor
end