copperegg-apm 1.0.0.pre1
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +102 -0
- data/README.md +181 -0
- data/Rakefile +4 -0
- data/bin/copperegg-apm-init +45 -0
- data/bin/copperegg-apm-methods +27 -0
- data/copperegg-apm-1.0.0.pre1.gem +0 -0
- data/copperegg-apm.gemspec +34 -0
- data/copperegg_apm_test.db +0 -0
- data/ext/mkrf_conf.rb +19 -0
- data/lib/copperegg-apm.rb +1 -0
- data/lib/copperegg/apm.rb +28 -0
- data/lib/copperegg/apm/action_controller/base.rb +31 -0
- data/lib/copperegg/apm/active_record/connection_adapters/abstract_adapter.rb +35 -0
- data/lib/copperegg/apm/benchmark.rb +212 -0
- data/lib/copperegg/apm/benchmark_methods_table.rb +65 -0
- data/lib/copperegg/apm/configuration.rb +188 -0
- data/lib/copperegg/apm/engine.rb +15 -0
- data/lib/copperegg/apm/errors.rb +6 -0
- data/lib/copperegg/apm/ethon/easy/operations.rb +37 -0
- data/lib/copperegg/apm/kernel.rb +19 -0
- data/lib/copperegg/apm/middleware.rb +20 -0
- data/lib/copperegg/apm/mysql.rb +31 -0
- data/lib/copperegg/apm/mysql2/client.rb +35 -0
- data/lib/copperegg/apm/net/http.rb +39 -0
- data/lib/copperegg/apm/pg/connection.rb +35 -0
- data/lib/copperegg/apm/restclient/request.rb +33 -0
- data/lib/copperegg/apm/rum.rb +24 -0
- data/lib/copperegg/apm/sqlite3/database.rb +35 -0
- data/lib/copperegg/apm/tasks.rb +11 -0
- data/lib/copperegg/apm/typhoeus/hydra.rb +33 -0
- data/lib/copperegg/apm/unbound_method.rb +116 -0
- data/lib/copperegg/apm/version.rb +5 -0
- data/lib/generators/copperegg/apm/init_generator.rb +20 -0
- data/lib/generators/copperegg/apm/templates/config.rb +10 -0
- data/performance/mysql2.rb +44 -0
- data/screenshot01.png +0 -0
- data/spec/action_controller_spec.rb +139 -0
- data/spec/apm_spec.rb +330 -0
- data/spec/ethon_spec.rb +73 -0
- data/spec/helpers/mysql2_setup.rb +51 -0
- data/spec/helpers/mysql_setup.rb +45 -0
- data/spec/helpers/pg_setup.rb +43 -0
- data/spec/helpers/rails.rb +18 -0
- data/spec/helpers/sqlite3_setup.rb +30 -0
- data/spec/kernel_spec.rb +37 -0
- data/spec/mysql2_spec.rb +58 -0
- data/spec/mysql_spec.rb +66 -0
- data/spec/net_http_spec.rb +52 -0
- data/spec/pg_spec.rb +45 -0
- data/spec/restclient_spec.rb +67 -0
- data/spec/rum_spec.rb +23 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/sqlite3_spec.rb +45 -0
- data/spec/typhoeus_spec.rb +66 -0
- metadata +316 -0
data/spec/ethon_spec.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ethon::Easy::Operations do
|
4
|
+
describe "#perform" do
|
5
|
+
it "should benchmark time for a get request" do
|
6
|
+
easy = Ethon::Easy.new(:url => "https://api.twitter.com/1.1/help/configuration.json")
|
7
|
+
easy.perform
|
8
|
+
|
9
|
+
expect(easy.response_code.to_s).to match(/\A\d{3}\Z/)
|
10
|
+
JSON.parse(easy.response_body)
|
11
|
+
|
12
|
+
last_payload = CopperEgg::APM.send(:class_variable_get, :@@payload_cache).split("\x00").select {|i| i.size > 2}.map {|i| i.sub(/^[^\{]+/,'')}.last
|
13
|
+
hash = JSON.parse last_payload
|
14
|
+
|
15
|
+
expect(hash.keys.sort).to eq ["id", "inst"]
|
16
|
+
expect(hash["id"]).to match(/\A[0-1a-z]{16}\z/i)
|
17
|
+
expect(hash["inst"].keys.sort).to eq ["time", "url"]
|
18
|
+
expect(hash["inst"]["url"]).to eq "https://api.twitter.com/1.1/help/configuration.json {Ruby}"
|
19
|
+
expect(hash["inst"]["time"].to_s).to match(/\A\d+\Z/)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should not have authentication nor query params in the url" do
|
23
|
+
easy = Ethon::Easy.new
|
24
|
+
easy.http_request("http://mikeapikey:U@api.rails.dev/v2/revealmetrics/metric_groups.json?show_hidden=true", :get)
|
25
|
+
easy.perform
|
26
|
+
|
27
|
+
expect(easy.response_code.to_s).to match(/\A\d{3}\Z/)
|
28
|
+
|
29
|
+
last_payload = CopperEgg::APM.send(:class_variable_get, :@@payload_cache).split("\x00").select {|i| i.size > 2}.map {|i| i.sub(/^[^\{]+/,'')}.last
|
30
|
+
hash = JSON.parse last_payload
|
31
|
+
|
32
|
+
expect(hash.keys.sort).to eq ["id", "inst"]
|
33
|
+
expect(hash["id"]).to match(/\A[0-1a-z]{16}\z/i)
|
34
|
+
expect(hash["inst"].keys.sort).to eq ["time", "url"]
|
35
|
+
expect(hash["inst"]["url"]).to eq "http://api.rails.dev/v2/revealmetrics/metric_groups.json {Ruby}"
|
36
|
+
expect(hash["inst"]["time"].to_s).to match(/\A\d+\Z/)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should benchmark time for a post request" do
|
40
|
+
easy = Ethon::Easy.new
|
41
|
+
easy.http_request("http://mikeapikey:U@api.rails.dev/v2/revealmetrics/tags.json", :post, {:params => {:tag => "asjasfe", :ids => "smtp"}})
|
42
|
+
easy.perform
|
43
|
+
|
44
|
+
expect(easy.response_code.to_s).to match(/\A\d{3}\Z/)
|
45
|
+
|
46
|
+
last_payload = CopperEgg::APM.send(:class_variable_get, :@@payload_cache).split("\x00").select {|i| i.size > 2}.map {|i| i.sub(/^[^\{]+/,'')}.last
|
47
|
+
hash = JSON.parse last_payload
|
48
|
+
|
49
|
+
expect(hash.keys.sort).to eq ["id", "inst"]
|
50
|
+
expect(hash["id"]).to match(/\A[0-1a-z]{16}\z/i)
|
51
|
+
expect(hash["inst"].keys.sort).to eq ["time", "url"]
|
52
|
+
expect(hash["inst"]["url"]).to eq "http://api.rails.dev/v2/revealmetrics/tags.json {Ruby}"
|
53
|
+
expect(hash["inst"]["time"].to_s).to match(/\A\d+\Z/)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should benchmark time for a delete request" do
|
57
|
+
easy = Ethon::Easy.new
|
58
|
+
easy.http_request("http://mikeapikey:U@api.rails.dev/v2/revealmetrics/tags/smtp.json", :delete, {:params => {:ids => "smtp"}})
|
59
|
+
easy.perform
|
60
|
+
|
61
|
+
expect(easy.response_code.to_s).to match(/\A\d{3}\Z/)
|
62
|
+
|
63
|
+
last_payload = CopperEgg::APM.send(:class_variable_get, :@@payload_cache).split("\x00").select {|i| i.size > 2}.map {|i| i.sub(/^[^\{]+/,'')}.last
|
64
|
+
hash = JSON.parse last_payload
|
65
|
+
|
66
|
+
expect(hash.keys.sort).to eq ["id", "inst"]
|
67
|
+
expect(hash["id"]).to match(/\A[0-1a-z]{16}\z/i)
|
68
|
+
expect(hash["inst"].keys.sort).to eq ["time", "url"]
|
69
|
+
expect(hash["inst"]["url"]).to eq "http://api.rails.dev/v2/revealmetrics/tags/smtp.json {Ruby}"
|
70
|
+
expect(hash["inst"]["time"].to_s).to match(/\A\d+\Z/)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
begin
|
2
|
+
require 'mysql2'
|
3
|
+
require 'faker'
|
4
|
+
rescue LoadError
|
5
|
+
require 'rubygems'
|
6
|
+
require 'mysql2'
|
7
|
+
require 'faker'
|
8
|
+
end
|
9
|
+
|
10
|
+
begin
|
11
|
+
client = Mysql2::Client.new :host => "localhost", :username => ENV["MYSQL_USER"]
|
12
|
+
|
13
|
+
create_db_sql = <<-SQL
|
14
|
+
CREATE DATABASE IF NOT EXISTS copperegg_apm_test
|
15
|
+
DEFAULT CHARACTER SET = utf8
|
16
|
+
SQL
|
17
|
+
|
18
|
+
client.query create_db_sql
|
19
|
+
client.query "GRANT ALL PRIVILEGES ON copperegg_apm_test.* TO '%'@'%'"
|
20
|
+
client.query "USE copperegg_apm_test"
|
21
|
+
|
22
|
+
create_table_sql = <<-SQL
|
23
|
+
CREATE TABLE IF NOT EXISTS users (
|
24
|
+
id MEDIUMINT NOT NULL AUTO_INCREMENT,
|
25
|
+
username VARCHAR(32),
|
26
|
+
email VARCHAR(100),
|
27
|
+
password VARCHAR(100),
|
28
|
+
details TEXT,
|
29
|
+
created_at TIMESTAMP,
|
30
|
+
updated_at TIMESTAMP,
|
31
|
+
PRIMARY KEY (id)
|
32
|
+
) DEFAULT CHARSET = utf8
|
33
|
+
SQL
|
34
|
+
|
35
|
+
client.query create_table_sql
|
36
|
+
|
37
|
+
client.query "TRUNCATE users"
|
38
|
+
|
39
|
+
insert_sql = <<-SQL
|
40
|
+
INSERT INTO users (username, email, password, details, created_at, updated_at)
|
41
|
+
VALUES
|
42
|
+
SQL
|
43
|
+
|
44
|
+
10.times do |i|
|
45
|
+
insert_sql << " ('#{Faker::Internet.user_name}', '#{Faker::Internet.email}', '#{Faker::Lorem.characters(16)}', '#{Faker::Lorem.paragraph(2)}', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)#{"," if i < 9}\n"
|
46
|
+
end
|
47
|
+
|
48
|
+
client.query insert_sql
|
49
|
+
rescue Exception => e
|
50
|
+
puts "Could not create database copperegg_apm_test using user set in ENV['MYSQL_USER']. #{e.message}."
|
51
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'mysql'
|
2
|
+
require 'faker'
|
3
|
+
|
4
|
+
begin
|
5
|
+
connection = Mysql.new("localhost", ENV["MYSQL_USER"])
|
6
|
+
|
7
|
+
create_db_sql = <<-SQL
|
8
|
+
CREATE DATABASE IF NOT EXISTS copperegg_apm_test
|
9
|
+
DEFAULT CHARACTER SET = utf8
|
10
|
+
SQL
|
11
|
+
|
12
|
+
connection.query create_db_sql
|
13
|
+
connection.query "GRANT ALL PRIVILEGES ON copperegg_apm_test.* TO '%'@'%'"
|
14
|
+
connection.query "USE copperegg_apm_test"
|
15
|
+
|
16
|
+
create_table_sql = <<-SQL
|
17
|
+
CREATE TABLE IF NOT EXISTS users (
|
18
|
+
id MEDIUMINT NOT NULL AUTO_INCREMENT,
|
19
|
+
username VARCHAR(32),
|
20
|
+
email VARCHAR(100),
|
21
|
+
password VARCHAR(100),
|
22
|
+
details TEXT,
|
23
|
+
created_at TIMESTAMP,
|
24
|
+
updated_at TIMESTAMP,
|
25
|
+
PRIMARY KEY (id)
|
26
|
+
) DEFAULT CHARSET = utf8
|
27
|
+
SQL
|
28
|
+
|
29
|
+
connection.query create_table_sql
|
30
|
+
|
31
|
+
connection.query "TRUNCATE users"
|
32
|
+
|
33
|
+
insert_sql = <<-SQL
|
34
|
+
INSERT INTO users (username, email, password, details, created_at, updated_at)
|
35
|
+
VALUES
|
36
|
+
SQL
|
37
|
+
|
38
|
+
10.times do |i|
|
39
|
+
insert_sql << " ('#{Faker::Internet.user_name}', '#{Faker::Internet.email}', '#{Faker::Lorem.characters(16)}', '#{Faker::Lorem.paragraph(2)}', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)#{"," if i < 9}\n"
|
40
|
+
end
|
41
|
+
|
42
|
+
connection.query insert_sql
|
43
|
+
rescue Mysql::Error => e
|
44
|
+
puts "Could not create database copperegg_apm_test using user set in ENV['MYSQL_USER']. #{e.message}."
|
45
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'pg'
|
2
|
+
require 'faker'
|
3
|
+
|
4
|
+
begin
|
5
|
+
connection = PG.connect(:dbname => 'copperegg_apm_test', :user => ENV["PG_USER"])
|
6
|
+
rescue PG::Error => e
|
7
|
+
if e.message =~ /database "copperegg_apm_test" does not exist/
|
8
|
+
if ENV["PG_USER"]
|
9
|
+
`createdb -U #{ENV["PG_USER"]} -w copperegg_apm_test`
|
10
|
+
else
|
11
|
+
`createdb -w copperegg_apm_test`
|
12
|
+
end
|
13
|
+
connection = PG.connect(:dbname => 'copperegg_apm_test', :user => ENV["PG_USER"])
|
14
|
+
else
|
15
|
+
raise e
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
create_table_sql = <<-SQL
|
20
|
+
CREATE TABLE IF NOT EXISTS users (
|
21
|
+
username VARCHAR,
|
22
|
+
email VARCHAR,
|
23
|
+
password VARCHAR,
|
24
|
+
details TEXT,
|
25
|
+
created_at TIMESTAMP,
|
26
|
+
updated_at TIMESTAMP
|
27
|
+
)
|
28
|
+
SQL
|
29
|
+
|
30
|
+
connection.exec create_table_sql
|
31
|
+
|
32
|
+
connection.exec "TRUNCATE users"
|
33
|
+
|
34
|
+
insert_sql = <<-SQL
|
35
|
+
INSERT INTO users (username, email, password, details, created_at, updated_at)
|
36
|
+
VALUES
|
37
|
+
SQL
|
38
|
+
|
39
|
+
10.times do |i|
|
40
|
+
insert_sql << " ('#{Faker::Internet.user_name}', '#{Faker::Internet.email}', '#{Faker::Lorem.characters(16)}', '#{Faker::Lorem.paragraph(2)}', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)#{"," if i < 9}\n"
|
41
|
+
end
|
42
|
+
|
43
|
+
connection.exec insert_sql
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'active_support/all'
|
2
|
+
require 'action_controller'
|
3
|
+
require 'action_dispatch'
|
4
|
+
require 'rspec/rails'
|
5
|
+
|
6
|
+
module Rails
|
7
|
+
class App
|
8
|
+
def env_config; {} end
|
9
|
+
def routes
|
10
|
+
return @routes if defined?(@routes)
|
11
|
+
@routes = ActionDispatch::Routing::RouteSet.new
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.application
|
16
|
+
@app ||= App.new
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'sqlite3'
|
2
|
+
require 'faker'
|
3
|
+
|
4
|
+
database = SQLite3::Database.new "copperegg_apm_test.db"
|
5
|
+
|
6
|
+
database.execute "DROP TABLE IF EXISTS users"
|
7
|
+
|
8
|
+
create_table_sql = <<-SQL
|
9
|
+
CREATE TABLE IF NOT EXISTS users (
|
10
|
+
id MEDIUMINT NOT NULL,
|
11
|
+
username VARCHAR(32),
|
12
|
+
email VARCHAR(100),
|
13
|
+
password VARCHAR(100),
|
14
|
+
details TEXT,
|
15
|
+
PRIMARY KEY (id)
|
16
|
+
);
|
17
|
+
SQL
|
18
|
+
|
19
|
+
database.execute create_table_sql
|
20
|
+
|
21
|
+
insert_sql = <<-SQL
|
22
|
+
INSERT INTO users (id, username, email, password, details)
|
23
|
+
VALUES
|
24
|
+
SQL
|
25
|
+
|
26
|
+
10.times do |i|
|
27
|
+
insert_sql << " (#{i}, '#{Faker::Internet.user_name}', '#{Faker::Internet.email}', '#{Faker::Lorem.characters(16)}', '#{Faker::Lorem.paragraph(2)}')#{"," if i < 9}\n"
|
28
|
+
end
|
29
|
+
|
30
|
+
database.execute insert_sql
|
data/spec/kernel_spec.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Kernel do
|
4
|
+
describe "#raise" do
|
5
|
+
it "should instrument any exception" do
|
6
|
+
expect { raise "the roof" }.to raise_error(RuntimeError)
|
7
|
+
print "."
|
8
|
+
|
9
|
+
last_payload = CopperEgg::APM.send(:class_variable_get, :@@payload_cache).split("\x00").select {|i| i.size > 2}.map {|i| i.sub(/^[^\{]+/,'')}.last
|
10
|
+
hash = JSON.parse last_payload
|
11
|
+
|
12
|
+
expect(hash.keys.sort).to eq ["excp", "id"]
|
13
|
+
expect(hash["id"]).to match(/\A[0-1a-z]{16}\z/i)
|
14
|
+
expect(hash["excp"].keys.sort).to eq ["error", "stacktrace", "ts"]
|
15
|
+
expect(hash["excp"]["error"]).to match(/RuntimeError\|/)
|
16
|
+
expect(hash["excp"]["stacktrace"]).to match(/\Athe roof\n/)
|
17
|
+
expect(hash["excp"]["ts"]).to be_an_instance_of(Fixnum)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#fail" do
|
22
|
+
it "should instrument any exception" do
|
23
|
+
expect { fail "epically" }.to raise_error(RuntimeError)
|
24
|
+
print "."
|
25
|
+
|
26
|
+
last_payload = CopperEgg::APM.send(:class_variable_get, :@@payload_cache).split("\x00").select {|i| i.size > 2}.map {|i| i.sub(/^[^\{]+/,'')}.last
|
27
|
+
hash = JSON.parse last_payload
|
28
|
+
|
29
|
+
expect(hash.keys.sort).to eq ["excp", "id"]
|
30
|
+
expect(hash["id"]).to match(/\A[0-1a-z]{16}\z/i)
|
31
|
+
expect(hash["excp"].keys.sort).to eq ["error", "stacktrace", "ts"]
|
32
|
+
expect(hash["excp"]["error"]).to match(/RuntimeError\|/)
|
33
|
+
expect(hash["excp"]["stacktrace"]).to match(/\Aepically\n/)
|
34
|
+
expect(hash["excp"]["ts"]).to be_an_instance_of(Fixnum)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/spec/mysql2_spec.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helpers/mysql2_setup'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Mysql2::Client do
|
5
|
+
describe "#query" do
|
6
|
+
before do
|
7
|
+
@client = Mysql2::Client.new :host => "localhost", :database => "copperegg_apm_test", :username => ENV["MYSQL_USER"]
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should benchmark time" do
|
11
|
+
result = @client.query "select * from users"
|
12
|
+
expect(result).to be_an_instance_of(Mysql2::Result)
|
13
|
+
|
14
|
+
last_payload = CopperEgg::APM.send(:class_variable_get, :@@payload_cache).split("\x00").select {|i| i.size > 2}.map {|i| i.sub(/^[^\{]+/,'')}.last
|
15
|
+
hash = JSON.parse last_payload
|
16
|
+
|
17
|
+
expect(hash.keys.sort).to eq ["id", "inst"]
|
18
|
+
expect(hash["id"]).to match(/\A[0-1a-z]{16}\z/i)
|
19
|
+
expect(hash["inst"].keys.sort).to eq ["sql", "time"]
|
20
|
+
expect(hash["inst"]["sql"]).to eq "select * from users {Ruby}"
|
21
|
+
expect(hash["inst"]["time"].to_s).to match(/\A\d+\Z/)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should benchmark update statements" do
|
25
|
+
@client.query "update users set details = 'blah' where id = 1"
|
26
|
+
|
27
|
+
last_payload = CopperEgg::APM.send(:class_variable_get, :@@payload_cache).split("\x00").select {|i| i.size > 2}.map {|i| i.sub(/^[^\{]+/,'')}.last
|
28
|
+
hash = JSON.parse last_payload
|
29
|
+
|
30
|
+
expect(hash.keys.sort).to eq ["id", "inst"]
|
31
|
+
expect(hash["id"]).to match(/\A[0-1a-z]{16}\z/i)
|
32
|
+
expect(hash["inst"].keys.sort).to eq ["sql", "time"]
|
33
|
+
expect(hash["inst"]["sql"]).to eq "update users set details = ? where id = ? {Ruby}"
|
34
|
+
expect(hash["inst"]["time"].to_s).to match(/\A\d+\Z/)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should not benchmark transaction statements" do
|
38
|
+
payload = CopperEgg::APM.send(:class_variable_get, :@@payload_cache)
|
39
|
+
|
40
|
+
@client.query "begin"
|
41
|
+
|
42
|
+
expect(CopperEgg::APM.send(:class_variable_get, :@@payload_cache)).to eq payload
|
43
|
+
|
44
|
+
@client.query "select * from users"
|
45
|
+
|
46
|
+
last_payload = CopperEgg::APM.send(:class_variable_get, :@@payload_cache).split("\x00").select {|i| i.size > 2}.map {|i| i.sub(/^[^\{]+/,'')}.last
|
47
|
+
hash = JSON.parse last_payload
|
48
|
+
|
49
|
+
expect(hash["inst"]["sql"]).to eq "select * from users {Ruby}"
|
50
|
+
|
51
|
+
@client.query "commit"
|
52
|
+
|
53
|
+
final_payload = CopperEgg::APM.send(:class_variable_get, :@@payload_cache).split("\x00").select {|i| i.size > 2}.map {|i| i.sub(/^[^\{]+/,'')}.last
|
54
|
+
|
55
|
+
expect(final_payload).to eq last_payload
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/spec/mysql_spec.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helpers/mysql_setup'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Mysql do
|
5
|
+
describe "#query" do
|
6
|
+
before do
|
7
|
+
@client = Mysql.new("localhost", ENV["MYSQL_USER"], "", "copperegg_apm_test")
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should benchmark time" do
|
11
|
+
result = @client.query("select * from users")
|
12
|
+
expect(result).to be_an_instance_of(Mysql::Result)
|
13
|
+
|
14
|
+
last_payload = CopperEgg::APM.send(:class_variable_get, :@@payload_cache).split("\x00").select {|i| i.size > 2}.map {|i| i.sub(/^[^\{]+/,'')}.last
|
15
|
+
hash = JSON.parse last_payload
|
16
|
+
|
17
|
+
expect(hash.keys.sort).to eq ["id", "inst"]
|
18
|
+
expect(hash["id"]).to match(/\A[0-1a-z]{16}\z/i)
|
19
|
+
expect(hash["inst"].keys.sort).to eq ["sql", "time"]
|
20
|
+
expect(hash["inst"]["sql"]).to eq "select * from users {Ruby}"
|
21
|
+
expect(hash["inst"]["time"].to_s).to match(/\A\d+\Z/)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should not benchmark transaction statements" do
|
25
|
+
payload = CopperEgg::APM.send(:class_variable_get, :@@payload_cache)
|
26
|
+
|
27
|
+
@client.query "begin"
|
28
|
+
|
29
|
+
expect(CopperEgg::APM.send(:class_variable_get, :@@payload_cache)).to eq payload
|
30
|
+
|
31
|
+
@client.query "select * from users"
|
32
|
+
|
33
|
+
last_payload = CopperEgg::APM.send(:class_variable_get, :@@payload_cache).split("\x00").select {|i| i.size > 2}.map {|i| i.sub(/^[^\{]+/,'')}.last
|
34
|
+
hash = JSON.parse last_payload
|
35
|
+
|
36
|
+
expect(hash["inst"]["sql"]).to eq "select * from users {Ruby}"
|
37
|
+
|
38
|
+
@client.query "commit"
|
39
|
+
|
40
|
+
final_payload = CopperEgg::APM.send(:class_variable_get, :@@payload_cache).split("\x00").select {|i| i.size > 2}.map {|i| i.sub(/^[^\{]+/,'')}.last
|
41
|
+
|
42
|
+
expect(final_payload).to eq last_payload
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#query (with block)" do
|
47
|
+
before do
|
48
|
+
@client = Mysql.new("localhost", ENV["MYSQL_USER"] || "root", "", "copperegg_apm_test")
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should benchmark time" do
|
52
|
+
@client.query("select * from users") do |result|
|
53
|
+
expect(result).to be_an_instance_of(Mysql::Result)
|
54
|
+
end
|
55
|
+
|
56
|
+
last_payload = CopperEgg::APM.send(:class_variable_get, :@@payload_cache).split("\x00").select {|i| i.size > 2}.map {|i| i.sub(/^[^\{]+/,'')}.last
|
57
|
+
hash = JSON.parse last_payload
|
58
|
+
|
59
|
+
expect(hash.keys.sort).to eq ["id", "inst"]
|
60
|
+
expect(hash["id"]).to match(/\A[0-1a-z]{16}\z/i)
|
61
|
+
expect(hash["inst"].keys.sort).to eq ["sql", "time"]
|
62
|
+
expect(hash["inst"]["sql"]).to eq "select * from users {Ruby}"
|
63
|
+
expect(hash["inst"]["time"].to_s).to match(/\A\d+\Z/)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Net::HTTP do
|
4
|
+
describe "#request" do
|
5
|
+
it "should benchmark time for a get request" do
|
6
|
+
uri = URI("http://api.rails.dev/v2/revealmetrics/metric_groups.json")
|
7
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
8
|
+
request.basic_auth :mikeapikey, :U
|
9
|
+
response = Net::HTTP.start(uri.host, uri.port) {|http| http.request(request)}
|
10
|
+
|
11
|
+
expect(response.code).to match(/\A\d{3}\Z/)
|
12
|
+
expect(response.body).to be_an_instance_of(String)
|
13
|
+
|
14
|
+
last_payload = CopperEgg::APM.send(:class_variable_get, :@@payload_cache).split("\x00").select {|i| i.size > 2}.map {|i| i.sub(/^[^\{]+/,'')}.last
|
15
|
+
hash = JSON.parse last_payload
|
16
|
+
|
17
|
+
expect(hash.keys.sort).to eq ["id", "inst"]
|
18
|
+
expect(hash["id"]).to match(/\A[0-1a-z]{16}\z/i)
|
19
|
+
expect(hash["inst"].keys.sort).to eq ["time", "url"]
|
20
|
+
expect(hash["inst"]["url"]).to eq "http://api.rails.dev/v2/revealmetrics/metric_groups.json {Ruby}"
|
21
|
+
expect(hash["inst"]["time"].to_s).to match(/\A\d+\Z/)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should not have authentication nor query params in the url" do
|
25
|
+
Net::HTTP.get(URI("http://mikeapikey:U@api.rails.dev/v2/revealmetrics/metric_groups.json?show_hidden=true"))
|
26
|
+
|
27
|
+
last_payload = CopperEgg::APM.send(:class_variable_get, :@@payload_cache).split("\x00").select {|i| i.size > 2}.map {|i| i.sub(/^[^\{]+/,'')}.last
|
28
|
+
hash = JSON.parse last_payload
|
29
|
+
|
30
|
+
expect(hash.keys.sort).to eq ["id", "inst"]
|
31
|
+
expect(hash["id"]).to match(/\A[0-1a-z]{16}\z/i)
|
32
|
+
expect(hash["inst"].keys.sort).to eq ["time", "url"]
|
33
|
+
expect(hash["inst"]["url"]).to eq "http://api.rails.dev/v2/revealmetrics/metric_groups.json {Ruby}"
|
34
|
+
expect(hash["inst"]["time"].to_s).to match(/\A\d+\Z/)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should benchmark time for a post request" do
|
38
|
+
response = Net::HTTP.post_form URI("http://mikeapikey:U@api.rails.dev/v2/revealmetrics/tags.json"), :tag => "asjasfe", :ids => "smtp"
|
39
|
+
|
40
|
+
expect(response.code).to match(/\A\d{3}\Z/)
|
41
|
+
|
42
|
+
last_payload = CopperEgg::APM.send(:class_variable_get, :@@payload_cache).split("\x00").select {|i| i.size > 2}.map {|i| i.sub(/^[^\{]+/,'')}.last
|
43
|
+
hash = JSON.parse last_payload
|
44
|
+
|
45
|
+
expect(hash.keys.sort).to eq ["id", "inst"]
|
46
|
+
expect(hash["id"]).to match(/\A[0-1a-z]{16}\z/i)
|
47
|
+
expect(hash["inst"].keys.sort).to eq ["time", "url"]
|
48
|
+
expect(hash["inst"]["url"]).to eq "http://api.rails.dev/v2/revealmetrics/tags.json {Ruby}"
|
49
|
+
expect(hash["inst"]["time"].to_s).to match(/\A\d+\Z/)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|