instrumental_agent 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +5 -4
- data/bin/watch_server.rb +77 -3
- data/instrumental_agent.gemspec +2 -2
- data/lib/instrumental/agent.rb +21 -9
- data/lib/instrumental/version.rb +2 -2
- data/spec/agent_spec.rb +23 -0
- data/spec/spec_helper.rb +0 -1
- metadata +6 -4
data/README.rdoc
CHANGED
@@ -6,16 +6,17 @@ Instrument anything.
|
|
6
6
|
|
7
7
|
Add the gem to your Gemfile.
|
8
8
|
|
9
|
-
gem '
|
9
|
+
gem 'instrumental_agent'
|
10
10
|
|
11
11
|
Head over to instrumentalapp.com and setup an account, then
|
12
12
|
initialize the agent.
|
13
13
|
|
14
|
-
I = Instrumental::Agent.new('YOUR_API_KEY')
|
14
|
+
I = Instrumental::Agent.new('YOUR_API_KEY', :enabled => Rails.env.production?)
|
15
15
|
|
16
|
-
|
16
|
+
If you already use EventMachine elsewhere, or are hosted on heroku
|
17
|
+
then you will need to disable the reactor loop startup like so:
|
17
18
|
|
18
|
-
I = Instrumental::Agent.new('YOUR_API_KEY', :start_reactor => false)
|
19
|
+
I = Instrumental::Agent.new('YOUR_API_KEY', :enabled => Rails.env.production?, :start_reactor => false)
|
19
20
|
|
20
21
|
Now you can begin to use instrumental to track your application
|
21
22
|
|
data/bin/watch_server.rb
CHANGED
@@ -123,12 +123,86 @@ class SystemInspector
|
|
123
123
|
end
|
124
124
|
end
|
125
125
|
end
|
126
|
+
|
127
|
+
module Linux
|
128
|
+
def self.load_cpu
|
129
|
+
output = { :gauges => {} }
|
130
|
+
output[:gauges].merge!(cpu)
|
131
|
+
output[:gauges].merge!(loadavg)
|
132
|
+
output
|
133
|
+
end
|
134
|
+
|
135
|
+
def self.cpu
|
136
|
+
cpu, user, nice, system, idle, iowait = `cat /proc/stat | grep cpu[^0-9]`.chomp.split(/\s+/)
|
137
|
+
total = user.to_i + system.to_i + idle.to_i + iowait.to_i
|
138
|
+
{
|
139
|
+
'cpu.user' => (user.to_f / total) * 100,
|
140
|
+
'cpu.system' => (system.to_f / total) * 100,
|
141
|
+
'cpu.idle' => (idle.to_f / total) * 100,
|
142
|
+
'cpu.iowait' => (iowait.to_f / total) * 100,
|
143
|
+
}
|
144
|
+
end
|
145
|
+
|
146
|
+
def self.loadavg
|
147
|
+
min_1, min_5, min_15 = `cat /proc/loadavg`.split(/\s+/)
|
148
|
+
{
|
149
|
+
'load.1min' => min_1.to_f,
|
150
|
+
'load.5min' => min_5.to_f,
|
151
|
+
'load.15min' => min_15.to_f,
|
152
|
+
}
|
153
|
+
end
|
154
|
+
|
155
|
+
def self.load_memory
|
156
|
+
output = { :gauges => {} }
|
157
|
+
output[:gauges].merge!(memory)
|
158
|
+
output[:gauges].merge!(swap)
|
159
|
+
output
|
160
|
+
end
|
161
|
+
|
162
|
+
def self.memory
|
163
|
+
_, total, used, free, shared, buffers, cached = `free -k -o | grep Mem`.chomp.split(/\s+/)
|
164
|
+
{
|
165
|
+
'memory.used_mb' => used.to_f / 1024,
|
166
|
+
'memory.free_mb' => free.to_f / 1024,
|
167
|
+
'memory.buffers_mb' => buffers.to_f / 1024,
|
168
|
+
'memory.cached_mb' => cached.to_f / 1024,
|
169
|
+
'memory.free_percent' => (free.to_f / total.to_f) * 100,
|
170
|
+
}
|
171
|
+
end
|
172
|
+
|
173
|
+
def self.swap
|
174
|
+
_, total, used, free = `free -k -o | grep Swap`.chomp.split(/\s+/)
|
175
|
+
{
|
176
|
+
'swap.used_mb' => used.to_f / 1024,
|
177
|
+
'swap.free_mb' => free.to_f / 1024,
|
178
|
+
'swap.free_percent' => (free.to_f / total.to_f) * 100,
|
179
|
+
}
|
180
|
+
end
|
181
|
+
|
182
|
+
def self.load_disks
|
183
|
+
{ :gauges => disks }
|
184
|
+
end
|
185
|
+
|
186
|
+
def self.disks
|
187
|
+
output = {}
|
188
|
+
`df -Pk`.split("\n").grep(%r{^/dev/}).each do |line|
|
189
|
+
device, total, used, available, capacity, mount = line.split(/\s+/)
|
190
|
+
names = [File.basename(device)]
|
191
|
+
names << 'root' if mount == '/'
|
192
|
+
names.each do |name|
|
193
|
+
output["disk.#{name}.total_mb"] = total.to_f / 1024
|
194
|
+
output["disk.#{name}.used_mb"] = used.to_f / 1024
|
195
|
+
output["disk.#{name}.available_mb"] = available.to_f / 1024
|
196
|
+
output["disk.#{name}.available_percent"] = available.to_f / total.to_f * 100
|
197
|
+
end
|
198
|
+
end
|
199
|
+
output
|
200
|
+
end
|
201
|
+
end
|
126
202
|
end
|
127
203
|
|
128
|
-
# TODO: swap
|
129
204
|
# TODO: utilization
|
130
205
|
|
131
|
-
|
132
206
|
token, collector = *ARGV
|
133
207
|
unless token
|
134
208
|
puts "Usage: #{$0} <token> [collector]"
|
@@ -147,5 +221,5 @@ loop do
|
|
147
221
|
I.gauge("#{host}.#{stat}", value)
|
148
222
|
end
|
149
223
|
# I.increment("#{host}.#{stat}", delta)
|
150
|
-
sleep
|
224
|
+
sleep 10
|
151
225
|
end
|
data/instrumental_agent.gemspec
CHANGED
@@ -4,8 +4,8 @@ require "instrumental/version"
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "instrumental_agent"
|
6
6
|
s.version = Instrumental::VERSION
|
7
|
-
s.authors = ["Elijah Miller", "Christopher Zelenak"]
|
8
|
-
s.email = ["elijah.miller@gmail.com", "netshade@gmail.com"]
|
7
|
+
s.authors = ["Elijah Miller", "Christopher Zelenak", "Kristopher Chambers"]
|
8
|
+
s.email = ["elijah.miller@gmail.com", "netshade@gmail.com", 'kristopher.chambers@gmail.com']
|
9
9
|
s.homepage = "http://github.com/fastestforward/instrumental_agent"
|
10
10
|
s.summary = %q{Agent for reporting data to instrumentalapp.com}
|
11
11
|
s.description = %q{Keep track of anything.}
|
data/lib/instrumental/agent.rb
CHANGED
@@ -9,7 +9,7 @@ require 'logger'
|
|
9
9
|
module Instrumental
|
10
10
|
class Agent
|
11
11
|
attr_accessor :host, :port
|
12
|
-
attr_reader :connection
|
12
|
+
attr_reader :connection, :enabled
|
13
13
|
|
14
14
|
def self.start_reactor
|
15
15
|
unless EM.reactor_running?
|
@@ -98,7 +98,7 @@ module Instrumental
|
|
98
98
|
# Instrumental::Agent.new(API_KEY)
|
99
99
|
# Instrumental::Agent.new(API_KEY, :collector => 'hostname:port')
|
100
100
|
def initialize(api_key, options = {})
|
101
|
-
default_options = { :start_reactor => true }
|
101
|
+
default_options = { :start_reactor => true, :enabled => true }
|
102
102
|
options = default_options.merge(options)
|
103
103
|
@api_key = api_key
|
104
104
|
if options[:collector]
|
@@ -109,10 +109,16 @@ module Instrumental
|
|
109
109
|
@port = 8000
|
110
110
|
end
|
111
111
|
|
112
|
-
|
112
|
+
@enabled = options[:enabled]
|
113
113
|
|
114
|
-
|
115
|
-
|
114
|
+
if @enabled
|
115
|
+
if options[:start_reactor]
|
116
|
+
self.class.start_reactor
|
117
|
+
end
|
118
|
+
|
119
|
+
EM.next_tick do
|
120
|
+
@connection = EM.connect host, port, ServerConnection, self, api_key
|
121
|
+
end
|
116
122
|
end
|
117
123
|
end
|
118
124
|
|
@@ -133,6 +139,10 @@ module Instrumental
|
|
133
139
|
send_command("increment", metric, value, time.to_i)
|
134
140
|
end
|
135
141
|
|
142
|
+
def enabled?
|
143
|
+
@enabled
|
144
|
+
end
|
145
|
+
|
136
146
|
def connected?
|
137
147
|
connection && connection.connected
|
138
148
|
end
|
@@ -158,10 +168,12 @@ module Instrumental
|
|
158
168
|
end
|
159
169
|
|
160
170
|
def send_command(cmd, *args)
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
171
|
+
if enabled?
|
172
|
+
cmd = "%s %s\n" % [cmd, args.collect(&:to_s).join(" ")]
|
173
|
+
logger.debug "Sending: #{cmd.chomp}"
|
174
|
+
EM.next_tick do
|
175
|
+
connection.send_data(cmd)
|
176
|
+
end
|
165
177
|
end
|
166
178
|
end
|
167
179
|
|
data/lib/instrumental/version.rb
CHANGED
data/spec/agent_spec.rb
CHANGED
@@ -1,5 +1,28 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
describe Instrumental::Agent, "disabled" do
|
4
|
+
before do
|
5
|
+
random_port = Time.now.to_i % rand(2000)
|
6
|
+
base_port = 4000
|
7
|
+
@port = base_port + random_port
|
8
|
+
TestServer.start(@port)
|
9
|
+
end
|
10
|
+
|
11
|
+
after do
|
12
|
+
TestServer.stop
|
13
|
+
end
|
14
|
+
|
15
|
+
subject { Instrumental::Agent.new('test_token', :collector => "127.0.0.1:#{@port}", :enabled => false) }
|
16
|
+
|
17
|
+
it 'should not connect to the server' do
|
18
|
+
subject.gauge('gauge_test', 123)
|
19
|
+
EM.next do
|
20
|
+
TestServer.last.should be_nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
3
26
|
describe Instrumental::Agent do
|
4
27
|
before do
|
5
28
|
random_port = Time.now.to_i % rand(2000)
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,22 +1,23 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: instrumental_agent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 2
|
10
|
+
version: 0.1.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Elijah Miller
|
14
14
|
- Christopher Zelenak
|
15
|
+
- Kristopher Chambers
|
15
16
|
autorequire:
|
16
17
|
bindir: bin
|
17
18
|
cert_chain: []
|
18
19
|
|
19
|
-
date: 2011-10-
|
20
|
+
date: 2011-10-30 00:00:00 -04:00
|
20
21
|
default_executable:
|
21
22
|
dependencies:
|
22
23
|
- !ruby/object:Gem::Dependency
|
@@ -108,6 +109,7 @@ description: Keep track of anything.
|
|
108
109
|
email:
|
109
110
|
- elijah.miller@gmail.com
|
110
111
|
- netshade@gmail.com
|
112
|
+
- kristopher.chambers@gmail.com
|
111
113
|
executables:
|
112
114
|
- watch_server.rb
|
113
115
|
extensions: []
|