appsignal 1.0.4 → 1.0.5.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/ext/agent.yml +7 -7
- data/ext/appsignal_extension.c +5 -3
- data/lib/appsignal/event_formatter.rb +2 -0
- data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +1 -47
- data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +88 -0
- data/lib/appsignal/event_formatter/moped/query_formatter.rb +6 -7
- data/lib/appsignal/event_formatter/sequel/sql_formatter.rb +13 -0
- data/lib/appsignal/hooks/sequel.rb +4 -7
- data/lib/appsignal/integrations/capistrano/appsignal.cap +1 -1
- data/lib/appsignal/integrations/mongo_ruby_driver.rb +9 -5
- data/lib/appsignal/subscriber.rb +3 -2
- data/lib/appsignal/transaction.rb +6 -0
- data/lib/appsignal/utils.rb +15 -4
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/capistrano3_spec.rb +21 -1
- data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +1 -1
- data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +14 -186
- data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +115 -0
- data/spec/lib/appsignal/event_formatter/moped/query_formatter_spec.rb +4 -4
- data/spec/lib/appsignal/event_formatter/sequel/sql_formatter_spec.rb +22 -0
- data/spec/lib/appsignal/extension_spec.rb +1 -1
- data/spec/lib/appsignal/hooks/sequel_spec.rb +1 -1
- data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +8 -5
- data/spec/lib/appsignal/subscriber_spec.rb +23 -5
- data/spec/lib/appsignal/transaction_spec.rb +21 -0
- data/spec/lib/appsignal/utils_spec.rb +16 -0
- data/spec/support/helpers/env_helpers.rb +1 -0
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 60c1db0e297973e3f82bb7f4e066f81e7f3aa21b
|
4
|
+
data.tar.gz: 1ac6c8bd4fc0e5d427c92fde8c1fa2a277137f02
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b92b2e03ddd2ab61e795545deb0241e7bb87270389bd558b9b6bb2b72da38f3a91b6171b595df64b0b2f498a9345622afb3048cbf9cde4363e0df413a38dbd09
|
7
|
+
data.tar.gz: d26efb030425c886260fd4e0fa9788127dd4bb829bc4bb9e8efc44e041e92d03be44a0246b54aadec6b7b9b72c9be703d60de48efdff428213d523a2a557d69e
|
data/CHANGELOG.md
CHANGED
data/ext/agent.yml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
|
-
version:
|
2
|
+
version: 6b0801e
|
3
3
|
triples:
|
4
4
|
x86_64-linux:
|
5
|
-
checksum:
|
6
|
-
download_url: https://appsignal-agent-releases.global.ssl.fastly.net/
|
5
|
+
checksum: 510a28ef2d76351ca308ebf8950ad50e8c93b4ec955c25f72b658f3ab009d42b
|
6
|
+
download_url: https://appsignal-agent-releases.global.ssl.fastly.net/6b0801e/appsignal-agent-x86_64-linux-static.tar.gz
|
7
7
|
lib_filename: libappsignal.a
|
8
8
|
i686-linux:
|
9
|
-
checksum:
|
10
|
-
download_url: https://appsignal-agent-releases.global.ssl.fastly.net/
|
9
|
+
checksum: 7aed9373264128c38c515463c671fba03db2fbc863c85bae77c56a2d240ac86f
|
10
|
+
download_url: https://appsignal-agent-releases.global.ssl.fastly.net/6b0801e/appsignal-agent-i686-linux-static.tar.gz
|
11
11
|
lib_filename: libappsignal.a
|
12
12
|
x86_64-darwin:
|
13
|
-
checksum:
|
14
|
-
download_url: https://appsignal-agent-releases.global.ssl.fastly.net/
|
13
|
+
checksum: 60ac2a74933d9ac58f441f6ee3f875f5c0cbdee24b6b671f7fc81db992ea117c
|
14
|
+
download_url: https://appsignal-agent-releases.global.ssl.fastly.net/6b0801e/appsignal-agent-x86_64-darwin-static.tar.gz
|
15
15
|
lib_filename: libappsignal.a
|
data/ext/appsignal_extension.c
CHANGED
@@ -26,17 +26,19 @@ static VALUE start_event(VALUE self, VALUE transaction_index) {
|
|
26
26
|
return Qnil;
|
27
27
|
}
|
28
28
|
|
29
|
-
static VALUE finish_event(VALUE self, VALUE transaction_index, VALUE name, VALUE title, VALUE body) {
|
29
|
+
static VALUE finish_event(VALUE self, VALUE transaction_index, VALUE name, VALUE title, VALUE body, VALUE body_format) {
|
30
30
|
Check_Type(transaction_index, T_FIXNUM);
|
31
31
|
Check_Type(name, T_STRING);
|
32
32
|
Check_Type(title, T_STRING);
|
33
33
|
Check_Type(body, T_STRING);
|
34
|
+
Check_Type(body_format, T_FIXNUM);
|
34
35
|
|
35
36
|
appsignal_finish_event(
|
36
37
|
FIX2INT(transaction_index),
|
37
38
|
StringValueCStr(name),
|
38
39
|
StringValueCStr(title),
|
39
|
-
StringValueCStr(body)
|
40
|
+
StringValueCStr(body),
|
41
|
+
FIX2INT(body_format)
|
40
42
|
);
|
41
43
|
return Qnil;
|
42
44
|
}
|
@@ -216,7 +218,7 @@ void Init_appsignal_extension(void) {
|
|
216
218
|
rb_define_singleton_method(Extension, "stop", stop, 0);
|
217
219
|
rb_define_singleton_method(Extension, "start_transaction", start_transaction, 2);
|
218
220
|
rb_define_singleton_method(Extension, "start_event", start_event, 1);
|
219
|
-
rb_define_singleton_method(Extension, "finish_event", finish_event,
|
221
|
+
rb_define_singleton_method(Extension, "finish_event", finish_event, 5);
|
220
222
|
rb_define_singleton_method(Extension, "set_transaction_error", set_transaction_error, 4);
|
221
223
|
rb_define_singleton_method(Extension, "set_transaction_sample_data", set_transaction_sample_data, 3);
|
222
224
|
rb_define_singleton_method(Extension, "set_transaction_action", set_transaction_action, 2);
|
@@ -4,55 +4,9 @@ module Appsignal
|
|
4
4
|
class SqlFormatter < Appsignal::EventFormatter
|
5
5
|
register 'sql.active_record'
|
6
6
|
|
7
|
-
SINGLE_QUOTED_STRING = /'(.?|[^']).*'/.freeze
|
8
|
-
DOUBLE_QUOTED_STRING = /"(.?|[^"]).*"/.freeze
|
9
|
-
IN_OPERATOR_CONTENT = /(IN \()[^SELECT][^\)]+(\))/.freeze
|
10
|
-
NUMERIC = /\d*\.?\d+/.freeze
|
11
|
-
REPLACEMENT = '?'.freeze
|
12
|
-
IN_REPLACEMENT = '\1?\2'.freeze
|
13
|
-
SCHEMA = 'SCHEMA'.freeze
|
14
|
-
|
15
|
-
attr_reader :adapter_uses_double_quoted_table_names
|
16
|
-
|
17
|
-
def initialize
|
18
|
-
@connection_config = connection_config
|
19
|
-
@adapter_uses_double_quoted_table_names = adapter_uses_double_quoted_table_names?
|
20
|
-
rescue ::ActiveRecord::ConnectionNotEstablished
|
21
|
-
Appsignal::EventFormatter.unregister('sql.active_record', self.class)
|
22
|
-
Appsignal.logger.error('Error while getting ActiveRecord connection info, unregistering sql.active_record event formatter')
|
23
|
-
end
|
24
|
-
|
25
7
|
def format(payload)
|
26
|
-
|
27
|
-
sql_string = payload[:sql].dup
|
28
|
-
unless adapter_uses_double_quoted_table_names
|
29
|
-
sql_string.gsub!(DOUBLE_QUOTED_STRING, REPLACEMENT)
|
30
|
-
end
|
31
|
-
sql_string.gsub!(SINGLE_QUOTED_STRING, REPLACEMENT)
|
32
|
-
sql_string.gsub!(IN_OPERATOR_CONTENT, IN_REPLACEMENT)
|
33
|
-
sql_string.gsub!(NUMERIC, REPLACEMENT)
|
34
|
-
[payload[:name], sql_string]
|
8
|
+
[payload[:name], payload[:sql], SQL_BODY_FORMAT]
|
35
9
|
end
|
36
|
-
|
37
|
-
protected
|
38
|
-
|
39
|
-
def schema_query?(payload)
|
40
|
-
payload[:name] == SCHEMA
|
41
|
-
end
|
42
|
-
|
43
|
-
def connection_config
|
44
|
-
# TODO handle ActiveRecord::ConnectionNotEstablished
|
45
|
-
if ::ActiveRecord::Base.respond_to?(:connection_config)
|
46
|
-
::ActiveRecord::Base.connection_config
|
47
|
-
else
|
48
|
-
::ActiveRecord::Base.connection_pool.spec.config
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def adapter_uses_double_quoted_table_names?
|
53
|
-
adapter = @connection_config[:adapter]
|
54
|
-
adapter =~ /postgres/ || adapter =~ /sqlite/
|
55
|
-
end
|
56
10
|
end
|
57
11
|
end
|
58
12
|
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Appsignal
|
2
|
+
class EventFormatter
|
3
|
+
module MongoRubyDriver
|
4
|
+
class QueryFormatter
|
5
|
+
ALLOWED = {
|
6
|
+
"find" => {
|
7
|
+
"find" => :allow,
|
8
|
+
"filter" => :sanitize_document
|
9
|
+
},
|
10
|
+
"count" => {
|
11
|
+
"count" => :allow,
|
12
|
+
"query" => :sanitize_document
|
13
|
+
},
|
14
|
+
"distinct" => {
|
15
|
+
"distinct" => :allow,
|
16
|
+
"key" => :allow,
|
17
|
+
"query" => :sanitize_document
|
18
|
+
},
|
19
|
+
"insert" => {
|
20
|
+
"insert" => :allow,
|
21
|
+
"documents" => :deny_array,
|
22
|
+
"ordered" => :allow
|
23
|
+
},
|
24
|
+
"update" => {
|
25
|
+
"update" => :allow,
|
26
|
+
"updates" => :sanitize_bulk,
|
27
|
+
"ordered" => :allow
|
28
|
+
},
|
29
|
+
"findandmodify" => {
|
30
|
+
"findandmodify" => :allow,
|
31
|
+
"query" => :sanitize_document,
|
32
|
+
"update" => :deny_array,
|
33
|
+
"new" => :allow
|
34
|
+
},
|
35
|
+
"delete" => {
|
36
|
+
"delete" => :allow,
|
37
|
+
"deletes" => :sanitize_bulk,
|
38
|
+
"ordered" => :allow
|
39
|
+
},
|
40
|
+
"bulk" => {
|
41
|
+
"q" => :sanitize_document,
|
42
|
+
"u" => :deny_array,
|
43
|
+
"limit" => :allow,
|
44
|
+
"multi" => :allow,
|
45
|
+
"upsert" => :allow
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
# Format command based on given strategy
|
50
|
+
def self.format(strategy, command)
|
51
|
+
# Stop processing if command is not a hash
|
52
|
+
return {} unless command.is_a?(Hash)
|
53
|
+
|
54
|
+
# Get the strategy and stop if it's not present
|
55
|
+
strategies = ALLOWED[strategy.to_s]
|
56
|
+
return {} unless strategies
|
57
|
+
|
58
|
+
{}.tap do |hsh|
|
59
|
+
command.each do |key, val|
|
60
|
+
hsh[key] = self.apply_strategy(strategies[key], val)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Applies strategy on hash values based on keys
|
66
|
+
def self.apply_strategy(strategy, val)
|
67
|
+
case strategy
|
68
|
+
when :allow then val
|
69
|
+
when :deny then '?'
|
70
|
+
when :deny_array then '[?]'
|
71
|
+
when :sanitize_document
|
72
|
+
Appsignal::Utils.sanitize(val, true, :mongodb)
|
73
|
+
when :sanitize_bulk
|
74
|
+
if val.length > 1
|
75
|
+
[
|
76
|
+
self.format(:bulk, val.first),
|
77
|
+
"[...]"
|
78
|
+
]
|
79
|
+
else
|
80
|
+
val.map { |v| self.format(:bulk, v) }
|
81
|
+
end
|
82
|
+
else '?'
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -11,12 +11,12 @@ module Appsignal
|
|
11
11
|
when 'Moped::Protocol::Command'
|
12
12
|
return ['Command', {
|
13
13
|
:database => op.full_collection_name,
|
14
|
-
:selector => Appsignal::Utils.sanitize(op.selector)
|
14
|
+
:selector => Appsignal::Utils.sanitize(op.selector, true, :mongodb)
|
15
15
|
}.inspect]
|
16
16
|
when 'Moped::Protocol::Query'
|
17
17
|
return ['Query', {
|
18
18
|
:database => op.full_collection_name,
|
19
|
-
:selector => Appsignal::Utils.sanitize(op.selector),
|
19
|
+
:selector => Appsignal::Utils.sanitize(op.selector, false, :mongodb),
|
20
20
|
:flags => op.flags,
|
21
21
|
:limit => op.limit,
|
22
22
|
:skip => op.skip,
|
@@ -25,21 +25,21 @@ module Appsignal
|
|
25
25
|
when 'Moped::Protocol::Delete'
|
26
26
|
return ['Delete', {
|
27
27
|
:database => op.full_collection_name,
|
28
|
-
:selector => Appsignal::Utils.sanitize(op.selector),
|
28
|
+
:selector => Appsignal::Utils.sanitize(op.selector, false, :mongodb),
|
29
29
|
:flags => op.flags,
|
30
30
|
}.inspect]
|
31
31
|
when 'Moped::Protocol::Insert'
|
32
32
|
return ['Insert', {
|
33
33
|
:database => op.full_collection_name,
|
34
|
-
:documents => Appsignal::Utils.sanitize(op.documents, true),
|
34
|
+
:documents => Appsignal::Utils.sanitize(op.documents, true, :mongodb),
|
35
35
|
:count => op.documents.count,
|
36
36
|
:flags => op.flags,
|
37
37
|
}.inspect]
|
38
38
|
when 'Moped::Protocol::Update'
|
39
39
|
return ['Update', {
|
40
40
|
:database => op.full_collection_name,
|
41
|
-
:selector => Appsignal::Utils.sanitize(op.selector),
|
42
|
-
:update => Appsignal::Utils.sanitize(op.update, true),
|
41
|
+
:selector => Appsignal::Utils.sanitize(op.selector, false, :mongodb),
|
42
|
+
:update => Appsignal::Utils.sanitize(op.update, true, :mongodb),
|
43
43
|
:flags => op.flags,
|
44
44
|
}.inspect]
|
45
45
|
when 'Moped::Protocol::KillCursors'
|
@@ -53,7 +53,6 @@ module Appsignal
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
56
|
-
|
57
56
|
end
|
58
57
|
end
|
59
58
|
end
|
@@ -3,13 +3,10 @@ module Appsignal
|
|
3
3
|
module SequelExtension
|
4
4
|
# Add query instrumentation
|
5
5
|
def log_yield(sql, args = nil)
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
# formatter.
|
11
|
-
|
12
|
-
ActiveSupport::Notifications.instrument('sql.sequel') do
|
6
|
+
ActiveSupport::Notifications.instrument(
|
7
|
+
'sql.sequel',
|
8
|
+
:sql => sql
|
9
|
+
) do
|
13
10
|
yield
|
14
11
|
end
|
15
12
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
namespace :appsignal do
|
2
2
|
task :deploy do
|
3
|
-
env = fetch(:rails_env, fetch(:rack_env, 'production'))
|
3
|
+
env = fetch(:stage, fetch(:rails_env, fetch(:rack_env, 'production')))
|
4
4
|
user = ENV['USER'] || ENV['USERNAME']
|
5
5
|
revision = fetch(:appsignal_revision, fetch(:current_revision))
|
6
6
|
logger = fetch(:logger, Logger.new($stdout))
|
@@ -1,16 +1,19 @@
|
|
1
1
|
module Appsignal
|
2
2
|
class Hooks
|
3
3
|
class MongoMonitorSubscriber
|
4
|
-
|
5
4
|
# Called by Mongo::Monitor when query starts
|
6
5
|
def started(event)
|
7
6
|
transaction = Appsignal::Transaction.current
|
8
7
|
return if transaction.nil_transaction?
|
9
8
|
return if transaction.paused?
|
10
9
|
|
10
|
+
# Format the command
|
11
|
+
command = Appsignal::EventFormatter::MongoRubyDriver::QueryFormatter
|
12
|
+
.format(event.command_name, event.command)
|
13
|
+
|
11
14
|
# Store the query on the transaction, we need it when the event finishes
|
12
15
|
store = transaction.store('mongo_driver')
|
13
|
-
store[event.request_id] =
|
16
|
+
store[event.request_id] = command
|
14
17
|
|
15
18
|
# Start this event
|
16
19
|
Appsignal::Extension.start_event(transaction.transaction_index)
|
@@ -36,14 +39,15 @@ module Appsignal
|
|
36
39
|
|
37
40
|
# Get the query from the transaction store
|
38
41
|
store = transaction.store('mongo_driver')
|
39
|
-
command = store
|
42
|
+
command = store.delete(event.request_id) || {}
|
40
43
|
|
41
44
|
# Finish the event in the extension.
|
42
45
|
Appsignal::Extension.finish_event(
|
43
46
|
transaction.transaction_index,
|
44
47
|
'query.mongodb',
|
45
|
-
event.command_name.to_s,
|
46
|
-
|
48
|
+
"#{event.command_name.to_s} | #{event.database_name} | #{result}",
|
49
|
+
JSON.generate(command),
|
50
|
+
0
|
47
51
|
)
|
48
52
|
end
|
49
53
|
end
|
data/lib/appsignal/subscriber.rb
CHANGED
@@ -45,12 +45,13 @@ module Appsignal
|
|
45
45
|
return unless transaction = Appsignal::Transaction.current
|
46
46
|
return if transaction.nil_transaction? || transaction.paused?
|
47
47
|
|
48
|
-
title, body = Appsignal::EventFormatter.format(name, payload)
|
48
|
+
title, body, body_format = Appsignal::EventFormatter.format(name, payload)
|
49
49
|
Appsignal::Extension.finish_event(
|
50
50
|
transaction.transaction_index,
|
51
51
|
name,
|
52
52
|
title || BLANK,
|
53
|
-
body || BLANK
|
53
|
+
body || BLANK,
|
54
|
+
body_format || 0
|
54
55
|
)
|
55
56
|
end
|
56
57
|
end
|
@@ -124,6 +124,7 @@ module Appsignal
|
|
124
124
|
:params => sanitized_params,
|
125
125
|
:environment => sanitized_environment,
|
126
126
|
:session_data => sanitized_session_data,
|
127
|
+
:metadata => metadata,
|
127
128
|
:tags => sanitized_tags
|
128
129
|
}.each do |key, data|
|
129
130
|
set_sample_data(key, data)
|
@@ -212,6 +213,11 @@ module Appsignal
|
|
212
213
|
Appsignal::ParamsSanitizer.sanitize(session.to_hash)
|
213
214
|
end
|
214
215
|
|
216
|
+
def metadata
|
217
|
+
return unless request.env
|
218
|
+
request.env[:metadata]
|
219
|
+
end
|
220
|
+
|
215
221
|
# Only keep tags if they meet the following criteria:
|
216
222
|
# * Key is a symbol or string with less then 100 chars
|
217
223
|
# * Value is a symbol or string with less then 100 chars
|
data/lib/appsignal/utils.rb
CHANGED
@@ -1,25 +1,36 @@
|
|
1
1
|
module Appsignal
|
2
2
|
module Utils
|
3
|
-
def self.sanitize(params, only_top_level=false)
|
3
|
+
def self.sanitize(params, only_top_level=false, key_sanitizer=nil)
|
4
4
|
if params.is_a?(Hash)
|
5
5
|
{}.tap do |hsh|
|
6
6
|
params.each do |key, val|
|
7
|
-
hsh[key] =
|
7
|
+
hsh[self.sanitize_key(key, key_sanitizer)] = if only_top_level
|
8
|
+
'?'
|
9
|
+
else
|
10
|
+
sanitize(val, only_top_level, key_sanitizer=nil)
|
11
|
+
end
|
8
12
|
end
|
9
13
|
end
|
10
14
|
elsif params.is_a?(Array)
|
11
15
|
if only_top_level
|
12
|
-
sanitize(params[0], only_top_level)
|
16
|
+
sanitize(params[0], only_top_level, key_sanitizer=nil)
|
13
17
|
elsif params.first.is_a?(String)
|
14
18
|
['?']
|
15
19
|
else
|
16
20
|
params.map do |item|
|
17
|
-
sanitize(item, only_top_level)
|
21
|
+
sanitize(item, only_top_level, key_sanitizer=nil)
|
18
22
|
end
|
19
23
|
end
|
20
24
|
else
|
21
25
|
'?'
|
22
26
|
end
|
23
27
|
end
|
28
|
+
|
29
|
+
def self.sanitize_key(key, sanitizer)
|
30
|
+
case sanitizer
|
31
|
+
when :mongodb then key.gsub(/(\..+)/, '.?')
|
32
|
+
else key
|
33
|
+
end
|
34
|
+
end
|
24
35
|
end
|
25
36
|
end
|
data/lib/appsignal/version.rb
CHANGED
@@ -80,9 +80,29 @@ if capistrano3_present?
|
|
80
80
|
)
|
81
81
|
end
|
82
82
|
end
|
83
|
+
|
84
|
+
context "when stage is used instead of rack_env / rails_env" do
|
85
|
+
before do
|
86
|
+
@capistrano_config.delete(:rails_env)
|
87
|
+
@capistrano_config.set(:stage, 'stage_production')
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should be instantiated with the right params" do
|
91
|
+
Appsignal::Config.should_receive(:new).with(
|
92
|
+
project_fixture_path,
|
93
|
+
'stage_production',
|
94
|
+
{:name => 'AppName'},
|
95
|
+
kind_of(Logger)
|
96
|
+
)
|
97
|
+
end
|
98
|
+
end
|
83
99
|
end
|
84
100
|
|
85
|
-
after
|
101
|
+
after do
|
102
|
+
invoke('appsignal:deploy')
|
103
|
+
@capistrano_config.delete(:stage)
|
104
|
+
@capistrano_config.delete(:rack_env)
|
105
|
+
end
|
86
106
|
end
|
87
107
|
|
88
108
|
context "send marker" do
|
@@ -4,7 +4,7 @@ describe Appsignal::EventFormatter::ActiveRecord::InstantiationFormatter do
|
|
4
4
|
let(:klass) { Appsignal::EventFormatter::ActiveRecord::InstantiationFormatter }
|
5
5
|
let(:formatter) { klass.new }
|
6
6
|
|
7
|
-
it "should register
|
7
|
+
it "should register instantiation.active_record" do
|
8
8
|
Appsignal::EventFormatter.registered?('instantiation.active_record', klass).should be_true
|
9
9
|
end
|
10
10
|
|
@@ -1,195 +1,23 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
describe Appsignal::EventFormatter::ActiveRecord::InstantiationFormatter do
|
4
|
+
let(:klass) { Appsignal::EventFormatter::ActiveRecord::SqlFormatter }
|
5
|
+
let(:formatter) { klass.new }
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
let(:connection_config) { {} }
|
10
|
-
before do
|
11
|
-
if ActiveRecord::Base.respond_to?(:connection_config)
|
12
|
-
# Rails 3.1+
|
13
|
-
ActiveRecord::Base.stub(
|
14
|
-
:connection_config => connection_config
|
15
|
-
)
|
16
|
-
else
|
17
|
-
# Rails 3.0
|
18
|
-
spec = double(:config => connection_config)
|
19
|
-
ActiveRecord::Base.stub(
|
20
|
-
:connection_pool => double(:spec => spec)
|
21
|
-
)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
pending "should register sql.activerecord" do
|
26
|
-
Appsignal::EventFormatter.registered?('sql.active_record', klass).should be_true
|
27
|
-
end
|
28
|
-
|
29
|
-
context "if a connection cannot be established" do
|
30
|
-
before do
|
31
|
-
ActiveRecord::Base.stub(:connection_config).and_raise(ActiveRecord::ConnectionNotEstablished)
|
32
|
-
end
|
33
|
-
|
34
|
-
it "should log the error and unregister the formatter" do
|
35
|
-
Appsignal.logger.should_receive(:error).with(
|
36
|
-
'Error while getting ActiveRecord connection info, unregistering sql.active_record event formatter'
|
37
|
-
)
|
38
|
-
|
39
|
-
lambda {
|
40
|
-
formatter
|
41
|
-
}.should_not raise_error
|
42
|
-
|
43
|
-
Appsignal::EventFormatter.registered?('sql.active_record').should be_false
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
describe "#format" do
|
48
|
-
let(:name) { 'Model load' }
|
49
|
-
let(:payload) { {:sql => sql, :name => name} }
|
50
|
-
subject { formatter.format(payload) }
|
51
|
-
|
52
|
-
context "with backtick table names" do
|
53
|
-
before { formatter.stub(:adapter_uses_double_quoted_table_names => false) }
|
54
|
-
|
55
|
-
context "single quoted data value" do
|
56
|
-
let(:sql) { "SELECT `table`.* FROM `table` WHERE `id` = 'secret' ORDER BY `table`.`id` ASC LIMIT 1" }
|
57
|
-
|
58
|
-
it { should == ['Model load', "SELECT `table`.* FROM `table` WHERE `id` = ? ORDER BY `table`.`id` ASC LIMIT ?"] }
|
59
|
-
|
60
|
-
context "with escaped single quotes in the string" do
|
61
|
-
let(:sql) { "`id` = 'this is a \'big\' secret'" }
|
62
|
-
|
63
|
-
it { should == ['Model load', "`id` = ?"] }
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
context "double quoted data value" do
|
68
|
-
let(:sql) { 'SELECT `table`.* FROM `table` WHERE `id` = "secret"' }
|
69
|
-
|
70
|
-
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `id` = ?'] }
|
71
|
-
|
72
|
-
context "with escaped double quotes in the string" do
|
73
|
-
let(:sql) { '`id` = "this is a \"big\" secret"' }
|
74
|
-
|
75
|
-
it { should == ['Model load', "`id` = ?"] }
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
context "numeric parameter" do
|
80
|
-
context "integer" do
|
81
|
-
let(:sql) { 'SELECT `table`.* FROM `table` WHERE `id` = 1' }
|
82
|
-
|
83
|
-
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `id` = ?'] }
|
84
|
-
end
|
85
|
-
|
86
|
-
context "float" do
|
87
|
-
let(:sql) { 'SELECT `table`.* FROM `table` WHERE `value` = 10.0' }
|
88
|
-
|
89
|
-
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `value` = ?'] }
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
context "in operator with values" do
|
94
|
-
let(:sql) { 'SELECT `table`.* FROM `table` WHERE `id` IN (1, 2)' }
|
95
|
-
|
96
|
-
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `id` IN (?)'] }
|
97
|
-
end
|
98
|
-
|
99
|
-
context "in operator with inner query" do
|
100
|
-
let(:sql) { 'SELECT `table`.* FROM `table` WHERE `id` IN (SELECT `id` from `other_table` WHERE `value` = 10.0)' }
|
101
|
-
|
102
|
-
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `id` IN (SELECT `id` from `other_table` WHERE `value` = ?)'] }
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
context "with double quote style table names" do
|
107
|
-
let(:connection_config) { {:adapter => 'postgresql'} }
|
108
|
-
|
109
|
-
context "single quoted data value" do
|
110
|
-
let(:sql) { "SELECT \"table\".* FROM \"table\" WHERE \"id\" = 'secret' ORDER BY \"table\".\"id\" ASC LIMIT 1" }
|
111
|
-
|
112
|
-
it { should == ['Model load', "SELECT \"table\".* FROM \"table\" WHERE \"id\" = ? ORDER BY \"table\".\"id\" ASC LIMIT ?"] }
|
113
|
-
|
114
|
-
context "with an escaped single quote" do
|
115
|
-
let(:sql) { "\"id\" = 'this is a \'big\' secret'" }
|
116
|
-
|
117
|
-
it { should == ['Model load', "\"id\" = ?"] }
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
context "numeric parameter" do
|
122
|
-
context "integer" do
|
123
|
-
let(:sql) { 'SELECT "table".* FROM "table" WHERE "id"=1' }
|
124
|
-
|
125
|
-
it { should == ['Model load', 'SELECT "table".* FROM "table" WHERE "id"=?'] }
|
126
|
-
end
|
127
|
-
|
128
|
-
context "float" do
|
129
|
-
let(:sql) { 'SELECT "table".* FROM "table" WHERE "value"=10.0' }
|
130
|
-
|
131
|
-
it { should == ['Model load', 'SELECT "table".* FROM "table" WHERE "value"=?'] }
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
context "return nil for schema queries" do
|
137
|
-
let(:name) { 'SCHEMA' }
|
138
|
-
let(:sql) { 'SET client_min_messages TO 22' }
|
139
|
-
|
140
|
-
it { should be_nil }
|
141
|
-
end
|
142
|
-
|
143
|
-
context "with a a frozen sql string" do
|
144
|
-
let(:sql) { "SELECT `table`.* FROM `table` WHERE `id` = 'secret'".freeze }
|
145
|
-
|
146
|
-
it { should == ['Model load', "SELECT `table`.* FROM `table` WHERE `id` = ?"] }
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
describe "#schema_query?" do
|
151
|
-
let(:payload) { {} }
|
152
|
-
subject { formatter.send(:schema_query?, payload) }
|
153
|
-
|
154
|
-
it { should be_false }
|
155
|
-
|
156
|
-
context "when name is schema" do
|
157
|
-
let(:payload) { {:name => 'SCHEMA'} }
|
7
|
+
it "should register sql.active_record" do
|
8
|
+
Appsignal::EventFormatter.registered?('sql.active_record', klass).should be_true
|
9
|
+
end
|
158
10
|
|
159
|
-
|
160
|
-
|
11
|
+
describe "#format" do
|
12
|
+
let(:payload) do
|
13
|
+
{
|
14
|
+
name: 'User load',
|
15
|
+
sql: 'SELECT * FROM users'
|
16
|
+
}
|
161
17
|
end
|
162
18
|
|
163
|
-
|
164
|
-
describe "#connection_config" do
|
165
|
-
let(:connection_config) { {:adapter => 'adapter'} }
|
166
|
-
|
167
|
-
subject { formatter.send(:connection_config) }
|
168
|
-
|
169
|
-
it { should == {:adapter => 'adapter'} }
|
170
|
-
end
|
171
|
-
|
172
|
-
describe "#adapter_uses_double_quoted_table_names" do
|
173
|
-
subject { formatter.adapter_uses_double_quoted_table_names }
|
19
|
+
subject { formatter.format(payload) }
|
174
20
|
|
175
|
-
|
176
|
-
let(:connection_config) { {:adapter => 'mysql'} }
|
177
|
-
|
178
|
-
it { should be_false }
|
179
|
-
end
|
180
|
-
|
181
|
-
context "when using postgresql" do
|
182
|
-
let(:connection_config) { {:adapter => 'postgresql'} }
|
183
|
-
|
184
|
-
it { should be_true }
|
185
|
-
end
|
186
|
-
|
187
|
-
context "when using sqlite" do
|
188
|
-
let(:connection_config) { {:adapter => 'sqlite'} }
|
189
|
-
|
190
|
-
it { should be_true }
|
191
|
-
end
|
192
|
-
end
|
193
|
-
end
|
21
|
+
it { should == ['User load', 'SELECT * FROM users', 1] }
|
194
22
|
end
|
195
23
|
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Appsignal::EventFormatter::MongoRubyDriver::QueryFormatter do
|
4
|
+
let(:formatter) { Appsignal::EventFormatter::MongoRubyDriver::QueryFormatter }
|
5
|
+
|
6
|
+
describe ".format" do
|
7
|
+
let(:strategy) { :find }
|
8
|
+
let(:command) do
|
9
|
+
{
|
10
|
+
"find" => "users",
|
11
|
+
"filter" => {"_id" => 1}
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should apply a strategy for each key" do
|
16
|
+
expect( formatter ).to receive(:apply_strategy)
|
17
|
+
.with(:sanitize_document, {"_id" => 1})
|
18
|
+
|
19
|
+
expect( formatter ).to receive(:apply_strategy)
|
20
|
+
.with(:allow, "users")
|
21
|
+
|
22
|
+
formatter.format(strategy, command)
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when strategy is unkown" do
|
26
|
+
let(:strategy) { :bananas }
|
27
|
+
|
28
|
+
it "should return an empty hash" do
|
29
|
+
expect( formatter.format(strategy, command) ).to eql({})
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when command is not a hash " do
|
34
|
+
let(:command) { :bananas }
|
35
|
+
|
36
|
+
it "should return an empty hash" do
|
37
|
+
expect( formatter.format(strategy, command) ).to eql({})
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe ".apply_strategy" do
|
43
|
+
context "when strategy is allow" do
|
44
|
+
let(:strategy) { :allow }
|
45
|
+
let(:value) { {"_id" => 1} }
|
46
|
+
|
47
|
+
it "should return the given value" do
|
48
|
+
expect( formatter.apply_strategy(strategy, value) ).to eql(value)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "when strategy is deny" do
|
53
|
+
let(:strategy) { :deny }
|
54
|
+
let(:value) { {"_id" => 1} }
|
55
|
+
|
56
|
+
it "should return a '?'" do
|
57
|
+
expect( formatter.apply_strategy(strategy, value) ).to eql('?')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "when strategy is deny_array" do
|
62
|
+
let(:strategy) { :deny_array }
|
63
|
+
let(:value) { {"_id" => 1} }
|
64
|
+
|
65
|
+
it "should return a sanitized array string" do
|
66
|
+
expect( formatter.apply_strategy(strategy, value) ).to eql("[?]")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when strategy is sanitize_document" do
|
71
|
+
let(:strategy) { :sanitize_document }
|
72
|
+
let(:value) { {"_id" => 1} }
|
73
|
+
|
74
|
+
it "should return a sanitized document" do
|
75
|
+
expect( formatter.apply_strategy(strategy, value) ).to eql({"_id" => '?'})
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "when strategy is sanitize_bulk" do
|
80
|
+
let(:strategy) { :sanitize_bulk }
|
81
|
+
let(:value) { [{"q" => {"_id" => 1}, "u" => [{"foo" => "bar"}]}] }
|
82
|
+
|
83
|
+
it "should return an array of sanitized bulk documents" do
|
84
|
+
expect( formatter.apply_strategy(strategy, value) ).to eql([
|
85
|
+
{"q" => {"_id" => '?'}, "u" => '[?]'}
|
86
|
+
])
|
87
|
+
end
|
88
|
+
|
89
|
+
context "when bulk has more than one update" do
|
90
|
+
let(:value) do
|
91
|
+
[
|
92
|
+
{"q" => {"_id" => 1}, "u" => [{"foo" => "bar"}]},
|
93
|
+
{"q" => {"_id" => 2}, "u" => [{"foo" => "baz"}]},
|
94
|
+
]
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should return only the first value of sanitized bulk documents" do
|
98
|
+
expect( formatter.apply_strategy(strategy, value) ).to eql([
|
99
|
+
{"q" => {"_id" => '?'}, "u" => '[?]'},
|
100
|
+
"[...]"
|
101
|
+
])
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context "when strategy is missing" do
|
107
|
+
let(:strategy) { nil }
|
108
|
+
let(:value) { {"_id" => 1} }
|
109
|
+
|
110
|
+
it "should return a '?'" do
|
111
|
+
expect( formatter.apply_strategy(strategy, value) ).to eql('?')
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -22,12 +22,12 @@ describe Appsignal::EventFormatter::Moped::QueryFormatter do
|
|
22
22
|
let(:op) do
|
23
23
|
double(
|
24
24
|
:full_collection_name => 'database.collection',
|
25
|
-
:selector => {'_id' => 'abc'},
|
25
|
+
:selector => {'query' => {'_id' => 'abc'}},
|
26
26
|
:class => double(:to_s => 'Moped::Protocol::Command')
|
27
27
|
)
|
28
28
|
end
|
29
29
|
|
30
|
-
it { should == ['Command', '{:database=>"database.collection", :selector=>{"
|
30
|
+
it { should == ['Command', '{:database=>"database.collection", :selector=>{"query"=>"?"}}'] }
|
31
31
|
end
|
32
32
|
|
33
33
|
context "Moped::Protocol::Query" do
|
@@ -80,13 +80,13 @@ describe Appsignal::EventFormatter::Moped::QueryFormatter do
|
|
80
80
|
double(
|
81
81
|
:full_collection_name => 'database.collection',
|
82
82
|
:selector => {'_id' => 'abc'},
|
83
|
-
:update => {'name' => 'James Bond'},
|
83
|
+
:update => {'user.name' => 'James Bond'},
|
84
84
|
:flags => [],
|
85
85
|
:class => double(:to_s => 'Moped::Protocol::Update')
|
86
86
|
)
|
87
87
|
end
|
88
88
|
|
89
|
-
it { should == ['Update', '{:database=>"database.collection", :selector=>{"_id"=>"?"}, :update=>{"
|
89
|
+
it { should == ['Update', '{:database=>"database.collection", :selector=>{"_id"=>"?"}, :update=>{"user.?"=>"?"}, :flags=>[]}'] }
|
90
90
|
end
|
91
91
|
|
92
92
|
context "Moped::Protocol::KillCursors" do
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Appsignal::EventFormatter::Sequel::SqlFormatter do
|
4
|
+
let(:klass) { Appsignal::EventFormatter::Sequel::SqlFormatter }
|
5
|
+
let(:formatter) { klass.new }
|
6
|
+
|
7
|
+
it "should register sql.sequel" do
|
8
|
+
Appsignal::EventFormatter.registered?('sql.sequel', klass).should be_true
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#format" do
|
12
|
+
let(:payload) do
|
13
|
+
{
|
14
|
+
sql: 'SELECT * FROM users'
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
subject { formatter.format(payload) }
|
19
|
+
|
20
|
+
it { should == [nil, 'SELECT * FROM users', 1] }
|
21
|
+
end
|
22
|
+
end
|
@@ -46,7 +46,7 @@ describe "extension loading and operation" do
|
|
46
46
|
end
|
47
47
|
|
48
48
|
it "should have a finish_event method" do
|
49
|
-
subject.finish_event(1, 'name', 'title', 'body')
|
49
|
+
subject.finish_event(1, 'name', 'title', 'body', 0)
|
50
50
|
end
|
51
51
|
|
52
52
|
it "should have a set_transaction_error method" do
|
@@ -15,7 +15,7 @@ describe "Sequel integration", if: sequel_present? do
|
|
15
15
|
.at_least(:once)
|
16
16
|
expect( Appsignal::Extension ).to receive(:finish_event)
|
17
17
|
.at_least(:once)
|
18
|
-
.with(kind_of(Integer), "sql.sequel", "",
|
18
|
+
.with(kind_of(Integer), "sql.sequel", "", kind_of(String), 1)
|
19
19
|
|
20
20
|
db['SELECT 1'].all
|
21
21
|
end
|
@@ -11,13 +11,15 @@ describe Appsignal::Hooks::MongoMonitorSubscriber do
|
|
11
11
|
describe "#started" do
|
12
12
|
let(:event) do
|
13
13
|
double(
|
14
|
-
:request_id
|
15
|
-
:
|
14
|
+
:request_id => 1,
|
15
|
+
:command_name => 'find',
|
16
|
+
:command => {'foo' => 'bar'}
|
16
17
|
)
|
17
18
|
end
|
18
19
|
|
19
20
|
it "should sanitize command" do
|
20
|
-
Appsignal::
|
21
|
+
Appsignal::EventFormatter::MongoRubyDriver::QueryFormatter
|
22
|
+
.should receive(:format).with('find', {'foo' => 'bar'})
|
21
23
|
|
22
24
|
subscriber.started(event)
|
23
25
|
end
|
@@ -81,8 +83,9 @@ describe Appsignal::Hooks::MongoMonitorSubscriber do
|
|
81
83
|
Appsignal::Extension.should receive(:finish_event).with(
|
82
84
|
transaction.transaction_index,
|
83
85
|
'query.mongodb',
|
84
|
-
'find',
|
85
|
-
"
|
86
|
+
'find | test | SUCCEEDED',
|
87
|
+
"{\"foo\":\"?\"}",
|
88
|
+
0
|
86
89
|
)
|
87
90
|
|
88
91
|
subscriber.finish('SUCCEEDED', event)
|
@@ -98,10 +98,10 @@ describe Appsignal::Subscriber do
|
|
98
98
|
|
99
99
|
it "should call native start and finish event for every event" do
|
100
100
|
Appsignal::Extension.should_receive(:start_event).exactly(4).times
|
101
|
-
Appsignal::Extension.should_receive(:finish_event).with(kind_of(Integer), 'one', '', '').once
|
102
|
-
Appsignal::Extension.should_receive(:finish_event).with(kind_of(Integer), 'two', '', '').once
|
103
|
-
Appsignal::Extension.should_receive(:finish_event).with(kind_of(Integer), 'two.three', '', '').once
|
104
|
-
Appsignal::Extension.should_receive(:finish_event).with(kind_of(Integer), 'one.three', '', '').once
|
101
|
+
Appsignal::Extension.should_receive(:finish_event).with(kind_of(Integer), 'one', '', '', 0).once
|
102
|
+
Appsignal::Extension.should_receive(:finish_event).with(kind_of(Integer), 'two', '', '', 0).once
|
103
|
+
Appsignal::Extension.should_receive(:finish_event).with(kind_of(Integer), 'two.three', '', '', 0).once
|
104
|
+
Appsignal::Extension.should_receive(:finish_event).with(kind_of(Integer), 'one.three', '', '', 0).once
|
105
105
|
|
106
106
|
ActiveSupport::Notifications.instrument('one') do
|
107
107
|
ActiveSupport::Notifications.instrument('two') do
|
@@ -119,7 +119,8 @@ describe Appsignal::Subscriber do
|
|
119
119
|
kind_of(Integer),
|
120
120
|
'request.net_http',
|
121
121
|
'GET http://www.google.com',
|
122
|
-
''
|
122
|
+
'',
|
123
|
+
0
|
123
124
|
).once
|
124
125
|
|
125
126
|
ActiveSupport::Notifications.instrument(
|
@@ -130,6 +131,23 @@ describe Appsignal::Subscriber do
|
|
130
131
|
)
|
131
132
|
end
|
132
133
|
|
134
|
+
it "should call finish with title, body and body format if there is a formatter that returns it" do
|
135
|
+
Appsignal::Extension.should_receive(:start_event).once
|
136
|
+
Appsignal::Extension.should_receive(:finish_event).with(
|
137
|
+
kind_of(Integer),
|
138
|
+
'sql.active_record',
|
139
|
+
'Something load',
|
140
|
+
'SELECT * FROM something',
|
141
|
+
1
|
142
|
+
).once
|
143
|
+
|
144
|
+
ActiveSupport::Notifications.instrument(
|
145
|
+
'sql.active_record',
|
146
|
+
:name => 'Something load',
|
147
|
+
:sql => 'SELECT * FROM something'
|
148
|
+
)
|
149
|
+
end
|
150
|
+
|
133
151
|
context "when paused" do
|
134
152
|
before { transaction.pause! }
|
135
153
|
|
@@ -331,6 +331,11 @@ describe Appsignal::Transaction do
|
|
331
331
|
'params',
|
332
332
|
'{"controller":"blog_posts","action":"show","id":"1"}'
|
333
333
|
).once
|
334
|
+
Appsignal::Extension.should_receive(:set_transaction_sample_data).with(
|
335
|
+
kind_of(Integer),
|
336
|
+
'metadata',
|
337
|
+
'{"key":"value"}'
|
338
|
+
).once
|
334
339
|
Appsignal::Extension.should_receive(:set_transaction_sample_data).with(
|
335
340
|
kind_of(Integer),
|
336
341
|
'tags',
|
@@ -616,6 +621,22 @@ describe Appsignal::Transaction do
|
|
616
621
|
end
|
617
622
|
end
|
618
623
|
|
624
|
+
describe "#metadata" do
|
625
|
+
subject { transaction.send(:metadata) }
|
626
|
+
|
627
|
+
context "when env is nil" do
|
628
|
+
before { transaction.request.stub(:env => nil) }
|
629
|
+
|
630
|
+
it { should be_nil }
|
631
|
+
end
|
632
|
+
|
633
|
+
context "when env is present" do
|
634
|
+
let(:env) { {:metadata => {:key => 'value'}} }
|
635
|
+
|
636
|
+
it { should == env[:metadata] }
|
637
|
+
end
|
638
|
+
end
|
639
|
+
|
619
640
|
describe '#sanitized_tags' do
|
620
641
|
before do
|
621
642
|
transaction.set_tags(
|
@@ -33,4 +33,20 @@ describe Appsignal::Utils do
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
36
|
+
|
37
|
+
describe ".sanitize_key" do
|
38
|
+
it "should not sanitize key when no key_sanitizer is given" do
|
39
|
+
expect( Appsignal::Utils.sanitize_key('foo', nil) ).to eql('foo')
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with mongodb sanitizer" do
|
43
|
+
it "should not sanitize key when no dots are in the key" do
|
44
|
+
expect( Appsignal::Utils.sanitize_key('foo', :mongodb) ).to eql('foo')
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should sanitize key when dots are in the key" do
|
48
|
+
expect( Appsignal::Utils.sanitize_key('foo.bar', :mongodb) ).to eql('foo.?')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
36
52
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appsignal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.5.beta.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Beekman
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-03-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -154,8 +154,10 @@ files:
|
|
154
154
|
- lib/appsignal/event_formatter/action_view/render_formatter.rb
|
155
155
|
- lib/appsignal/event_formatter/active_record/instantiation_formatter.rb
|
156
156
|
- lib/appsignal/event_formatter/active_record/sql_formatter.rb
|
157
|
+
- lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb
|
157
158
|
- lib/appsignal/event_formatter/moped/query_formatter.rb
|
158
159
|
- lib/appsignal/event_formatter/net_http/request_formatter.rb
|
160
|
+
- lib/appsignal/event_formatter/sequel/sql_formatter.rb
|
159
161
|
- lib/appsignal/extension.rb
|
160
162
|
- lib/appsignal/hooks.rb
|
161
163
|
- lib/appsignal/hooks/celluloid.rb
|
@@ -209,8 +211,10 @@ files:
|
|
209
211
|
- spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb
|
210
212
|
- spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb
|
211
213
|
- spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb
|
214
|
+
- spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb
|
212
215
|
- spec/lib/appsignal/event_formatter/moped/query_formatter_spec.rb
|
213
216
|
- spec/lib/appsignal/event_formatter/net_http/request_formatter_spec.rb
|
217
|
+
- spec/lib/appsignal/event_formatter/sequel/sql_formatter_spec.rb
|
214
218
|
- spec/lib/appsignal/event_formatter_spec.rb
|
215
219
|
- spec/lib/appsignal/extension_spec.rb
|
216
220
|
- spec/lib/appsignal/hooks/celluloid_spec.rb
|
@@ -274,9 +278,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
274
278
|
version: '1.9'
|
275
279
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
276
280
|
requirements:
|
277
|
-
- - "
|
281
|
+
- - ">"
|
278
282
|
- !ruby/object:Gem::Version
|
279
|
-
version:
|
283
|
+
version: 1.3.1
|
280
284
|
requirements: []
|
281
285
|
rubyforge_project:
|
282
286
|
rubygems_version: 2.2.5
|
@@ -292,8 +296,10 @@ test_files:
|
|
292
296
|
- spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb
|
293
297
|
- spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb
|
294
298
|
- spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb
|
299
|
+
- spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb
|
295
300
|
- spec/lib/appsignal/event_formatter/moped/query_formatter_spec.rb
|
296
301
|
- spec/lib/appsignal/event_formatter/net_http/request_formatter_spec.rb
|
302
|
+
- spec/lib/appsignal/event_formatter/sequel/sql_formatter_spec.rb
|
297
303
|
- spec/lib/appsignal/event_formatter_spec.rb
|
298
304
|
- spec/lib/appsignal/extension_spec.rb
|
299
305
|
- spec/lib/appsignal/hooks/celluloid_spec.rb
|