appsignal 1.0.4 → 1.0.5.beta.1
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 +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
|