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 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', :enabled => Rails.env.production?)
14
+ I = Instrumental::Agent.new('YOUR_API_KEY', :test_mode => !Rails.env.production?)
15
15
 
16
- If you're already using EventMachine elsewhere, or are hosted on Heroku, then you will need to disable the reactor loop startup.
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.
@@ -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 = { :enabled => true }
43
- options = default_options.merge(options)
44
- @api_key = api_key
45
- if options[:collector]
46
- @host, @port = options[:collector].split(':')
47
- @port = (@port || 8000).to_i
48
- else
49
- @host = 'instrumentalapp.com'
50
- @port = 8000
51
- end
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
- send_command("gauge", metric, value, time.to_i)
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
- send_command("increment", metric, value, time.to_i)
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 0.0"
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
@@ -1,3 +1,3 @@
1
1
  module Instrumental
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
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: 23
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 2
8
+ - 3
9
9
  - 0
10
- version: 0.2.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-15 00:00:00 -05:00
20
+ date: 2011-11-17 00:00:00 -05:00
21
21
  default_executable:
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency