instrumental_agent 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +4 -4
- data/lib/instrumental/agent.rb +42 -17
- data/lib/instrumental/version.rb +1 -1
- data/spec/agent_spec.rb +71 -0
- metadata +4 -4
data/README.rdoc
CHANGED
@@ -11,11 +11,9 @@ Add the gem to your Gemfile.
|
|
11
11
|
Visit instrumentalapp.com[instrumentalapp.com] and create an account, then
|
12
12
|
initialize the agent with your API key, found in the Docs section.
|
13
13
|
|
14
|
-
I = Instrumental::Agent.new('YOUR_API_KEY', :
|
14
|
+
I = Instrumental::Agent.new('YOUR_API_KEY', :test_mode => !Rails.env.production?)
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
I = Instrumental::Agent.new('YOUR_API_KEY', :enabled => Rails.env.production?, :start_reactor => false)
|
16
|
+
We recommend setting test_mode to true in dev/test modes so that you don't pollute your production data.
|
19
17
|
|
20
18
|
Now you can begin to use Instrumental to track your application.
|
21
19
|
|
@@ -38,6 +36,8 @@ a shot by initializing it with:
|
|
38
36
|
|
39
37
|
Instrumental::Middleware.boot
|
40
38
|
|
39
|
+
Need to quickly disable the agent? set :enabled to false on initialization and you don't need to change any application code.
|
40
|
+
|
41
41
|
== Troubleshooting & Help
|
42
42
|
|
43
43
|
We are here to help, please email us at mailto:support@instrumentalapp.com.
|
data/lib/instrumental/agent.rb
CHANGED
@@ -15,7 +15,7 @@ module Instrumental
|
|
15
15
|
|
16
16
|
attr_accessor :host, :port
|
17
17
|
attr_reader :connection, :enabled
|
18
|
-
|
18
|
+
|
19
19
|
def self.logger=(l)
|
20
20
|
@logger = l
|
21
21
|
end
|
@@ -39,18 +39,20 @@ module Instrumental
|
|
39
39
|
# Instrumental::Agent.new(API_KEY)
|
40
40
|
# Instrumental::Agent.new(API_KEY, :collector => 'hostname:port')
|
41
41
|
def initialize(api_key, options = {})
|
42
|
-
default_options = {
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
42
|
+
default_options = {
|
43
|
+
:collector => 'instrumentalapp.com:8000',
|
44
|
+
:enabled => true,
|
45
|
+
:test_mode => false,
|
46
|
+
}
|
47
|
+
options = default_options.merge(options)
|
48
|
+
collector = options[:collector].split(':')
|
49
|
+
|
50
|
+
@api_key = api_key
|
51
|
+
@host = collector[0]
|
52
|
+
@port = (collector[1] || 8000).to_i
|
53
|
+
@enabled = options[:enabled]
|
54
|
+
@test_mode = options[:test_mode]
|
52
55
|
|
53
|
-
@enabled = options[:enabled]
|
54
56
|
if @enabled
|
55
57
|
@failures = 0
|
56
58
|
@queue = Queue.new
|
@@ -62,17 +64,30 @@ module Instrumental
|
|
62
64
|
#
|
63
65
|
# agent.gauge('load', 1.23)
|
64
66
|
def gauge(metric, value, time = Time.now)
|
65
|
-
if valid?(metric, value, time)
|
66
|
-
|
67
|
+
if valid?(metric, value, time) &&
|
68
|
+
send_command("gauge", metric, value, time.to_i)
|
69
|
+
value
|
70
|
+
else
|
71
|
+
nil
|
67
72
|
end
|
73
|
+
rescue Exception => e
|
74
|
+
report_exception(e)
|
75
|
+
nil
|
68
76
|
end
|
69
77
|
|
70
78
|
# Increment a metric, optionally more than one or at a specific time.
|
71
79
|
#
|
72
80
|
# agent.increment('users')
|
73
81
|
def increment(metric, value = 1, time = Time.now)
|
74
|
-
valid?(metric, value, time)
|
75
|
-
|
82
|
+
if valid?(metric, value, time) &&
|
83
|
+
send_command("increment", metric, value, time.to_i)
|
84
|
+
value
|
85
|
+
else
|
86
|
+
nil
|
87
|
+
end
|
88
|
+
rescue Exception => e
|
89
|
+
report_exception(e)
|
90
|
+
nil
|
76
91
|
end
|
77
92
|
|
78
93
|
def enabled?
|
@@ -103,14 +118,21 @@ module Instrumental
|
|
103
118
|
true
|
104
119
|
end
|
105
120
|
|
121
|
+
def report_exception(e)
|
122
|
+
logger.error "Exception occurred: #{e.message}"
|
123
|
+
logger.error e.backtrace.join("\n")
|
124
|
+
end
|
125
|
+
|
106
126
|
def send_command(cmd, *args)
|
107
127
|
if enabled?
|
108
128
|
cmd = "%s %s\n" % [cmd, args.collect(&:to_s).join(" ")]
|
109
129
|
if @queue.size < MAX_BUFFER
|
110
130
|
logger.debug "Queueing: #{cmd.chomp}"
|
111
131
|
@queue << cmd
|
132
|
+
cmd
|
112
133
|
else
|
113
134
|
logger.warn "Dropping command, queue full(#{@queue.size}): #{cmd.chomp}"
|
135
|
+
nil
|
114
136
|
end
|
115
137
|
end
|
116
138
|
end
|
@@ -125,12 +147,13 @@ module Instrumental
|
|
125
147
|
end
|
126
148
|
|
127
149
|
def start_connection_thread
|
150
|
+
logger.info "Starting thread"
|
128
151
|
@thread = Thread.new do
|
129
152
|
begin
|
130
153
|
@socket = TCPSocket.new(host, port)
|
131
154
|
@failures = 0
|
132
155
|
logger.info "connected to collector"
|
133
|
-
@socket.puts "hello version
|
156
|
+
@socket.puts "hello version #{Instrumental::VERSION} test_mode #{@test_mode}"
|
134
157
|
@socket.puts "authenticate #{@api_key}"
|
135
158
|
loop do
|
136
159
|
command_and_args = @queue.pop
|
@@ -143,6 +166,7 @@ module Instrumental
|
|
143
166
|
|
144
167
|
if command_and_args == 'exit'
|
145
168
|
logger.info "exiting, #{@queue.size} commands remain"
|
169
|
+
@socket.flush
|
146
170
|
Thread.exit
|
147
171
|
else
|
148
172
|
logger.debug "Sending: #{command_and_args.chomp}"
|
@@ -173,4 +197,5 @@ module Instrumental
|
|
173
197
|
end
|
174
198
|
end
|
175
199
|
end
|
200
|
+
|
176
201
|
end
|
data/lib/instrumental/version.rb
CHANGED
data/spec/agent_spec.rb
CHANGED
@@ -28,6 +28,46 @@ describe Instrumental::Agent, "disabled" do
|
|
28
28
|
|
29
29
|
end
|
30
30
|
|
31
|
+
describe Instrumental::Agent, "enabled in test_mode" do
|
32
|
+
before do
|
33
|
+
@server = TestServer.new
|
34
|
+
@agent = Instrumental::Agent.new('test_token', :collector => @server.host_and_port, :test_mode => true)
|
35
|
+
end
|
36
|
+
|
37
|
+
after do
|
38
|
+
@server.stop
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should connect to the server" do
|
42
|
+
wait
|
43
|
+
@server.connect_count.should == 1
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should announce itself, and include version and test_mode flag" do
|
47
|
+
wait
|
48
|
+
@server.commands[0].should =~ /hello .*version .*test_mode true/
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should authenticate using the token" do
|
52
|
+
wait
|
53
|
+
@server.commands[1].should == "authenticate test_token"
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should report a gauge" do
|
57
|
+
now = Time.now
|
58
|
+
@agent.gauge('gauge_test', 123)
|
59
|
+
wait
|
60
|
+
@server.commands.last.should == "gauge gauge_test 123 #{now.to_i}"
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should report an increment" do
|
64
|
+
now = Time.now
|
65
|
+
@agent.increment("increment_test")
|
66
|
+
wait
|
67
|
+
@server.commands.last.should == "increment increment_test 1 #{now.to_i}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
31
71
|
describe Instrumental::Agent, "enabled" do
|
32
72
|
before do
|
33
73
|
@server = TestServer.new
|
@@ -60,6 +100,13 @@ describe Instrumental::Agent, "enabled" do
|
|
60
100
|
@server.commands.last.should == "gauge gauge_test 123 #{now.to_i}"
|
61
101
|
end
|
62
102
|
|
103
|
+
it "should return the value gauged" do
|
104
|
+
now = Time.now
|
105
|
+
@agent.gauge('gauge_test', 123).should == 123
|
106
|
+
@agent.gauge('gauge_test', 989).should == 989
|
107
|
+
wait
|
108
|
+
end
|
109
|
+
|
63
110
|
it "should report a gauge with a set time" do
|
64
111
|
@agent.gauge('gauge_test', 123, 555)
|
65
112
|
wait
|
@@ -73,6 +120,13 @@ describe Instrumental::Agent, "enabled" do
|
|
73
120
|
@server.commands.last.should == "increment increment_test 1 #{now.to_i}"
|
74
121
|
end
|
75
122
|
|
123
|
+
it "should return the value incremented by" do
|
124
|
+
now = Time.now
|
125
|
+
@agent.increment("increment_test").should == 1
|
126
|
+
@agent.increment("increment_test", 5).should == 5
|
127
|
+
wait
|
128
|
+
end
|
129
|
+
|
76
130
|
it "should report an increment a value" do
|
77
131
|
now = Time.now
|
78
132
|
@agent.increment("increment_test", 2)
|
@@ -94,4 +148,21 @@ describe Instrumental::Agent, "enabled" do
|
|
94
148
|
@server.connect_count.should == 2
|
95
149
|
@server.commands.last.should == "increment reconnect_test 1 1234"
|
96
150
|
end
|
151
|
+
|
152
|
+
it "should never let an exception reach the user" do
|
153
|
+
@agent.stub!(:send_command).and_raise(Exception.new("Test Exception"))
|
154
|
+
@agent.increment('throws_exception', 2).should be_nil
|
155
|
+
wait
|
156
|
+
@agent.gauge('throws_exception', 234).should be_nil
|
157
|
+
wait
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should return nil if the user overflows the MAX_BUFFER" do
|
161
|
+
thread = @agent.instance_variable_get(:@thread)
|
162
|
+
thread.kill
|
163
|
+
1.upto(Instrumental::Agent::MAX_BUFFER) do
|
164
|
+
@agent.increment("test").should == 1
|
165
|
+
end
|
166
|
+
@agent.increment("test").should be_nil
|
167
|
+
end
|
97
168
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: instrumental_agent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 3
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.3.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Elijah Miller
|
@@ -17,7 +17,7 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2011-11-
|
20
|
+
date: 2011-11-17 00:00:00 -05:00
|
21
21
|
default_executable:
|
22
22
|
dependencies:
|
23
23
|
- !ruby/object:Gem::Dependency
|