nosey 0.0.6 → 0.0.7

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.
@@ -9,4 +9,8 @@ Nosey::Munin.graph do
9
9
  category 'App'
10
10
  title 'My Cool Chart'
11
11
  vertical_label 'Response Time (seconds)'
12
+ filter do |name|
13
+ # Only show these 3 dudes
14
+ %w[min max avg].include? name
15
+ end
12
16
  end
@@ -13,7 +13,7 @@ EM.run {
13
13
  puts "Starting nosey test server"
14
14
  EventMachine::Nosey::SocketServer.start(probes.report, '/tmp/nosey_test.socket')
15
15
 
16
- EM::add_periodic_timer(1) do
16
+ EM::add_periodic_timer(2) do
17
17
  probes.increment 'ticks'
18
18
  probes.avg 'avg', rand
19
19
  probes.min 'min', rand
@@ -13,15 +13,23 @@ module EventMachine
13
13
  @report = report
14
14
  end
15
15
 
16
- # Dump out the stats and close down the connection
17
- def post_init
18
- begin
16
+ def receive_data(data)
17
+ buffer << data
18
+ # Stop buffering if a newline is detected and process command
19
+ process_command buffer.strip if data =~ /\n/
20
+ end
21
+
22
+ def process_command(command)
23
+ case command
24
+ when 'READ' # This is for more normal uses cases where you want to watch stats
25
+ send_data report.to_s
26
+ when 'RESET' # This is used primarly by munin, or other tools that can't track state.
19
27
  send_data report.to_s
20
- rescue => e
21
- send_data "Exception! #{e}\n#{e.backtrace}"
22
- ensure
23
- close_connection
28
+ report.reset
29
+ else
30
+ send_data "No Comprende. send 'read' to see stats or 'reset' to read and reset."
24
31
  end
32
+ close_connection_after_writing
25
33
  end
26
34
 
27
35
  # A nice short-cut for peeps who aren't familar with EM to fire up
@@ -29,6 +37,11 @@ module EventMachine
29
37
  def self.start(report, host=SocketServer::Host, port=SocketServer::Port)
30
38
  EventMachine::start_server(host, port, self, report)
31
39
  end
40
+
41
+ private
42
+ def buffer
43
+ @buffer ||= ""
44
+ end
32
45
  end
33
46
  end
34
47
  end
data/lib/nosey/munin.rb CHANGED
@@ -24,7 +24,7 @@ module Nosey
24
24
 
25
25
  # Parse a Nosey socket for Munin
26
26
  class Graph
27
- attr_accessor :data, :title, :vertical_label, :category
27
+ attr_accessor :data, :title, :vertical_label, :category, :filter
28
28
  attr_writer :probe_set
29
29
 
30
30
  def initialize(data=nil)
@@ -67,13 +67,16 @@ module Nosey
67
67
  def munin_hash(root_key=nil,hash=self.probe_set)
68
68
  # TODO perform processing for more complicated probes, like samplers, etc
69
69
  hash.reduce({}) do |memo, (name, value)|
70
- case value
71
- when Hash # Its nested, go deep! Oooo yeah!
72
- munin_hash(format_field(root_key, name), value).each do |name, value|
73
- memo[format_field(root_key, name)] = value.to_a
70
+ # If there's NOt a filter OR we have a filter and it filters...
71
+ if !filter or (filter and filter.call(name))
72
+ case value
73
+ when Hash # Its nested, go deep! Oooo yeah!
74
+ munin_hash(format_field(root_key, name), value).each do |name, value|
75
+ memo[format_field(root_key, name)] = value.to_a
76
+ end
77
+ else # Its cool, return this mmmkay? Sheesh man
78
+ memo[format_field(root_key, name)] = [name, value]
74
79
  end
75
- else # Its cool, return this mmmkay? Sheesh man
76
- memo[format_field(root_key, name)] = [name, value]
77
80
  end
78
81
  memo
79
82
  end
@@ -88,10 +91,12 @@ module Nosey
88
91
  @title ||= probe_set
89
92
  end
90
93
 
91
- private
92
- def process_filter(hash)
93
- hash.select{}
94
+ # Setup a filter from the graphing DSL so that we can grep out specific probes
95
+ def filter(&block)
96
+ block_given? ? @filter = block : @filter
94
97
  end
98
+
99
+ private
95
100
  # http://munin-monitoring.org/wiki/notes_on_datasource_names
96
101
  # Notes on field names
97
102
  # Each data source in a plugin must be identified by a field name. The following describes the name of the field:
@@ -114,6 +119,12 @@ module Nosey
114
119
 
115
120
  # A little DSL that lets us set the socket and report name we'll read
116
121
  class Graph::DSL
122
+ # We use this command to read Nosey data from the socket, but more
123
+ # importantly, reset it so that when we come back around the next time
124
+ # we can grab all the data that's occured since that time.
125
+ ResetCommand = "RESET\n"
126
+
127
+ # Default munin category. Zie app!
117
128
  Category = 'App'
118
129
 
119
130
  def initialize(&block)
@@ -147,6 +158,11 @@ module Nosey
147
158
  self
148
159
  end
149
160
 
161
+ def filter(&block)
162
+ @filter = block
163
+ self
164
+ end
165
+
150
166
  # Category this thing will be in
151
167
  def category(category=Category)
152
168
  @category = category
@@ -160,6 +176,7 @@ module Nosey
160
176
  c.category = @category
161
177
  c.title = @title
162
178
  c.vertical_label = @vertical_label
179
+ c.filter = @filter
163
180
  end
164
181
  end
165
182
 
@@ -171,7 +188,10 @@ module Nosey
171
188
 
172
189
  # Read the report YAML data from the socket
173
190
  def read_socket
174
- UNIXSocket.new(@host).gets("\n\n")
191
+ p ResetCommand
192
+ socket = UNIXSocket.new(@host)
193
+ socket.puts(ResetCommand)
194
+ socket.gets("\n\n")
175
195
  end
176
196
  end
177
197
  end
data/lib/nosey/probe.rb CHANGED
@@ -27,9 +27,12 @@ module Nosey
27
27
  end
28
28
 
29
29
  class Average < Base
30
+ def initialize(*args)
31
+ super(*args)
32
+ reset
33
+ end
34
+
30
35
  def sample(value)
31
- @sum ||= 0
32
- @count ||= 0
33
36
  @sum += value
34
37
  @count += 1
35
38
  end
@@ -37,6 +40,12 @@ module Nosey
37
40
  def value
38
41
  @sum.to_f / @count.to_f if @sum and @count > 0
39
42
  end
43
+
44
+ def reset
45
+ @sum = 0
46
+ @count = 0
47
+ @count = 0
48
+ end
40
49
  end
41
50
 
42
51
  class Minimum < Base
@@ -147,6 +156,11 @@ module Nosey
147
156
  end
148
157
  end
149
158
 
159
+ # Reset the values in all the probes
160
+ def reset
161
+ probes.each{|_, probe| probe.reset }
162
+ end
163
+
150
164
  private
151
165
  # This factory creates probes based on the methods called from
152
166
  # the instrumentation. If a probe doesn't exist, we create an instance
data/lib/nosey/report.rb CHANGED
@@ -29,6 +29,11 @@ module Nosey
29
29
  }
30
30
  end
31
31
 
32
+ # Reset all the counters in each probe.
33
+ def reset
34
+ probe_sets.each(&:reset)
35
+ end
36
+
32
37
  # String representation of all the probe_sets that's suitable for
33
38
  # flushing out over a socket.
34
39
  def to_s
data/lib/nosey/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Nosey
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  end
data/nosey.gemspec CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.require_paths = ["lib"]
20
20
 
21
21
  s.add_runtime_dependency "eventmachine"
22
+ s.add_runtime_dependency "thor"
22
23
 
23
24
  s.add_development_dependency 'rspec'
24
25
  s.add_development_dependency 'guard-rspec'
@@ -27,4 +28,4 @@ Gem::Specification.new do |s|
27
28
  s.add_development_dependency 'rb-fsevent'
28
29
  s.add_development_dependency 'em-ventually'
29
30
  s.add_development_dependency 'ruby-debug19'
30
- end
31
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+ require 'yaml'
3
+
4
+ describe EventMachine::Nosey::SocketServer do
5
+ include EM::Ventually
6
+
7
+ before(:each) do
8
+ @report = Nosey::Report.new do |r|
9
+ 3.times do |n|
10
+ r.probe_sets << Nosey::Probe::Set.new("Group #{n}") do |set|
11
+ set.increment 'hit'
12
+ set.increment 'hit'
13
+ set.touch 'generated-at'
14
+ set.avg 'zie-number-avg', 1
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ it "should read report data with READ command" do
21
+ EventMachine::Nosey::SocketServer.start @report
22
+ socket = Nosey::Test::ReadSocket.start('/tmp/nosey.socket')
23
+ socket.callback{|data|
24
+ @resp = data
25
+ }
26
+ socket.send_data("READ\n")
27
+
28
+ ly{2}.test{|count| YAML.load(@resp)['Group 0']['hit'] == count }
29
+ end
30
+
31
+ it "should reset report and read data with RESET command" do
32
+ @r1 = @r2 = nil
33
+
34
+ EventMachine::Nosey::SocketServer.start @report
35
+
36
+ s1 = Nosey::Test::ReadSocket.start('/tmp/nosey.socket')
37
+ s2 = Nosey::Test::ReadSocket.start('/tmp/nosey.socket')
38
+
39
+ s1.send_data("RESET\n")
40
+ s1.callback{|data|
41
+ @r1 = data
42
+ s2.send_data("READ\n")
43
+ s2.callback{|data|
44
+ @r2 = data
45
+ }
46
+ }
47
+
48
+ ly{nil}.test{|count| YAML.load(@r2)['Group 0']['hit'] == count }
49
+ end
50
+ end
@@ -43,6 +43,13 @@ describe Nosey::Munin::Graph do
43
43
  end
44
44
  end
45
45
 
46
+ it "should filter" do
47
+ @graph.filter do |name|
48
+ name =~ /chopper-sum|chopper-avg/
49
+ end
50
+ @graph.munin_hash.should have(2).items
51
+ end
52
+
46
53
  context "sample" do
47
54
  before(:each) do
48
55
  @text = @graph.sample
@@ -42,38 +42,88 @@ describe Nosey::Probe::Set do
42
42
  @probes.probe('barf').should be_instance_of(Nosey::Probe::Touch)
43
43
  end
44
44
 
45
+ it "should reset" do
46
+ @probes.touch('barf')
47
+ @probes.reset
48
+ @probes.probe('barf').value.should be_nil
49
+ end
50
+
45
51
  it "should return report" do
46
52
  @probes.report.probe_sets.first.should eql(@probes)
47
53
  end
48
54
  end
49
55
 
50
- describe Nosey::Probe do
51
- it "should calculate sum" do
52
- sum = Nosey::Probe::Sum.new
53
- sum.sample(1)
54
- sum.sample(2)
55
- sum.value.should eql(3)
56
+ describe Nosey::Probe::Sum do
57
+ before(:all) do
58
+ @sum = Nosey::Probe::Sum.new
59
+ end
60
+
61
+ it "should sum" do
62
+ @sum.sample(1)
63
+ @sum.sample(2)
64
+ @sum.value.should eql(3)
65
+ end
66
+
67
+ it "should reset" do
68
+ @sum.sample(1)
69
+ @sum.sample(2)
70
+ @sum.reset
71
+ @sum.value.should be_nil
72
+ end
73
+ end
74
+
75
+ describe Nosey::Probe::Maximum do
76
+ before(:all) do
77
+ @max = Nosey::Probe::Maximum.new
78
+ end
79
+
80
+ it "should know max" do
81
+ @max.sample(1)
82
+ @max.sample(3)
83
+ @max.value.should eql(3)
84
+ end
85
+
86
+ it "should reset" do
87
+ @max.sample(1)
88
+ @max.reset
89
+ @max.value.should be_nil
90
+ end
91
+ end
92
+
93
+ describe Nosey::Probe::Minimum do
94
+ before(:all) do
95
+ @min = Nosey::Probe::Minimum.new
56
96
  end
57
97
 
58
- it "should calculate max" do
59
- max = Nosey::Probe::Maximum.new
60
- max.sample(1)
61
- max.sample(3)
62
- max.value.should eql(3)
98
+ it "should know max" do
99
+ @min.sample(1)
100
+ @min.sample(2)
101
+ @min.value.should eql(1)
63
102
  end
64
103
 
65
- it "should calculate minimum" do
66
- min = Nosey::Probe::Minimum.new
67
- min.sample(1)
68
- min.sample(2)
69
- min.value.should eql(1)
104
+ it "should reset" do
105
+ @min.sample(2)
106
+ @min.reset
107
+ @min.value.should be_nil
70
108
  end
109
+ end
71
110
 
72
- it "should calculate average" do
73
- avg = Nosey::Probe::Average.new
74
- avg.sample(1)
75
- avg.sample(2)
76
- avg.value.should eql(1.5)
111
+ describe Nosey::Probe::Average do
112
+ before(:all) do
113
+ @avg = Nosey::Probe::Average.new
114
+ end
115
+
116
+ it "should know avg" do
117
+ @avg.sample(1)
118
+ @avg.sample(2)
119
+ @avg.value.should eql(1.5)
120
+ end
121
+
122
+ it "should reset" do
123
+ @avg.sample(1)
124
+ @avg.sample(2)
125
+ @avg.reset
126
+ @avg.value.should be_nil
77
127
  end
78
128
  end
79
129
 
@@ -97,6 +147,12 @@ describe Nosey::Probe::Count do
97
147
  it "should set" do
98
148
  @counter.set(0).should eql(0)
99
149
  end
150
+
151
+ it "should reset" do
152
+ @counter.increment(1)
153
+ @counter.reset
154
+ @counter.value.should be_nil
155
+ end
100
156
  end
101
157
 
102
158
  describe Nosey::Probe::Touch do
@@ -1,25 +1 @@
1
- require 'spec_helper'
2
-
3
- describe EventMachine::Nosey::SocketServer do
4
- include EM::Ventually
5
-
6
- before(:each) do
7
- @report = Nosey::Report.new do |r|
8
- 3.times do |n|
9
- r.probe_sets << Nosey::Probe::Set.new("Group #{n}") do |set|
10
- set.increment 'hit'
11
- set.touch 'generated-at'
12
- set.avg 'zie-number-avg', 1
13
- end
14
- end
15
- end
16
- end
17
-
18
- it "should write report to socket" do
19
- EventMachine::Nosey::SocketServer.start @report
20
- Nosey::Test::ReadSocket.start('/tmp/nosey.socket').callback{|data|
21
- @response = data
22
- }
23
- ly{ @response }.test{|response| YAML.load(response).is_a?(Hash) }
24
- end
25
- end
1
+ require 'spec_helper'
data/spec/spec_helper.rb CHANGED
@@ -29,7 +29,7 @@ module Nosey
29
29
  end
30
30
 
31
31
  def self.start(host,port=nil)
32
- EventMachine::connect host, port, self
32
+ EventMachine::connect(host, port, self)
33
33
  end
34
34
 
35
35
  private
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nosey
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-09-16 00:00:00.000000000Z
12
+ date: 2011-09-19 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
16
- requirement: &70339837952660 !ruby/object:Gem::Requirement
16
+ requirement: &70234556114360 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,21 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70339837952660
24
+ version_requirements: *70234556114360
25
+ - !ruby/object:Gem::Dependency
26
+ name: thor
27
+ requirement: &70234556113540 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70234556113540
25
36
  - !ruby/object:Gem::Dependency
26
37
  name: rspec
27
- requirement: &70339837952240 !ruby/object:Gem::Requirement
38
+ requirement: &70234556112860 !ruby/object:Gem::Requirement
28
39
  none: false
29
40
  requirements:
30
41
  - - ! '>='
@@ -32,10 +43,10 @@ dependencies:
32
43
  version: '0'
33
44
  type: :development
34
45
  prerelease: false
35
- version_requirements: *70339837952240
46
+ version_requirements: *70234556112860
36
47
  - !ruby/object:Gem::Dependency
37
48
  name: guard-rspec
38
- requirement: &70339837951820 !ruby/object:Gem::Requirement
49
+ requirement: &70234556110900 !ruby/object:Gem::Requirement
39
50
  none: false
40
51
  requirements:
41
52
  - - ! '>='
@@ -43,10 +54,10 @@ dependencies:
43
54
  version: '0'
44
55
  type: :development
45
56
  prerelease: false
46
- version_requirements: *70339837951820
57
+ version_requirements: *70234556110900
47
58
  - !ruby/object:Gem::Dependency
48
59
  name: guard-bundler
49
- requirement: &70339837951340 !ruby/object:Gem::Requirement
60
+ requirement: &70234556110300 !ruby/object:Gem::Requirement
50
61
  none: false
51
62
  requirements:
52
63
  - - ! '>='
@@ -54,10 +65,10 @@ dependencies:
54
65
  version: '0'
55
66
  type: :development
56
67
  prerelease: false
57
- version_requirements: *70339837951340
68
+ version_requirements: *70234556110300
58
69
  - !ruby/object:Gem::Dependency
59
70
  name: growl
60
- requirement: &70339837950920 !ruby/object:Gem::Requirement
71
+ requirement: &70234556109540 !ruby/object:Gem::Requirement
61
72
  none: false
62
73
  requirements:
63
74
  - - ! '>='
@@ -65,10 +76,10 @@ dependencies:
65
76
  version: '0'
66
77
  type: :development
67
78
  prerelease: false
68
- version_requirements: *70339837950920
79
+ version_requirements: *70234556109540
69
80
  - !ruby/object:Gem::Dependency
70
81
  name: rb-fsevent
71
- requirement: &70339837950360 !ruby/object:Gem::Requirement
82
+ requirement: &70234556108520 !ruby/object:Gem::Requirement
72
83
  none: false
73
84
  requirements:
74
85
  - - ! '>='
@@ -76,10 +87,10 @@ dependencies:
76
87
  version: '0'
77
88
  type: :development
78
89
  prerelease: false
79
- version_requirements: *70339837950360
90
+ version_requirements: *70234556108520
80
91
  - !ruby/object:Gem::Dependency
81
92
  name: em-ventually
82
- requirement: &70339837949880 !ruby/object:Gem::Requirement
93
+ requirement: &70234556107600 !ruby/object:Gem::Requirement
83
94
  none: false
84
95
  requirements:
85
96
  - - ! '>='
@@ -87,10 +98,10 @@ dependencies:
87
98
  version: '0'
88
99
  type: :development
89
100
  prerelease: false
90
- version_requirements: *70339837949880
101
+ version_requirements: *70234556107600
91
102
  - !ruby/object:Gem::Dependency
92
103
  name: ruby-debug19
93
- requirement: &70339837949240 !ruby/object:Gem::Requirement
104
+ requirement: &70234556106180 !ruby/object:Gem::Requirement
94
105
  none: false
95
106
  requirements:
96
107
  - - ! '>='
@@ -98,7 +109,7 @@ dependencies:
98
109
  version: '0'
99
110
  type: :development
100
111
  prerelease: false
101
- version_requirements: *70339837949240
112
+ version_requirements: *70234556106180
102
113
  description: Nosey is a way to instrument your Evented Ruby applications to track
103
114
  counts, aggregates, etc. It was built a Poll Everywhere because we need a way to
104
115
  peer into our Evented apps and grab some basic statistics so that we could graph
@@ -127,6 +138,7 @@ files:
127
138
  - lib/nosey/report.rb
128
139
  - lib/nosey/version.rb
129
140
  - nosey.gemspec
141
+ - spec/lib/eventmachine_spec.rb
130
142
  - spec/lib/nosey/instrumentation_spec.rb
131
143
  - spec/lib/nosey/munin_spec.rb
132
144
  - spec/lib/nosey/probe_spec.rb
@@ -158,6 +170,7 @@ signing_key:
158
170
  specification_version: 3
159
171
  summary: Instrument Ruby EventMachine applications
160
172
  test_files:
173
+ - spec/lib/eventmachine_spec.rb
161
174
  - spec/lib/nosey/instrumentation_spec.rb
162
175
  - spec/lib/nosey/munin_spec.rb
163
176
  - spec/lib/nosey/probe_spec.rb