instana 0.1.0 → 0.8.beta1
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 +4 -4
- data/Gemfile +5 -2
- data/README.md +15 -6
- data/Rakefile +5 -0
- data/instana.gemspec +8 -2
- data/lib/instana.rb +37 -4
- data/lib/instana/agent.rb +159 -7
- data/lib/instana/collectors.rb +47 -0
- data/lib/instana/collectors/gc.rb +63 -0
- data/lib/instana/collectors/memory.rb +41 -0
- data/lib/instana/collectors/thread.rb +39 -0
- data/lib/instana/config.rb +24 -0
- data/lib/instana/util.rb +52 -0
- data/lib/instana/version.rb +1 -1
- metadata +55 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c7002d4134c228c245a364723eaca19b0f1f46c
|
4
|
+
data.tar.gz: 72ed46de39b20562edd678d53c41440807255bf9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6334386fa5f9088f80156783cee4c4c6416fa87bdc376b9cda97f275d19759a1f581501a81560f8647952e3cab6c58e9e8a82542222c9ff776f3b7dc0b5ee5c4
|
7
|
+
data.tar.gz: 81077cde159bfe0fac9a95ced6287d3e797a8dce11c360a711ccbe6039e81d756337b4092a169a9086eafa2920a4f2c615144639427fbbf864d88a33673c18b2
|
data/Gemfile
CHANGED
@@ -3,9 +3,8 @@ source 'https://rubygems.org'
|
|
3
3
|
group :development, :test do
|
4
4
|
gem 'rake'
|
5
5
|
gem 'minitest'
|
6
|
-
gem 'minitest-reporters'
|
6
|
+
gem 'minitest-reporters'
|
7
7
|
gem 'minitest-debugger', :require => false
|
8
|
-
gem 'rack-test'
|
9
8
|
end
|
10
9
|
|
11
10
|
group :development do
|
@@ -20,5 +19,9 @@ group :development do
|
|
20
19
|
end
|
21
20
|
end
|
22
21
|
|
22
|
+
gem 'get_process_mem'
|
23
|
+
gem 'sys-proctable'
|
24
|
+
gem 'timers'
|
25
|
+
|
23
26
|
# instana.gemspec
|
24
27
|
gemspec
|
data/README.md
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
# Instana
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
3
|
+
The Instana gem provides Ruby metrics for [Instana](https://www.instana.com/).
|
6
4
|
|
7
5
|
## Installation
|
8
6
|
|
9
|
-
|
7
|
+
The gem is available on [Rubygems](https://rubygems.org/gems/instana). To install, add this line to _the end_ of your application's Gemfile:
|
10
8
|
|
11
9
|
```ruby
|
12
10
|
gem 'instana'
|
@@ -22,7 +20,18 @@ Or install it yourself as:
|
|
22
20
|
|
23
21
|
## Usage
|
24
22
|
|
25
|
-
|
23
|
+
The instana gem is a zero configuration tool that will automatically collect key metrics from your Ruby processes. Just install and go.
|
24
|
+
|
25
|
+
## Configuration
|
26
|
+
|
27
|
+
Although the gem has no configuration required for metrics, individual components can be disabled with a local config.
|
28
|
+
|
29
|
+
To disable a single component in the gem, you can disable a single component with the following code:
|
30
|
+
|
31
|
+
```Ruby
|
32
|
+
::Instana.config[:metrics][:gc][:enabled] = false
|
33
|
+
```
|
34
|
+
Current components are `:gc`, `:memory` and `:thread`.
|
26
35
|
|
27
36
|
## Development
|
28
37
|
|
@@ -32,5 +41,5 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
32
41
|
|
33
42
|
## Contributing
|
34
43
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
44
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/instana/ruby-sensor.
|
36
45
|
|
data/Rakefile
CHANGED
@@ -2,12 +2,17 @@ require "bundler/gem_tasks"
|
|
2
2
|
require "rake/testtask"
|
3
3
|
|
4
4
|
Rake::TestTask.new(:test) do |t|
|
5
|
+
t.verbose = false
|
6
|
+
t.warning = false
|
7
|
+
t.ruby_opts = []
|
8
|
+
|
5
9
|
t.libs << "test"
|
6
10
|
t.libs << "lib"
|
7
11
|
t.test_files = FileList['test/**/*_test.rb']
|
8
12
|
end
|
9
13
|
|
10
14
|
task :environment do
|
15
|
+
ENV['INSTANA_GEM_DEV'] = 'true'
|
11
16
|
Bundler.require(:default, :development)
|
12
17
|
end
|
13
18
|
|
data/instana.gemspec
CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Peter Giacomo Lombardo"]
|
10
10
|
spec.email = ["pglombardo@gmail.com"]
|
11
11
|
|
12
|
-
spec.summary = %q{
|
13
|
-
spec.description = %q{
|
12
|
+
spec.summary = %q{Ruby sensor for Instana}
|
13
|
+
spec.description = %q{Provides Ruby sensor instrumentation for Instana.}
|
14
14
|
spec.homepage = "https://www.instana.com/"
|
15
15
|
|
16
16
|
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
@@ -26,7 +26,13 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
27
|
spec.require_paths = ["lib"]
|
28
28
|
|
29
|
+
spec.required_ruby_version = '>= 2.0'
|
30
|
+
|
29
31
|
spec.add_development_dependency "bundler", "~> 1.11"
|
30
32
|
spec.add_development_dependency "rake", "~> 10.0"
|
31
33
|
spec.add_development_dependency "minitest", "~> 5.0"
|
34
|
+
|
35
|
+
spec.add_runtime_dependency('sys-proctable', '>= 1.1.3')
|
36
|
+
spec.add_runtime_dependency('get_process_mem', '>= 0.2.1')
|
37
|
+
spec.add_runtime_dependency('timers', '>= 4.1.0')
|
32
38
|
end
|
data/lib/instana.rb
CHANGED
@@ -1,13 +1,46 @@
|
|
1
|
-
|
2
|
-
require "instana/agent"
|
1
|
+
|
3
2
|
require 'logger'
|
3
|
+
require "instana/version"
|
4
|
+
require "instana/util"
|
4
5
|
|
5
6
|
module Instana
|
6
7
|
class << self
|
7
8
|
attr_accessor :agent
|
9
|
+
attr_accessor :collectors
|
10
|
+
attr_accessor :config
|
8
11
|
attr_accessor :logger
|
12
|
+
attr_accessor :pid
|
13
|
+
|
14
|
+
##
|
15
|
+
# start
|
16
|
+
#
|
17
|
+
# Initialize the Instana language agent
|
18
|
+
#
|
19
|
+
def start
|
20
|
+
Instana.agent = Instana::Agent.new
|
21
|
+
Instana.collectors = []
|
22
|
+
Instana.logger = Logger.new(STDOUT)
|
23
|
+
Instana.logger.info "Stan is on the scene. Starting Instana instrumentation."
|
24
|
+
|
25
|
+
# Store the current pid so we can detect a potential fork
|
26
|
+
# later on
|
27
|
+
Instana.pid = Process.pid
|
28
|
+
end
|
29
|
+
|
30
|
+
def pid_change?
|
31
|
+
@pid != Process.pid
|
32
|
+
end
|
9
33
|
end
|
10
34
|
end
|
11
35
|
|
12
|
-
|
13
|
-
|
36
|
+
require "instana/config"
|
37
|
+
require "instana/agent"
|
38
|
+
|
39
|
+
::Instana.start
|
40
|
+
|
41
|
+
if ::Instana.agent.host_agent_ready?
|
42
|
+
::Instana.agent.announce_sensor
|
43
|
+
require "instana/collectors"
|
44
|
+
else
|
45
|
+
::Instana.logger.info "Instana host agent not available. Going to sit in a corner quietly."
|
46
|
+
end
|
data/lib/instana/agent.rb
CHANGED
@@ -1,33 +1,185 @@
|
|
1
1
|
require 'net/http'
|
2
2
|
require 'uri'
|
3
3
|
require 'json'
|
4
|
+
require 'sys/proctable'
|
5
|
+
include Sys
|
4
6
|
|
5
7
|
module Instana
|
6
8
|
class Agent
|
7
|
-
|
9
|
+
attr_accessor :last_entity_response
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
# Host agent defaults. Can be configured via Instana.config
|
8
13
|
@request_timeout = 5000
|
9
14
|
@host = '127.0.0.1'
|
10
15
|
@port = 42699
|
11
16
|
@server_header = 'Instana Agent'
|
12
|
-
|
17
|
+
|
18
|
+
# Snapshot data is collected once per process but resent
|
19
|
+
# every 10 minutes along side process metrics.
|
20
|
+
@snapshot = take_snapshot
|
21
|
+
|
22
|
+
# Set last snapshot to 10 minutes ago
|
23
|
+
# so we send a snapshot on first report
|
24
|
+
@last_snapshot = Time.now - 601
|
13
25
|
end
|
14
26
|
|
27
|
+
##
|
28
|
+
# take_snapshot
|
29
|
+
#
|
30
|
+
# Method to collect up process info for snapshots. This
|
31
|
+
# is generally used once per process.
|
32
|
+
#
|
33
|
+
def take_snapshot
|
34
|
+
data = {}
|
35
|
+
|
36
|
+
data[:sensorVersion] = ::Instana::VERSION
|
37
|
+
data[:pid] = Process.pid
|
38
|
+
data[:ruby_version] = RUBY_VERSION
|
39
|
+
|
40
|
+
process = ProcTable.ps(Process.pid)
|
41
|
+
arguments = process.cmdline.split(' ')
|
42
|
+
data[:name] = arguments.shift
|
43
|
+
data[:exec_args] = arguments
|
44
|
+
|
45
|
+
# Since a snapshot is only taken on process boot,
|
46
|
+
# this is ok here.
|
47
|
+
data[:start_time] = Time.now.to_s
|
48
|
+
|
49
|
+
# Framework Detection
|
50
|
+
if defined?(::RailsLts::VERSION)
|
51
|
+
data[:framework] = "Rails on Rails LTS-#{::RailsLts::VERSION}"
|
52
|
+
|
53
|
+
elsif defined?(::Rails.version)
|
54
|
+
data[:framework] = "Ruby on Rails #{::Rails.version}"
|
55
|
+
|
56
|
+
elsif defined?(::Grape::VERSION)
|
57
|
+
data[:framework] = "Grape #{::Grape::VERSION}"
|
58
|
+
|
59
|
+
elsif defined?(::Padrino::VERSION)
|
60
|
+
data[:framework] = "Padrino #{::Padrino::VERSION}"
|
61
|
+
|
62
|
+
elsif defined?(::Sinatra::VERSION)
|
63
|
+
data[:framework] = "Sinatra #{::Sinatra::VERSION}"
|
64
|
+
end
|
65
|
+
|
66
|
+
data
|
67
|
+
rescue => e
|
68
|
+
::Instana.logger.debug "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
|
69
|
+
::Instana.logger.debug e.backtrace.join("\r\n")
|
70
|
+
return data
|
71
|
+
end
|
72
|
+
|
73
|
+
##
|
74
|
+
# announce_sensor
|
75
|
+
#
|
76
|
+
# Collect process ID, name and arguments to notify
|
77
|
+
# the host agent.
|
78
|
+
#
|
15
79
|
def announce_sensor
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
payload[:name] = $0
|
80
|
+
process = ProcTable.ps(Process.pid)
|
81
|
+
announce_payload = {}
|
82
|
+
announce_payload[:pid] = Process.pid
|
20
83
|
|
84
|
+
arguments = process.cmdline.split(' ')
|
85
|
+
arguments.shift
|
86
|
+
announce_payload[:args] = arguments
|
87
|
+
|
88
|
+
path = 'com.instana.plugin.ruby.discovery'
|
89
|
+
uri = URI.parse("http://#{@host}:#{@port}/#{path}")
|
21
90
|
req = Net::HTTP::Put.new(uri)
|
91
|
+
|
92
|
+
req['Accept'] = 'application/json'
|
93
|
+
req['Content-Type'] = 'application/json'
|
94
|
+
req.body = announce_payload.to_json
|
95
|
+
|
96
|
+
::Instana.logger.debug "Announcing sensor to #{path} for pid #{Process.pid}: #{announce_payload.to_json}"
|
97
|
+
|
98
|
+
response = nil
|
99
|
+
Net::HTTP.start(uri.hostname, uri.port) do |http|
|
100
|
+
response = http.request(req)
|
101
|
+
end
|
102
|
+
Instana.logger.debug response.code
|
103
|
+
rescue => e
|
104
|
+
Instana.logger.debug "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
|
105
|
+
Instana.logger.debug e.backtrace.join("\r\n")
|
106
|
+
end
|
107
|
+
|
108
|
+
##
|
109
|
+
# report_entity_data
|
110
|
+
#
|
111
|
+
# Method to report metrics data to the host agent. Every 10 minutes, this
|
112
|
+
# method will also send a process snapshot data.
|
113
|
+
#
|
114
|
+
def report_entity_data(payload)
|
115
|
+
path = "com.instana.plugin.ruby.#{Process.pid}"
|
116
|
+
uri = URI.parse("http://#{@host}:#{@port}/#{path}")
|
117
|
+
req = Net::HTTP::Post.new(uri)
|
118
|
+
|
119
|
+
# Every 5 minutes, send snapshot data as well
|
120
|
+
if (Time.now - @last_snapshot) > 600
|
121
|
+
payload.merge!(@snapshot)
|
122
|
+
@last_snapshot = Time.now
|
123
|
+
end
|
124
|
+
|
22
125
|
req['Accept'] = 'application/json'
|
23
126
|
req['Content-Type'] = 'application/json'
|
24
127
|
req.body = payload.to_json
|
25
128
|
|
129
|
+
#Instana.logger.debug "Posting metrics to #{path}: #{payload.to_json}"
|
130
|
+
|
26
131
|
response = nil
|
27
132
|
Net::HTTP.start(uri.hostname, uri.port) do |http|
|
28
133
|
response = http.request(req)
|
29
134
|
end
|
30
|
-
|
135
|
+
|
136
|
+
# If snapshot data is in the payload and last response
|
137
|
+
# was ok then delete the snapshot data. Otherwise let it
|
138
|
+
# ride for another run.
|
139
|
+
if response.code.to_i == 200
|
140
|
+
@snapshot.each do |k, v|
|
141
|
+
payload.delete(k)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
Instana.logger.debug response.code unless response.code.to_i == 200
|
145
|
+
@last_entity_response = response.code.to_i
|
146
|
+
rescue => e
|
147
|
+
Instana.logger.debug "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
|
148
|
+
Instana.logger.debug e.backtrace.join("\r\n")
|
149
|
+
end
|
150
|
+
|
151
|
+
##
|
152
|
+
# host_agent_ready?
|
153
|
+
#
|
154
|
+
# Check that the host agent is available and can be contacted.
|
155
|
+
#
|
156
|
+
def host_agent_ready?
|
157
|
+
uri = URI.parse("http://#{@host}:#{@port}/")
|
158
|
+
req = Net::HTTP::Get.new(uri)
|
159
|
+
|
160
|
+
req['Accept'] = 'application/json'
|
161
|
+
req['Content-Type'] = 'application/json'
|
162
|
+
|
163
|
+
::Instana.logger.debug "Checking agent availability...."
|
164
|
+
|
165
|
+
response = nil
|
166
|
+
Net::HTTP.start(uri.hostname, uri.port) do |http|
|
167
|
+
response = http.request(req)
|
168
|
+
end
|
169
|
+
|
170
|
+
if response.code.to_i != 200
|
171
|
+
Instana.logger.debug "Host agent returned #{response.code}"
|
172
|
+
false
|
173
|
+
else
|
174
|
+
true
|
175
|
+
end
|
176
|
+
rescue Errno::ECONNREFUSED => e
|
177
|
+
Instana.logger.debug "Agent not responding: #{e.inspect}"
|
178
|
+
return false
|
179
|
+
rescue => e
|
180
|
+
Instana.logger.debug "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
|
181
|
+
Instana.logger.debug e.backtrace.join("\r\n")
|
182
|
+
return false
|
31
183
|
end
|
32
184
|
end
|
33
185
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'timers'
|
2
|
+
require 'instana/collectors/gc'
|
3
|
+
require 'instana/collectors/memory'
|
4
|
+
require 'instana/collectors/thread'
|
5
|
+
|
6
|
+
module Instana
|
7
|
+
module Collector
|
8
|
+
class << self
|
9
|
+
attr_accessor :interval
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
if ENV.key?('INSTANA_GEM_DEV')
|
15
|
+
::Instana::Collector.interval = 3
|
16
|
+
else
|
17
|
+
::Instana::Collector.interval = 1
|
18
|
+
end
|
19
|
+
|
20
|
+
::Thread.new do
|
21
|
+
timers = ::Timers::Group.new
|
22
|
+
payload = {}
|
23
|
+
|
24
|
+
timers.every(::Instana::Collector.interval) {
|
25
|
+
|
26
|
+
# Check if we forked (unicorn, puma) and
|
27
|
+
# if so, re-announce the process sensor
|
28
|
+
if ::Instana.pid_change?
|
29
|
+
::Instana.logger.debug "Detected a fork (old: #{::Instana.pid} new: #{::Process.pid}). Re-announcing sensor."
|
30
|
+
::Instana.pid = Process.pid
|
31
|
+
Instana.agent.announce_sensor
|
32
|
+
end
|
33
|
+
|
34
|
+
::Instana.collectors.each do |c|
|
35
|
+
metrics = c.collect
|
36
|
+
if metrics
|
37
|
+
payload[c.payload_key] = metrics
|
38
|
+
else
|
39
|
+
payload.delete(c.payload_key)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Report all the collected goodies
|
44
|
+
::Instana.agent.report_entity_data(payload)
|
45
|
+
}
|
46
|
+
loop { timers.wait }
|
47
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Instana
|
2
|
+
module Collector
|
3
|
+
class GC
|
4
|
+
attr_accessor :payload_key
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@payload_key = :gc
|
8
|
+
@last_report = {}
|
9
|
+
@this_gc = {}
|
10
|
+
@last_major_count = 0
|
11
|
+
@last_minor_count = 0
|
12
|
+
::GC::Profiler.enable
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# collect
|
17
|
+
#
|
18
|
+
# To collect garbage collector related metrics.
|
19
|
+
#
|
20
|
+
def collect
|
21
|
+
@this_gc.clear
|
22
|
+
stats = ::GC.stat
|
23
|
+
|
24
|
+
# Time spent in GC. Report in milliseconds
|
25
|
+
@this_gc[:totalTime] = ::GC::Profiler.total_time * 1000
|
26
|
+
::GC::Profiler.clear
|
27
|
+
|
28
|
+
# GC metrics only available on newer Ruby versions
|
29
|
+
if RUBY_VERSION >= '2.1'
|
30
|
+
# GC runs. Calculate how many have occurred since the last call
|
31
|
+
@this_gc[:minorGcs] = stats[:minor_gc_count] - @last_minor_count
|
32
|
+
@this_gc[:majorGcs] = stats[:major_gc_count] - @last_major_count
|
33
|
+
|
34
|
+
# Store these counts so that we have something to compare to next
|
35
|
+
# time around.
|
36
|
+
@last_major_count = stats[:major_gc_count]
|
37
|
+
@last_minor_count = stats[:minor_gc_count]
|
38
|
+
end
|
39
|
+
|
40
|
+
# GC Heap
|
41
|
+
@this_gc[:heap_live] = stats[:heap_live_slot] || stats[:heap_live_slots] || stats[:heap_live_num]
|
42
|
+
@this_gc[:heap_free] = stats[:heap_free_slot] || stats[:heap_free_slots] || stats[:heap_free_num]
|
43
|
+
|
44
|
+
@this_gc = ::Instana::Util.enforce_deltas(@this_gc, @last_report)
|
45
|
+
|
46
|
+
unless @this_gc.empty?
|
47
|
+
@last_report.merge!(@this_gc)
|
48
|
+
@this_gc
|
49
|
+
else
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
rescue => e
|
53
|
+
::Instana.logger.debug "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
|
54
|
+
::Instana.logger.debug e.backtrace.join("\r\n")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Register the metrics collector if enabled
|
61
|
+
if ::Instana.config[:metrics][:gc][:enabled]
|
62
|
+
::Instana.collectors << ::Instana::Collector::GC.new
|
63
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'get_process_mem'
|
2
|
+
|
3
|
+
module Instana
|
4
|
+
module Collector
|
5
|
+
class Memory
|
6
|
+
attr_accessor :payload_key
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@payload_key = :memory
|
10
|
+
@last_report = {}
|
11
|
+
@this_mem = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
##
|
15
|
+
# collect
|
16
|
+
#
|
17
|
+
# To collect process memory usage.
|
18
|
+
#
|
19
|
+
def collect
|
20
|
+
@this_mem.clear
|
21
|
+
@this_mem[:rss_size] = ::GetProcessMem.new(Process.pid).kb
|
22
|
+
|
23
|
+
@this_mem = ::Instana::Util.enforce_deltas(@this_mem, @last_report)
|
24
|
+
unless @this_mem.empty?
|
25
|
+
@last_report.merge!(@this_mem)
|
26
|
+
@this_mem
|
27
|
+
else
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
rescue => e
|
31
|
+
::Instana.logger.debug "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
|
32
|
+
::Instana.logger.debug e.backtrace.join("\r\n")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Register the metrics collector if enabled
|
39
|
+
if ::Instana.config[:metrics][:memory][:enabled]
|
40
|
+
::Instana.collectors << ::Instana::Collector::Memory.new
|
41
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Instana
|
2
|
+
module Collector
|
3
|
+
class Thread
|
4
|
+
attr_accessor :payload_key
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@payload_key = :thread
|
8
|
+
@last_report = {}
|
9
|
+
@this_count = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
##
|
13
|
+
# collect
|
14
|
+
#
|
15
|
+
# To collect thread count
|
16
|
+
#
|
17
|
+
def collect
|
18
|
+
@this_count[:count] = ::Thread.list.count
|
19
|
+
|
20
|
+
@this_count = ::Instana::Util.enforce_deltas(@this_count, @last_report)
|
21
|
+
|
22
|
+
unless @this_count.empty?
|
23
|
+
@last_report.merge!(@this_count)
|
24
|
+
@this_count
|
25
|
+
else
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
rescue => e
|
29
|
+
::Instana.logger.debug "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
|
30
|
+
::Instana.logger.debug e.backtrace.join("\r\n")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Register the metrics collector if enabled
|
37
|
+
if ::Instana.config[:metrics][:thread][:enabled]
|
38
|
+
::Instana.collectors << ::Instana::Collector::Thread.new
|
39
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Instana
|
2
|
+
class Config
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@config = {}
|
6
|
+
@config[:agent_host] = '127.0.0.1'
|
7
|
+
@config[:agent_port] = 42699
|
8
|
+
@config[:metrics] = {}
|
9
|
+
@config[:metrics][:gc] = { :enabled => true }
|
10
|
+
@config[:metrics][:memory] = { :enabled => true }
|
11
|
+
@config[:metrics][:thread] = { :enabled => true }
|
12
|
+
end
|
13
|
+
|
14
|
+
def [](key)
|
15
|
+
@config[key.to_sym]
|
16
|
+
end
|
17
|
+
|
18
|
+
def []=(key, value)
|
19
|
+
@config[key.to_sym] = value
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
::Instana.config = ::Instana::Config.new
|
data/lib/instana/util.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
module Instana
|
2
|
+
module Util
|
3
|
+
##
|
4
|
+
# enforce_deltas
|
5
|
+
#
|
6
|
+
# Take two hashes, and make sure candidate does not have
|
7
|
+
# any of the same values as `last`. We only report
|
8
|
+
# when values change.
|
9
|
+
#
|
10
|
+
# Note this is not recursive, so only pass in the single
|
11
|
+
# hashes that you want delta reporting with.
|
12
|
+
#
|
13
|
+
def self.enforce_deltas(candidate, last)
|
14
|
+
return unless last.is_a?(Hash)
|
15
|
+
|
16
|
+
candidate.each do |k,v|
|
17
|
+
if candidate[k] == last[k]
|
18
|
+
candidate.delete(k)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
candidate
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Debugging helper method
|
27
|
+
#
|
28
|
+
def self.pry!
|
29
|
+
# Only valid for development or test environments
|
30
|
+
#env = ENV['RACK_ENV'] || ENV['RAILS_ENV']
|
31
|
+
#return unless %w(development, test).include? env
|
32
|
+
|
33
|
+
if RUBY_VERSION > '1.8.7'
|
34
|
+
require 'pry-byebug'
|
35
|
+
|
36
|
+
if defined?(PryByebug)
|
37
|
+
Pry.commands.alias_command 'c', 'continue'
|
38
|
+
Pry.commands.alias_command 's', 'step'
|
39
|
+
Pry.commands.alias_command 'n', 'next'
|
40
|
+
Pry.commands.alias_command 'f', 'finish'
|
41
|
+
|
42
|
+
Pry::Commands.command(/^$/, 'repeat last command') do
|
43
|
+
_pry_.run_command Pry.history.to_a.last
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
binding.pry
|
48
|
+
else
|
49
|
+
require 'ruby-debug'; debugger
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/instana/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: instana
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Giacomo Lombardo
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,7 +52,49 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '5.0'
|
55
|
-
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: sys-proctable
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.1.3
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.1.3
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: get_process_mem
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.2.1
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.2.1
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: timers
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 4.1.0
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 4.1.0
|
97
|
+
description: Provides Ruby sensor instrumentation for Instana.
|
56
98
|
email:
|
57
99
|
- pglombardo@gmail.com
|
58
100
|
executables: []
|
@@ -69,6 +111,12 @@ files:
|
|
69
111
|
- instana.gemspec
|
70
112
|
- lib/instana.rb
|
71
113
|
- lib/instana/agent.rb
|
114
|
+
- lib/instana/collectors.rb
|
115
|
+
- lib/instana/collectors/gc.rb
|
116
|
+
- lib/instana/collectors/memory.rb
|
117
|
+
- lib/instana/collectors/thread.rb
|
118
|
+
- lib/instana/config.rb
|
119
|
+
- lib/instana/util.rb
|
72
120
|
- lib/instana/version.rb
|
73
121
|
homepage: https://www.instana.com/
|
74
122
|
licenses: []
|
@@ -81,16 +129,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
81
129
|
requirements:
|
82
130
|
- - ">="
|
83
131
|
- !ruby/object:Gem::Version
|
84
|
-
version: '0'
|
132
|
+
version: '2.0'
|
85
133
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
134
|
requirements:
|
87
|
-
- - "
|
135
|
+
- - ">"
|
88
136
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
137
|
+
version: 1.3.1
|
90
138
|
requirements: []
|
91
139
|
rubyforge_project:
|
92
140
|
rubygems_version: 2.5.1
|
93
141
|
signing_key:
|
94
142
|
specification_version: 4
|
95
|
-
summary:
|
143
|
+
summary: Ruby sensor for Instana
|
96
144
|
test_files: []
|