alexb-raygun-apm 1.0.57-x64-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.rdoc +117 -0
- data/bin/console +14 -0
- data/bin/diagnostics +7 -0
- data/bin/setup +8 -0
- data/ext/raygun/extconf.rb +49 -0
- data/lib/raygun/2.5/raygun_ext.so +0 -0
- data/lib/raygun/2.6/raygun_ext.so +0 -0
- data/lib/raygun/2.7/raygun_ext.so +0 -0
- data/lib/raygun/alexb-raygun-apm.rb +25 -0
- data/lib/raygun/apm/blacklist.rb +460 -0
- data/lib/raygun/apm/blacklist/parser.rb +47 -0
- data/lib/raygun/apm/blacklist/translator.rb +73 -0
- data/lib/raygun/apm/config.rb +88 -0
- data/lib/raygun/apm/diagnostics.rb +52 -0
- data/lib/raygun/apm/event.rb +39 -0
- data/lib/raygun/apm/hooks/excon.rb +36 -0
- data/lib/raygun/apm/hooks/httpclient.rb +36 -0
- data/lib/raygun/apm/hooks/internals.rb +74 -0
- data/lib/raygun/apm/hooks/net_http.rb +44 -0
- data/lib/raygun/apm/hooks/redis.rb +46 -0
- data/lib/raygun/apm/tracer.rb +85 -0
- data/lib/raygun/apm/version.rb +6 -0
- data/raygun-apm.gemspec +39 -0
- metadata +253 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
module Raygun
|
2
|
+
module Apm
|
3
|
+
module Blacklist
|
4
|
+
class Parser
|
5
|
+
COMMENT = /^#[^<].*/
|
6
|
+
ANONYMOUS = /^#<.*:.*>?/
|
7
|
+
|
8
|
+
def initialize(tracer)
|
9
|
+
@tracer = tracer
|
10
|
+
@translator = Blacklist::Translator.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_filters(filters)
|
14
|
+
filters.each do |filter|
|
15
|
+
filter.strip!
|
16
|
+
add_filter(filter)
|
17
|
+
end
|
18
|
+
show_filters
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
def add_filter(filter)
|
23
|
+
if filter =~ COMMENT && filter !~ ANONYMOUS
|
24
|
+
return
|
25
|
+
end
|
26
|
+
if filter.start_with?('+')
|
27
|
+
@tracer.add_whitelist *translate(filter[1..-1])
|
28
|
+
elsif filter.start_with?('-')
|
29
|
+
@tracer.add_blacklist *translate(filter[1..-1])
|
30
|
+
elsif filter.size > 0
|
31
|
+
@tracer.add_blacklist *translate(filter)
|
32
|
+
end
|
33
|
+
rescue => e
|
34
|
+
puts "Failed to add line '#{filter}' to the blacklist (#{e}) #{e.backtrace.join("\n")}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def show_filters
|
38
|
+
@tracer.show_filters if @tracer.config.loglevel == Tracer::LOG_BLACKLIST
|
39
|
+
end
|
40
|
+
|
41
|
+
def translate(filter)
|
42
|
+
@translator.translate(filter)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Raygun
|
2
|
+
module Apm
|
3
|
+
module Blacklist
|
4
|
+
class Translator
|
5
|
+
class RubyTranslator
|
6
|
+
# Foo::Bar#baz
|
7
|
+
# Foo::Bar.baz
|
8
|
+
COMMENT = /^#.*/
|
9
|
+
ANONYMOUS = /^#<.*>?/
|
10
|
+
NAMESPACE = /::/
|
11
|
+
NAMESPACE_ONLY = /::$/
|
12
|
+
METHOD = /#|\./
|
13
|
+
LETTER_CASE = /^[A-Z]/
|
14
|
+
|
15
|
+
def translate(filter)
|
16
|
+
path, method = nil, nil
|
17
|
+
if filter !~ COMMENT && filter !~ ANONYMOUS
|
18
|
+
if filter.end_with?("#")
|
19
|
+
path = filter
|
20
|
+
else
|
21
|
+
path, method = filter.split(METHOD)
|
22
|
+
end
|
23
|
+
# .NET fallback
|
24
|
+
return if method =~ LETTER_CASE && !method.start_with?("Ruby")
|
25
|
+
if path == path.downcase
|
26
|
+
method = path
|
27
|
+
path = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
# .NET fallback
|
31
|
+
return if method =~ NAMESPACE
|
32
|
+
[path, method]
|
33
|
+
elsif filter =~ ANONYMOUS
|
34
|
+
_, klass, method = filter.split(METHOD)
|
35
|
+
["##{klass}", method]
|
36
|
+
else
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# References https://raygun.com/documentation/product-guides/apm/blacklist/
|
43
|
+
class DotnetTranslator
|
44
|
+
# Foo.Bar::Baz
|
45
|
+
COMMENT = /^#/
|
46
|
+
NAMESPACE = /\./
|
47
|
+
METHOD = /::/
|
48
|
+
|
49
|
+
def translate(filter)
|
50
|
+
if filter !~ COMMENT
|
51
|
+
path, method = nil, nil
|
52
|
+
path, method = filter.split(METHOD)
|
53
|
+
path.gsub!(NAMESPACE, "::")
|
54
|
+
[path, method]
|
55
|
+
else
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def initialize
|
62
|
+
@ruby = RubyTranslator.new
|
63
|
+
@dotnet = DotnetTranslator.new
|
64
|
+
end
|
65
|
+
|
66
|
+
def translate(filter)
|
67
|
+
translated = @ruby.translate(filter)
|
68
|
+
translated ? translated : @dotnet.translate(filter)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Raygun
|
2
|
+
module Apm
|
3
|
+
class Config
|
4
|
+
LOGLEVELS = {
|
5
|
+
"None" => Tracer::LOG_NONE,
|
6
|
+
"Info" => Tracer::LOG_INFO,
|
7
|
+
"Warning" => Tracer::LOG_WARNING,
|
8
|
+
"Error" => Tracer::LOG_ERROR,
|
9
|
+
"Verbose" => Tracer::LOG_VERBOSE,
|
10
|
+
"Debug" => Tracer::LOG_DEBUG,
|
11
|
+
"Everything" => Tracer::LOG_EVERYTHING,
|
12
|
+
# ruby profiler specific
|
13
|
+
"Blacklist" => Tracer::LOG_BLACKLIST
|
14
|
+
}
|
15
|
+
|
16
|
+
ENVIRONMENTS = {
|
17
|
+
"development" => Tracer::ENV_DEVELOPMENT,
|
18
|
+
"production" => Tracer::ENV_PRODUCTION
|
19
|
+
}
|
20
|
+
|
21
|
+
attr_accessor :env
|
22
|
+
def initialize(env=ENV)
|
23
|
+
@env = env
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.cast_to_boolean(x)
|
27
|
+
case x
|
28
|
+
when true, 'true', 'True', 1, '1' then true
|
29
|
+
else
|
30
|
+
false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.config_var(attr, opts={}, &blk)
|
35
|
+
define_method attr.downcase do
|
36
|
+
val = if x = env[attr]
|
37
|
+
if opts[:as] == Integer
|
38
|
+
Integer(x)
|
39
|
+
elsif opts[:as] == String
|
40
|
+
x.to_s
|
41
|
+
elsif opts[:as] == :boolean
|
42
|
+
self.class.cast_to_boolean(x)
|
43
|
+
end
|
44
|
+
else
|
45
|
+
opts[:default]
|
46
|
+
end
|
47
|
+
blk ? blk.call(val) : val
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Initial constants for ProtonAgentTail.exe
|
52
|
+
UDP_SINK_HOST = TCP_MANAGEMENT_HOST = '127.0.0.1'
|
53
|
+
UDP_SINK_MULTICAST_HOST = '239.100.15.215'
|
54
|
+
UDP_SINK_PORT = 2799
|
55
|
+
TCP_MANAGEMENT_PORT = 2790
|
56
|
+
|
57
|
+
## Enumerate all PROTON_ constants
|
58
|
+
config_var 'PROTON_API_KEY', as: String, default: ''
|
59
|
+
config_var 'PROTON_DEBUG_LOGLEVEL', as: String, default: 'None'
|
60
|
+
config_var 'PROTON_USER_OVERRIDES_FILE', as: String
|
61
|
+
config_var 'PROTON_NETWORK_MODE', as: String, default: 'Udp'
|
62
|
+
config_var 'PROTON_FILE_IPC_FOLDER', as: String
|
63
|
+
config_var 'PROTON_USE_MULTICAST', as: String, default: 'False'
|
64
|
+
config_var 'PROTON_BATCH_IDLE_COUNTER', as: Integer, default: 500
|
65
|
+
|
66
|
+
def udp_host
|
67
|
+
if proton_use_multicast == 'True'
|
68
|
+
UDP_SINK_MULTICAST_HOST
|
69
|
+
else
|
70
|
+
UDP_SINK_HOST
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def udp_port
|
75
|
+
UDP_SINK_PORT
|
76
|
+
end
|
77
|
+
|
78
|
+
def loglevel
|
79
|
+
LOGLEVELS[proton_debug_loglevel] || raise(ArgumentError, "invalid log level")
|
80
|
+
end
|
81
|
+
|
82
|
+
def environment
|
83
|
+
environment = env['RACK_ENV'] || env['RAILS_ENV'] || 'production'
|
84
|
+
ENVIRONMENTS[environment] || Tracer::ENV_PRODUCTION
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "socket"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
module Raygun
|
5
|
+
module Apm
|
6
|
+
class Diagnostics
|
7
|
+
AGENT_STATE_DOWN = "\nThe Raygun APM Agent appears to not be running on the current host.\nIf not already installed, please consult https://raygun.com/documentation/product-guides/apm/agent/downloads/\nOtherwise refer to https://raygun.com/documentation/product-guides/apm/agent/installation/ for starting the Agent."
|
8
|
+
AGENT_STATE_UNKNOWN = "\nUnable to determine the state of the Raygun APM Agent."
|
9
|
+
AGENT_STATE_UP_MISCONFIGURED = "\nThe Raygun APM Agent is running, but misconfigured.\nThe API Key needs to be set through the Raygun_ApiKey environment variable.\nThe API key can be found under 'Application Settings' in the Raygun UI"
|
10
|
+
AGENT_STATE_UP_CONFIGURED = "\nThe Raygun APM Agent is configured properly!"
|
11
|
+
AGENT_MINIMUM_VERSION_NOT_MET = "\nVersion #{Raygun::Apm::VERSION} of the Raygun APM Profiler requires a minimum Agent version #{Raygun::Apm::MINIMUM_AGENT_VERSION}\nPlease download the latest Agent from https://raygun.com/documentation/product-guides/apm/agent/downloads/"
|
12
|
+
|
13
|
+
def initialize(host: Apm::Config::TCP_MANAGEMENT_HOST, port: Apm::Config::TCP_MANAGEMENT_PORT)
|
14
|
+
@host = host
|
15
|
+
@port = port
|
16
|
+
end
|
17
|
+
|
18
|
+
def verify_agent(tracer)
|
19
|
+
socket.write "GetAgentInfo"
|
20
|
+
response = JSON.parse(socket.gets)
|
21
|
+
if minimum_agent_version_not_met?(response['Version'])
|
22
|
+
puts AGENT_MINIMUM_VERSION_NOT_MET
|
23
|
+
tracer.noop!
|
24
|
+
else
|
25
|
+
if response['Status'] == 1
|
26
|
+
puts AGENT_STATE_UP_CONFIGURED
|
27
|
+
elsif response['Status'] == 0
|
28
|
+
puts AGENT_STATE_UP_MISCONFIGURED
|
29
|
+
end
|
30
|
+
end
|
31
|
+
rescue Errno::ECONNREFUSED
|
32
|
+
puts AGENT_STATE_DOWN
|
33
|
+
rescue
|
34
|
+
puts AGENT_STATE_UNKNOWN
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def socket
|
39
|
+
@socket ||= s = TCPSocket.new(@host, @port)
|
40
|
+
end
|
41
|
+
|
42
|
+
def minimum_agent_version_not_met?(version)
|
43
|
+
# Legacy path
|
44
|
+
if String === version
|
45
|
+
version < Raygun::Apm::MINIMUM_AGENT_VERSION
|
46
|
+
else
|
47
|
+
"#{version['Major']}.#{version['Minor']}.#{version['Build']}.#{version['Revision']}" < Raygun::Apm::MINIMUM_AGENT_VERSION
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Raygun
|
2
|
+
module Apm
|
3
|
+
class Event
|
4
|
+
def inspect
|
5
|
+
"#<#{self.class.name}:#{self.object_id}> length:#{self.length} pid:#{self[:pid]} tid:#{self[:tid]} timestamp:#{self[:timestamp]}"
|
6
|
+
end
|
7
|
+
class ThreadStarted < Event
|
8
|
+
def inspect
|
9
|
+
super + " parent_tid:#{self[:parent_tid]}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
class Begin < Event
|
13
|
+
def inspect
|
14
|
+
super + " function_id:#{self[:function_id]} instance_id:#{self[:instance_id]}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
class End < Event
|
18
|
+
def inspect
|
19
|
+
super + " function_id:#{self[:function_id]}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
class Methodinfo < Event
|
23
|
+
def inspect
|
24
|
+
super + " function_id:#{self[:function_id]} class_name:#{self[:class_name]} method_name:#{self[:method_name]} method_source:#{self[:method_source]}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
class HttpOut < Event
|
28
|
+
def inspect
|
29
|
+
super + " url:#{self[:url]} verb:#{self[:verb]} status:#{self[:status]} duration:#{self[:duration]}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
class BeginTransaction < Event
|
33
|
+
def inspect
|
34
|
+
super + " api_key:#{self[:api_key]} technology_type:#{self[:technology_type]} process_type:#{self[:process_type]}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'excon'
|
2
|
+
|
3
|
+
module Raygun
|
4
|
+
module Apm
|
5
|
+
module Hooks
|
6
|
+
module Excon
|
7
|
+
def request(params={}, &block)
|
8
|
+
if tracer = Raygun::Apm::Tracer.instance
|
9
|
+
started = tracer.now
|
10
|
+
response = super
|
11
|
+
ended = tracer.now
|
12
|
+
event = raygun_apm_http_out_event
|
13
|
+
event[:pid] = Process.pid
|
14
|
+
event[:url] = "#{@data[:scheme]}://#{@data[:host]}/#{params[:path]}"
|
15
|
+
event[:verb] = params[:method].to_s.upcase
|
16
|
+
event[:status] = response.status
|
17
|
+
event[:duration] = ended - started
|
18
|
+
event[:timestamp] = started
|
19
|
+
event[:tid] = tracer.get_thread_id(Thread.current)
|
20
|
+
tracer.emit(event)
|
21
|
+
response
|
22
|
+
else
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def raygun_apm_http_out_event
|
29
|
+
@_raygun_apm_http_out_event ||= Raygun::Apm::Event::HttpOut.new
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
Excon::Connection.prepend(Raygun::Apm::Hooks::Excon)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'httpclient'
|
2
|
+
|
3
|
+
module Raygun
|
4
|
+
module Apm
|
5
|
+
module Hooks
|
6
|
+
module HTTPClient
|
7
|
+
def do_request(method, uri, query, body, header, &filtered_block)
|
8
|
+
if tracer = Raygun::Apm::Tracer.instance
|
9
|
+
started = tracer.now
|
10
|
+
response = super
|
11
|
+
ended = tracer.now
|
12
|
+
event = raygun_apm_http_out_event
|
13
|
+
event[:pid] = Process.pid
|
14
|
+
event[:url] = query ? URI.join(uri, query).to_s : uri.to_s
|
15
|
+
event[:verb] = method.to_s.upcase
|
16
|
+
event[:status] = response.code.to_i
|
17
|
+
event[:duration] = ended - started
|
18
|
+
event[:timestamp] = started
|
19
|
+
event[:tid] = tracer.get_thread_id(Thread.current)
|
20
|
+
tracer.emit(event)
|
21
|
+
response
|
22
|
+
else
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def raygun_apm_http_out_event
|
29
|
+
@_raygun_apm_http_out_event ||= Raygun::Apm::Event::HttpOut.new
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
HTTPClient.prepend(Raygun::Apm::Hooks::HTTPClient)
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Raygun
|
2
|
+
module Apm
|
3
|
+
module Hooks
|
4
|
+
module Object
|
5
|
+
def system(*args)
|
6
|
+
super
|
7
|
+
end
|
8
|
+
|
9
|
+
def sleep(*args)
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
def exec(*args)
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
def spawn(*args)
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
def fork(*args)
|
22
|
+
super
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module IO
|
27
|
+
def sycall(*args)
|
28
|
+
super
|
29
|
+
end
|
30
|
+
|
31
|
+
def open(*args)
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
35
|
+
def puts(*args)
|
36
|
+
super
|
37
|
+
end
|
38
|
+
|
39
|
+
def gets(*args)
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
def readline(*args)
|
44
|
+
super
|
45
|
+
end
|
46
|
+
|
47
|
+
def readlines(*args)
|
48
|
+
super
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
module Random
|
53
|
+
def srand(*args)
|
54
|
+
super
|
55
|
+
end
|
56
|
+
|
57
|
+
def rand(*args)
|
58
|
+
super
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
module Signal
|
63
|
+
def trap(*args)
|
64
|
+
super
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
Object.prepend Raygun::Apm::Hooks::Object
|
72
|
+
IO.prepend Raygun::Apm::Hooks::IO
|
73
|
+
Random.prepend Raygun::Apm::Hooks::Random
|
74
|
+
Signal.prepend Raygun::Apm::Hooks::Signal
|