simple_performer 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.
- data/README.markdown +24 -0
- data/lib/api_auth.rb +12 -0
- data/lib/base.rb +7 -0
- data/lib/config.rb +9 -0
- data/lib/data_array.rb +11 -0
- data/lib/simple_performer.rb +186 -0
- data/lib/simple_performr_rufus.rb +47 -0
- data/lib/sp_rack.rb +37 -0
- metadata +96 -0
data/README.markdown
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
Getting Started
|
3
|
+
===============
|
4
|
+
|
5
|
+
In environment.rb:
|
6
|
+
|
7
|
+
config.gem 'simple_performer'
|
8
|
+
config.middleware.use SimplePerformer::Rack
|
9
|
+
|
10
|
+
To wrap your own sections:
|
11
|
+
|
12
|
+
SimplePerformer.benchmark("name_of_code_section") do
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
Other Utility Functions
|
17
|
+
-----------------------
|
18
|
+
|
19
|
+
To print duration of a block:
|
20
|
+
|
21
|
+
SimplePerformer.puts_duration ("name_of_code_section") do
|
22
|
+
|
23
|
+
end
|
24
|
+
|
data/lib/api_auth.rb
ADDED
data/lib/base.rb
ADDED
data/lib/config.rb
ADDED
data/lib/data_array.rb
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rest_client'
|
3
|
+
require 'eventmachine'
|
4
|
+
require 'benchmark'
|
5
|
+
require 'pp'
|
6
|
+
require 'json'
|
7
|
+
require_relative 'base'
|
8
|
+
require_relative 'data_array'
|
9
|
+
require_relative 'api_auth'
|
10
|
+
require_relative 'sp_rack'
|
11
|
+
|
12
|
+
#for Now data array would simply be a queue
|
13
|
+
module SimplePerformer
|
14
|
+
|
15
|
+
@@metrics_path = '/api/metrics'
|
16
|
+
@@base_url = 'http://incoming.simpleperformr.com' + @@metrics_path
|
17
|
+
|
18
|
+
class << self
|
19
|
+
attr_accessor :config,
|
20
|
+
:service
|
21
|
+
|
22
|
+
def configure()
|
23
|
+
SimplePerformer.config ||= SimplePerformer::Config.new
|
24
|
+
yield(config)
|
25
|
+
# SimplePerformer.service = Performr.new(config.access_key, config.secret_key, :config=>config)
|
26
|
+
Performr.start
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# name is what this chunk of code will be referred to in the UI.
|
31
|
+
def self.benchmark(name, &block)
|
32
|
+
Performr.benchmark(name, &block)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.shutdown
|
36
|
+
EventMachine.stop
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.base_url=(url)
|
40
|
+
@@base_url = url + @@metrics_path
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.base_url
|
44
|
+
@@base_url
|
45
|
+
end
|
46
|
+
|
47
|
+
# Simple function that simply spits out the duration of the block
|
48
|
+
# - name is for reference.
|
49
|
+
def self.puts_duration(name, &block)
|
50
|
+
start_time = Time.now
|
51
|
+
yield
|
52
|
+
end_time = Time.now
|
53
|
+
puts "#{name} duration: #{(end_time-start_time)} seconds."
|
54
|
+
end
|
55
|
+
|
56
|
+
class Performr
|
57
|
+
#< ApiAuth
|
58
|
+
|
59
|
+
class <<self
|
60
|
+
|
61
|
+
attr_accessor :data, :api_key, :base_uri, :timer
|
62
|
+
|
63
|
+
def config options={}, &blk
|
64
|
+
SimplePerformer.configure do |config|
|
65
|
+
config.access_key = options[:access_key]
|
66
|
+
config.host = options[:host]
|
67
|
+
end
|
68
|
+
|
69
|
+
instance_eval &blk if block_given?
|
70
|
+
end
|
71
|
+
|
72
|
+
def start
|
73
|
+
self.data = Queue.new
|
74
|
+
|
75
|
+
puts "api_key=" + api_key.to_s
|
76
|
+
if api_key
|
77
|
+
# only start it if we passed in a key
|
78
|
+
run_update
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
def reset_queue
|
84
|
+
self.data = Queue.new
|
85
|
+
end
|
86
|
+
|
87
|
+
def send_update
|
88
|
+
# puts "send_update api_key=" + api_key
|
89
|
+
url = "/update_metrics/"+api_key
|
90
|
+
#consumer for data
|
91
|
+
#delete all data from queue after update
|
92
|
+
to_send = return_data
|
93
|
+
# puts "sending json=" + to_send.inspect
|
94
|
+
|
95
|
+
to_send = to_send.to_json
|
96
|
+
# puts 'posting to ' + full_url(url)
|
97
|
+
response = RestClient.post(full_url(url), to_send, :content_type => :json)
|
98
|
+
end
|
99
|
+
|
100
|
+
def return_data
|
101
|
+
avg_metrics = {}
|
102
|
+
i=0
|
103
|
+
data = self.data
|
104
|
+
reset_queue
|
105
|
+
# create a new one so the current queue doesn't have the opportunity to keep filling up and we try to keep popping too
|
106
|
+
until data.empty?
|
107
|
+
metric=data.pop
|
108
|
+
name=metric[:name]
|
109
|
+
avg_metrics[name] ||= {:count => 0, :user => 0, :system => 0, :total => 0, :real => 0}
|
110
|
+
avg_metrics[name][:count] += 1
|
111
|
+
avg_metrics[name][:user] += metric[:user]
|
112
|
+
avg_metrics[name][:system] += metric[:system]
|
113
|
+
avg_metrics[name][:total] += metric[:total]
|
114
|
+
avg_metrics[name][:real] += metric[:real]
|
115
|
+
end
|
116
|
+
# puts hash.inspect + " hash inspect"
|
117
|
+
avg_metrics
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
def full_url(path)
|
122
|
+
SimplePerformer.base_url + path
|
123
|
+
end
|
124
|
+
|
125
|
+
def periodic_update
|
126
|
+
|
127
|
+
EventMachine.run do
|
128
|
+
@timer = EventMachine::PeriodicTimer.new(60) do
|
129
|
+
# puts "the time is #{Time.now}"
|
130
|
+
begin
|
131
|
+
send_update
|
132
|
+
rescue => ex
|
133
|
+
puts 'Failed to send data to SimplePerformr!'
|
134
|
+
puts ex.message
|
135
|
+
puts ex.backtrace
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def cancel_update
|
143
|
+
timer.cancel if timer
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
def run_update
|
148
|
+
Thread.new do
|
149
|
+
periodic_update
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def benchmark name, &block
|
154
|
+
opts = name
|
155
|
+
stat=Benchmark::measure &block
|
156
|
+
puts 'name2=' + name.inspect
|
157
|
+
if opts.is_a? Hash
|
158
|
+
name = opts[:name]
|
159
|
+
end
|
160
|
+
unless name && name.length > 0
|
161
|
+
raise "Must provide a name for benchmark."
|
162
|
+
end
|
163
|
+
puts 'name =' + name
|
164
|
+
pp stat.to_hash, stat.class
|
165
|
+
collect_stats stat.to_hash.merge(:name => name)
|
166
|
+
end
|
167
|
+
|
168
|
+
def collect_stats stat
|
169
|
+
self.data.push(stat)
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
class Benchmark::Tms
|
177
|
+
def to_hash
|
178
|
+
{
|
179
|
+
:user => @utime,
|
180
|
+
:real => @real,
|
181
|
+
:total => @total,
|
182
|
+
:system =>@stime
|
183
|
+
}
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'httpparty'
|
3
|
+
require 'rufus/scheduler'
|
4
|
+
require 'json'
|
5
|
+
module SimplePerformer
|
6
|
+
class TimeBlock
|
7
|
+
attr_reader :start_time, :end_time, :duration
|
8
|
+
|
9
|
+
def initialize(start_time, end_time, duration)
|
10
|
+
@start_time=start_time
|
11
|
+
@end_time=end_time
|
12
|
+
@duration=duration
|
13
|
+
end
|
14
|
+
end
|
15
|
+
class PerformrRufus
|
16
|
+
@@store = {}
|
17
|
+
|
18
|
+
attr_reader :scheduler
|
19
|
+
include HTTParty
|
20
|
+
base_uri 'http://localhost:3000/api/metrics'
|
21
|
+
format :json
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
@scheduler = Rufus::Scheduler.start_new
|
25
|
+
end
|
26
|
+
|
27
|
+
def benchmark(name)
|
28
|
+
start_time=Time.now
|
29
|
+
yield
|
30
|
+
end_time =Time.now
|
31
|
+
@@store[name] ||= []
|
32
|
+
duration = start_time-end_time
|
33
|
+
@@store[name] << TimeBlock.new(start_time, end_time, duration)
|
34
|
+
end
|
35
|
+
|
36
|
+
def send_updates
|
37
|
+
scheduler do
|
38
|
+
api_key = "1b27953c-1b9f-11df-af31-002618d9f74e"
|
39
|
+
url = "/update_metrics"+"/"+api_key
|
40
|
+
response=self.class.post(url, :query => {"metrics" => @@store.to_json})
|
41
|
+
puts response
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
p=SimplePerformer::PerformrRufus.new
|
47
|
+
|
data/lib/sp_rack.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# Rack is stack of middleware
|
2
|
+
# server middleware1(middleware2(middleware3( .... middlewareN (app)))
|
3
|
+
# Rack middleware is an object that responds to call method and could be intialized with other middleware
|
4
|
+
#
|
5
|
+
# How it works?
|
6
|
+
# middleware2 is intialized with middleware3
|
7
|
+
# when middleware1 is called by server
|
8
|
+
# middleware1 will call middleware2 and chain continues until the app is called and response
|
9
|
+
# returned from app is returned back to server through middleware chain which is sent back as
|
10
|
+
# response to request
|
11
|
+
require_relative 'simple_performer'
|
12
|
+
|
13
|
+
module SimplePerformer
|
14
|
+
|
15
|
+
class Rack
|
16
|
+
|
17
|
+
def initialize(app, message = "SimplePerformr stats")
|
18
|
+
@app = app
|
19
|
+
@message = message
|
20
|
+
end
|
21
|
+
|
22
|
+
def call(env)
|
23
|
+
dup._call(env) # why dup?
|
24
|
+
end
|
25
|
+
|
26
|
+
def _call(env)
|
27
|
+
# puts 'env=' + env.inspect
|
28
|
+
name = {}
|
29
|
+
Performr.benchmark(name) do
|
30
|
+
@response = @app.call(env)
|
31
|
+
name[:name] = "#{env['action_controller.request.path_parameters']['controller'].camelize}##{env['action_controller.request.path_parameters']['action']}"
|
32
|
+
end
|
33
|
+
@response
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simple_performer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 7
|
9
|
+
version: 0.0.7
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Travis Reeder
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-09-30 00:00:00 -07:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rest-client
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :runtime
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: eventmachine
|
35
|
+
prerelease: false
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
version: "0"
|
44
|
+
type: :runtime
|
45
|
+
version_requirements: *id002
|
46
|
+
description: Appoxy SimplePerformer Client Gem ...
|
47
|
+
email: travis@appoxy.com
|
48
|
+
executables: []
|
49
|
+
|
50
|
+
extensions: []
|
51
|
+
|
52
|
+
extra_rdoc_files:
|
53
|
+
- README.markdown
|
54
|
+
files:
|
55
|
+
- lib/api_auth.rb
|
56
|
+
- lib/base.rb
|
57
|
+
- lib/config.rb
|
58
|
+
- lib/data_array.rb
|
59
|
+
- lib/simple_performer.rb
|
60
|
+
- lib/simple_performr_rufus.rb
|
61
|
+
- lib/sp_rack.rb
|
62
|
+
- README.markdown
|
63
|
+
has_rdoc: true
|
64
|
+
homepage: http://www.appoxy.com
|
65
|
+
licenses: []
|
66
|
+
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options:
|
69
|
+
- --charset=UTF-8
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
segments:
|
78
|
+
- 0
|
79
|
+
version: "0"
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
segments:
|
86
|
+
- 0
|
87
|
+
version: "0"
|
88
|
+
requirements: []
|
89
|
+
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 1.3.7
|
92
|
+
signing_key:
|
93
|
+
specification_version: 3
|
94
|
+
summary: Appoxy SimplePerformer Client Gem
|
95
|
+
test_files: []
|
96
|
+
|