instrumental_agent 0.2.0 → 0.3.0
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.
- 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
|