rackamole 0.2.7 → 0.2.8

Sign up to get free protection for your applications and to get access to all the features.
data/HISTORY CHANGED
@@ -37,4 +37,7 @@
37
37
 
38
38
  0.2.7
39
39
  * Bug fixes and cleanup
40
- * Added user_agent parsing. now extracting os/platform/version as well as browser type and version.
40
+ * Added user_agent parsing. now extracting os/platform/version as well as browser type and version.
41
+
42
+ 0.2.8
43
+ * Formatted email alerts so they are a little more readable
@@ -17,19 +17,19 @@ module Rackamole::Alert
17
17
  # or persisted in the db regardless.
18
18
  #
19
19
  # === Parameters:
20
- # options :: Hash minimaly containing :from for the from address. Must be a valid domain.
20
+ # options :: Mole options. The :email key minimaly contains :from for the from address. Must be a valid domain.
21
21
  # :: And a :to, n array of email addresses for recipients to be notified.
22
22
  # args :: The gathered information from the mole.
23
23
  #
24
24
  def self.deliver_alert( logger, options, args )
25
- params = options.clone
26
- params[:to] = options[:to].join( ", " )
27
- params[:subject] = "[M()le] (#{alert_type( args )}#{request_time?( args )}) -#{args[:app_name]}@#{args[:host]}- for user #{args[:user_name]}"
28
-
29
- content = []
30
- dump( content, args, 0 )
31
- content = content.join( "\n" )
25
+ @options = options
26
+ opts = options[:email]
27
+ params = opts.clone
28
+ params[:to] = opts[:to].join( ", " )
29
+ params[:subject] = "RackAmole <#{alert_type( args )}> #{request_time?( args )} on #{args[:app_name]}.#{args[:host]} for user #{args[:user_name]}"
32
30
 
31
+ @args = args
32
+
33
33
  tmpl = File.join( template_root, %w[alert.erb] )
34
34
  template = Erubis::Eruby.new( IO.read( tmpl ), :trim => true )
35
35
 
@@ -39,15 +39,85 @@ module Rackamole::Alert
39
39
  Pony.mail( params )
40
40
  output
41
41
  rescue => boom
42
+ puts boom
43
+ boom.backtrace.each { |l| puts l }
42
44
  logger.error( "Rackamole email alert failed with error `#{boom}" )
43
45
  end
44
46
 
45
- # =========================================================================
47
+ def self.section( title )
48
+ buff = []
49
+ # buff << "-"*80
50
+ buff << "-"*40
51
+ buff << "o #{title.capitalize}\n"
52
+ buff << self.send( title.downcase )
53
+ buff << "\n"
54
+ buff.join( "\n" )
55
+ end
56
+
57
+ # =========================================================================
46
58
  private
47
-
59
+
60
+ def self.args
61
+ @args
62
+ end
63
+
64
+ def self.humanize( key )
65
+ key
66
+ end
67
+
68
+ def self.feature_type
69
+ case args[:type]
70
+ when Rackamole.feature
71
+ "Feature"
72
+ when Rackamole.perf
73
+ "Performance"
74
+ when Rackamole.fault
75
+ "Fault"
76
+ end
77
+ end
78
+
79
+ # Format args and spit out into buffer
80
+ def self.spew( key, silent=false )
81
+ buff = []
82
+
83
+ _spew( buff, '--', (silent ? '' : ' '), key, args[key], silent )
84
+ buff.join( "\n" )
85
+ end
86
+ def self._spew( buff, sep, indent, key, value, silent )
87
+ if value.is_a?( Hash )
88
+ buff << "#{indent}#{humanize( key )}:" unless silent
89
+ value.each_pair{ |k,v| _spew( buff, sep, indent+" ", k, v, false ) }
90
+ elsif value.is_a?( Array )
91
+ buff << "#{indent}#{humanize( key )}:" unless silent
92
+ value.each { |s| _spew( buff, sep, indent+" ", '', s, false ) }
93
+ else
94
+ buff << "#{indent}#{humanize( key )}: #{value}"
95
+ end
96
+ end
97
+
98
+ # What just happened?
99
+ def self.what
100
+ buff = []
101
+ case args[:type]
102
+ when Rackamole.fault
103
+ buff << spew( :fault ) << spew( :stack ) + "\n"
104
+ when Rackamole.perf
105
+ buff << "#{spew( :request_time )}/#{@options[:perf_threshold]}"
106
+ end
107
+ buff << spew( :url ) << spew( :path ) << spew( :status )
108
+ buff << spew( :method ) << spew( :request_time ) << spew( :ip )
109
+ buff.join( "\n" )
110
+ end
111
+ def self.server() [ spew( :host ), spew( :software ), spew( :ruby_version ) ]; end
112
+ def self.client() [ spew( :machine, true ) ]; end
113
+ def self.params() [ spew( :params, true ) ]; end
114
+ def self.session() [ spew( :session, true ) ]; end
115
+ def self.browser() [ spew( :browser, true ) ]; end
116
+ def self.headers() [ spew( :headers, true ) ]; end
117
+
48
118
  # Dump request time if any...
49
119
  def self.request_time?( args )
50
- args[:type] == Rackamole.perf ? ":#{args[:request_time]}" : ''
120
+ args[:type] == Rackamole.perf ? ("%5.2f" % args[:request_time] ) : ''
51
121
  end
52
122
 
53
123
  # Identify the type of alert...
@@ -62,21 +132,21 @@ module Rackamole::Alert
62
132
  end
63
133
  end
64
134
 
65
- # Dump args...
66
- def self.dump( buff, env, level=0 )
67
- env.each_pair do |k,value|
68
- if value.respond_to?(:each_pair)
69
- buff << "%s %-#{40-level}s" % [' '*level,k]
70
- dump( buff, env[k], level+1 )
71
- elsif value.instance_of?(Array)
72
- buff << "%s %-#{40-level}s" % [' '*level,k]
73
- value.each do |v|
74
- buff << "%s %-#{40-(level+1)}s" % [' '*(level+1),v]
75
- end
76
- else
77
- buff << "%s %-#{40-level}s %s" % [ ' '*level, k, value.inspect ]
78
- end
79
- end
80
- end
135
+ # # Dump args...
136
+ # def self.dump( buff, env, level=0 )
137
+ # env.each_pair do |k,value|
138
+ # if value.respond_to?(:each_pair)
139
+ # buff << "%s %-#{40-level}s" % [' '*level,k]
140
+ # dump( buff, env[k], level+1 )
141
+ # elsif value.instance_of?(Array)
142
+ # buff << "%s %-#{40-level}s" % [' '*level,k]
143
+ # value.each do |v|
144
+ # buff << "%s %-#{40-(level+1)}s" % [' '*(level+1),v]
145
+ # end
146
+ # else
147
+ # buff << "%s %-#{40-level}s %s" % [ ' '*level, k, value.inspect ]
148
+ # end
149
+ # end
150
+ # end
81
151
  end
82
152
  end
@@ -1,9 +1,9 @@
1
- A watched feature was triggered in application `<%= args[:app_name] %> on host `<%=args[:host]%>
1
+ <%= feature_type %> alert on application <%= args[:app_name] %> on host <%=args[:host] %>
2
2
 
3
- Details...
3
+ <% %w(what server params session browser headers client).each do |heading| %>
4
+ <%= section( heading ) -%>
5
+ <% end -%>
4
6
 
5
- <%= content %>
6
-
7
- - Your Rackamole
8
-
9
- This message was generated automatically. Please do not respond directly.
7
+ ===============================================================
8
+ Powered by Rackamole. This message was generated automatically.
9
+ Please do not respond directly.
@@ -6,8 +6,8 @@ module Rackamole::Alert
6
6
  class Twitt
7
7
 
8
8
  # Twitt an alert
9
- def self.deliver_alert( logger, username, password, attrs )
10
- @twitt ||= Twitt.new( logger, username, password )
9
+ def self.deliver_alert( logger, options, attrs )
10
+ @twitt ||= Twitt.new( logger, options[:twitter][:username], options[:twitter][:password] )
11
11
  @twitt.send_alert( attrs )
12
12
  end
13
13
 
@@ -163,13 +163,13 @@ module Rack
163
163
  # send email alert ?
164
164
  if alertable?( :email, attrs[:type] )
165
165
  logger.debug ">>> Sending out email on mole type #{attrs[:type]} to #{options[:email][:to].join( ", ")}"
166
- Rackamole::Alert::Emole.deliver_alert( logger, options[:email], attrs )
166
+ Rackamole::Alert::Emole.deliver_alert( logger, options, attrs )
167
167
  end
168
168
 
169
169
  # send twitter alert ?
170
170
  if alertable?( :twitter, attrs[:type] )
171
171
  logger.debug ">>> Sending out twitt on mole type #{attrs[:type]} on @#{options[:twitter][:username]}"
172
- Rackamole::Alert::Twitt.deliver_alert( logger, options[:twitter][:username], options[:twitter][:password], attrs )
172
+ Rackamole::Alert::Twitt.deliver_alert( logger, options, attrs )
173
173
  end
174
174
  end
175
175
  rescue => boom
data/lib/rackamole.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Rackamole
2
2
 
3
3
  # :stopdoc:
4
- VERSION = '0.2.7'
4
+ VERSION = '0.2.8'
5
5
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
6
6
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
7
7
  # :startdoc:
@@ -10,99 +10,285 @@ describe Rackamole::Alert::Emole do
10
10
  @expected.set_content_type 'text', 'plain', { 'charset' => 'utf-8' }
11
11
  @expected.mime_version = '1.0'
12
12
  @expected.from = @from
13
- @expected.to = @to
13
+ @expected.to = @to
14
14
 
15
+ @options = { :email => { :from => @from, :to => @to }, :perf_threshold => 10 }
16
+
15
17
  @args = OrderedHash.new
16
- @args[:type] = Rackamole.feature
17
- @args[:app_name] = 'Test'
18
- @args[:host] = 'Fred'
19
- @args[:user_name] = 'Fernand'
18
+ @args[:type] = Rackamole.feature
19
+ @args[:method] = "POST"
20
+ @args[:status] = 200
21
+ @args[:app_name] = 'Test'
22
+ @args[:host] = 'Fred'
23
+ @args[:user_name] = 'Fernand'
24
+ @args[:url] = 'http://bumblebeetuna/fred/blee'
25
+ @args[:path] = '/fred/blee'
26
+ @args[:software] = "nginx/0.7.64"
27
+ @args[:request_time] = 0.55
28
+ @args[:ruby_version] = "ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin10.0.0]"
29
+
30
+ @args[:params] = OrderedHash.new
31
+ @args[:params][:id] = 10
32
+ @args[:params][:fred] = [10,20,30]
33
+
34
+ @args[:session] = OrderedHash.new
35
+ @args[:session][:blee] = "Hello World"
36
+ @args[:session][:fred] = [10,20,30]
37
+
38
+ @args[:headers] = OrderedHash.new
39
+ @args[:headers]['Cache-Control'] = "no-cache"
40
+ @args[:headers]['Content-Type'] = "text/html; charset=utf-8"
41
+ @args[:headers]['Content-Length'] = "17911"
42
+ @args[:headers]['Set-Cookie'] = "fred"
43
+
44
+ @args[:browser] = OrderedHash.new
45
+ @args[:browser][:name] = "Chromey"
46
+ @args[:browser][:version] = "1.12.23.54"
47
+
48
+ @args[:machine] = OrderedHash.new
49
+ @args[:machine][:platform] = "Windoze"
50
+ @args[:machine][:os] = "Windows NT"
51
+ @args[:machine][:version] = "3.5"
52
+ @args[:machine][:local] = "en-us"
53
+
20
54
  end
21
55
 
22
56
  describe "#alert" do
23
57
 
24
58
  it "should send a feature email correctly" do
25
59
  # @expected.subject = "[M()le] (Feature) -Test@Fred- for user Fernand"
26
- @expected.body = feature_body
27
- Rackamole::Alert::Emole.deliver_alert( nil, {:from => @from, :to => @to}, @args ).should == @expected.body_port.to_s
60
+ @expected.body = feature_body
61
+ # puts Rackamole::Alert::Emole.deliver_alert( nil, @options, @args )
62
+ Rackamole::Alert::Emole.deliver_alert( nil, @options, @args ).should == @expected.body_port.to_s
28
63
  end
29
64
 
30
65
  it "should send a perf email correctly" do
31
66
  @args[:type] = Rackamole.perf
32
- @args[:request_time] = 10.0
67
+ @args[:request_time] = 15.2
33
68
  # @expected.subject = "[M()le] (Performance:10.0) -Test@Fred- for user Fernand"
34
69
  @expected.body = perf_body
35
- Rackamole::Alert::Emole.deliver_alert( nil, {:from => @from, :to => @to }, @args ).should == @expected.body_port.to_s
70
+ # puts Rackamole::Alert::Emole.deliver_alert( nil, @options, @args )
71
+ Rackamole::Alert::Emole.deliver_alert( nil, @options, @args ).should == @expected.body_port.to_s
36
72
  end
37
73
 
38
74
  it "should send a fault email correctly" do
39
75
  @args[:type] = Rackamole.fault
40
76
  @args[:fault] = 'Oh Snap!'
41
77
  @args[:stack] = ['fred', 'blee']
42
- @args[:params] = { :id => 10 }
43
78
  # @expected.subject = "[M()le] (Fault) -Test@Fred- for user Fernand"
44
79
  @expected.body = fault_body
45
- Rackamole::Alert::Emole.deliver_alert( nil, { :from => @from, :to => @to }, @args ).should == @expected.body_port.to_s
80
+ # puts Rackamole::Alert::Emole.deliver_alert( nil, @options, @args )
81
+ Rackamole::Alert::Emole.deliver_alert( nil, @options, @args ).should == @expected.body_port.to_s
46
82
  end
47
-
48
83
  end
49
84
 
50
-
51
85
  def feature_body
52
86
  msg=<<MSG
53
- A watched feature was triggered in application `Test on host `Fred
87
+ Feature alert on application Test on host Fred
88
+
89
+ ----------------------------------------
90
+ o What
91
+
92
+ url: http://bumblebeetuna/fred/blee
93
+ path: /fred/blee
94
+ status: 200
95
+ method: POST
96
+ request_time: 0.55
97
+ ip:
98
+
99
+ ----------------------------------------
100
+ o Server
54
101
 
55
- Details...
102
+ host: Fred
103
+ software: nginx/0.7.64
104
+ ruby_version: ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin10.0.0]
56
105
 
57
- type 0
58
- app_name \"Test\"
59
- host \"Fred\"
60
- user_name \"Fernand\"
106
+ ----------------------------------------
107
+ o Params
61
108
 
62
- - Your Rackamole
109
+ id: 10
110
+ fred:
111
+ : 10
112
+ : 20
113
+ : 30
63
114
 
64
- This message was generated automatically. Please do not respond directly.
115
+ ----------------------------------------
116
+ o Session
117
+
118
+ blee: Hello World
119
+ fred:
120
+ : 10
121
+ : 20
122
+ : 30
123
+
124
+ ----------------------------------------
125
+ o Browser
126
+
127
+ name: Chromey
128
+ version: 1.12.23.54
129
+
130
+ ----------------------------------------
131
+ o Headers
132
+
133
+ Cache-Control: no-cache
134
+ Content-Type: text/html; charset=utf-8
135
+ Content-Length: 17911
136
+ Set-Cookie: fred
137
+
138
+ ----------------------------------------
139
+ o Client
140
+
141
+ platform: Windoze
142
+ os: Windows NT
143
+ version: 3.5
144
+ local: en-us
145
+
146
+
147
+ ===============================================================
148
+ Powered by Rackamole. This message was generated automatically.
149
+ Please do not respond directly.
65
150
  MSG
66
151
  end
67
152
 
68
153
  def perf_body
69
154
  msg=<<MSG
70
- A watched feature was triggered in application `Test on host `Fred
155
+ Performance alert on application Test on host Fred
156
+
157
+ ----------------------------------------
158
+ o What
159
+
160
+ request_time: 15.2/10
161
+ url: http://bumblebeetuna/fred/blee
162
+ path: /fred/blee
163
+ status: 200
164
+ method: POST
165
+ request_time: 15.2
166
+ ip:
71
167
 
72
- Details...
168
+ ----------------------------------------
169
+ o Server
73
170
 
74
- type 1
75
- app_name \"Test\"
76
- host \"Fred\"
77
- user_name \"Fernand\"
78
- request_time 10.0
171
+ host: Fred
172
+ software: nginx/0.7.64
173
+ ruby_version: ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin10.0.0]
79
174
 
80
- - Your Rackamole
175
+ ----------------------------------------
176
+ o Params
81
177
 
82
- This message was generated automatically. Please do not respond directly.
178
+ id: 10
179
+ fred:
180
+ : 10
181
+ : 20
182
+ : 30
183
+
184
+ ----------------------------------------
185
+ o Session
186
+
187
+ blee: Hello World
188
+ fred:
189
+ : 10
190
+ : 20
191
+ : 30
192
+
193
+ ----------------------------------------
194
+ o Browser
195
+
196
+ name: Chromey
197
+ version: 1.12.23.54
198
+
199
+ ----------------------------------------
200
+ o Headers
201
+
202
+ Cache-Control: no-cache
203
+ Content-Type: text/html; charset=utf-8
204
+ Content-Length: 17911
205
+ Set-Cookie: fred
206
+
207
+ ----------------------------------------
208
+ o Client
209
+
210
+ platform: Windoze
211
+ os: Windows NT
212
+ version: 3.5
213
+ local: en-us
214
+
215
+
216
+ ===============================================================
217
+ Powered by Rackamole. This message was generated automatically.
218
+ Please do not respond directly.
83
219
  MSG
84
220
  end
85
221
 
86
222
  def fault_body
87
223
  msg=<<MSG
88
- A watched feature was triggered in application `Test on host `Fred
224
+ Fault alert on application Test on host Fred
225
+
226
+ ----------------------------------------
227
+ o What
228
+
229
+ fault: Oh Snap!
230
+ stack:
231
+ : fred
232
+ : blee
233
+
234
+ url: http://bumblebeetuna/fred/blee
235
+ path: /fred/blee
236
+ status: 200
237
+ method: POST
238
+ request_time: 0.55
239
+ ip:
240
+
241
+ ----------------------------------------
242
+ o Server
243
+
244
+ host: Fred
245
+ software: nginx/0.7.64
246
+ ruby_version: ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin10.0.0]
247
+
248
+ ----------------------------------------
249
+ o Params
250
+
251
+ id: 10
252
+ fred:
253
+ : 10
254
+ : 20
255
+ : 30
256
+
257
+ ----------------------------------------
258
+ o Session
259
+
260
+ blee: Hello World
261
+ fred:
262
+ : 10
263
+ : 20
264
+ : 30
265
+
266
+ ----------------------------------------
267
+ o Browser
268
+
269
+ name: Chromey
270
+ version: 1.12.23.54
271
+
272
+ ----------------------------------------
273
+ o Headers
274
+
275
+ Cache-Control: no-cache
276
+ Content-Type: text/html; charset=utf-8
277
+ Content-Length: 17911
278
+ Set-Cookie: fred
89
279
 
90
- Details...
280
+ ----------------------------------------
281
+ o Client
91
282
 
92
- type 2
93
- app_name \"Test\"
94
- host \"Fred\"
95
- user_name \"Fernand\"
96
- fault \"Oh Snap!\"
97
- stack
98
- fred
99
- blee
100
- params
101
- id 10
283
+ platform: Windoze
284
+ os: Windows NT
285
+ version: 3.5
286
+ local: en-us
102
287
 
103
- - Your Rackamole
104
288
 
105
- This message was generated automatically. Please do not respond directly.
289
+ ===============================================================
290
+ Powered by Rackamole. This message was generated automatically.
291
+ Please do not respond directly.
106
292
  MSG
107
293
  end
108
294
 
@@ -3,7 +3,7 @@ require 'chronic'
3
3
 
4
4
  describe Rackamole::Alert::Twitt do
5
5
  before( :each ) do
6
- @alert = Rackamole::Alert::Twitt.new( nil, 'fernand', "blee" )
6
+ @alert = Rackamole::Alert::Twitt.new( nil, 'fernand', 'blee' )
7
7
  end
8
8
 
9
9
  it "should truncate a message correctly" do
@@ -39,7 +39,7 @@ describe Rackamole::Alert::Twitt do
39
39
  # client.should_receive( :new ).once.and_return( client )
40
40
  twitt.should_receive( :send_alert ).with( @args ).once.and_return( "yeah" )
41
41
 
42
- Rackamole::Alert::Twitt.deliver_alert( nil, "blee", "duh", @args )
42
+ Rackamole::Alert::Twitt.deliver_alert( nil, { :twitter => { :username => "blee", :password => "duh" } }, @args )
43
43
  end
44
44
 
45
45
  it "should twitt a feature alert correctly" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rackamole
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.2.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fernand Galiana
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-28 00:00:00 -07:00
12
+ date: 2010-01-31 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency