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 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