scout_apm 1.0.0 → 1.1.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/scout_apm.rb +3 -0
- data/lib/scout_apm/agent/reporting.rb +7 -1
- data/lib/scout_apm/attribute_arranger.rb +17 -0
- data/lib/scout_apm/bucket_name_splitter.rb +27 -0
- data/lib/scout_apm/context.rb +1 -1
- data/lib/scout_apm/metric_meta.rb +8 -0
- data/lib/scout_apm/metric_stats.rb +6 -0
- data/lib/scout_apm/serializers/payload_serializer.rb +5 -1
- data/lib/scout_apm/serializers/payload_serializer_to_json.rb +67 -0
- data/lib/scout_apm/slow_transaction.rb +11 -0
- data/lib/scout_apm/store.rb +1 -1
- data/lib/scout_apm/tracer.rb +0 -2
- data/lib/scout_apm/version.rb +1 -1
- data/test/unit/serializers/payload_serializer_test.rb +212 -0
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6241efa65950ed1d898ba3d688c0d0e442ed4871
|
4
|
+
data.tar.gz: 166976b4a15c5e4481bb171abba5dcf2f155e70f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d0f7893d4df03ff5216bac6334ffa04e7e0bfa0e50e9eb14be6cb8a3d8e58b40afe140ed0691b3e324b311349119917f686f152e885dfbebbe20376c0d66c571
|
7
|
+
data.tar.gz: 4f6c3c86c84349989dfb406711a35791bd7d9f550b9139d67432fd7e37f512a9d879cfd7f08bbca6f8c30d9eb730fe8c469e7b7790138d87f02d0a25ce697993
|
data/lib/scout_apm.rb
CHANGED
@@ -74,6 +74,7 @@ require 'scout_apm/layaway'
|
|
74
74
|
require 'scout_apm/layaway_file'
|
75
75
|
require 'scout_apm/reporter'
|
76
76
|
require 'scout_apm/background_worker'
|
77
|
+
require 'scout_apm/bucket_name_splitter'
|
77
78
|
require 'scout_apm/metric_meta'
|
78
79
|
require 'scout_apm/metric_stats'
|
79
80
|
require 'scout_apm/stack_item'
|
@@ -83,8 +84,10 @@ require 'scout_apm/context'
|
|
83
84
|
require 'scout_apm/stackprof_tree_collapser'
|
84
85
|
require 'scout_apm/slow_transaction'
|
85
86
|
require 'scout_apm/capacity'
|
87
|
+
require 'scout_apm/attribute_arranger'
|
86
88
|
|
87
89
|
require 'scout_apm/serializers/payload_serializer'
|
90
|
+
require 'scout_apm/serializers/payload_serializer_to_json'
|
88
91
|
require 'scout_apm/serializers/directive_serializer'
|
89
92
|
require 'scout_apm/serializers/app_server_load_serializer'
|
90
93
|
require 'scout_apm/serializers/deploy_serializer'
|
@@ -49,7 +49,13 @@ module ScoutApm
|
|
49
49
|
|
50
50
|
logger.debug "Total payload [#{payload.size/1024} KB] for #{total_request_count} requests and Slow Transactions [#{slow_transactions_kb} KB] for #{slow_transactions.size} transactions of durations: #{slow_transactions.map(&:total_call_time).join(',')}."
|
51
51
|
|
52
|
-
|
52
|
+
if ScoutApm::Agent.instance.config.value("report_format") == 'json'
|
53
|
+
headers = {'Content-Type' => 'application/json'}
|
54
|
+
else
|
55
|
+
headers = {}
|
56
|
+
end
|
57
|
+
|
58
|
+
response = reporter.report(payload, headers)
|
53
59
|
|
54
60
|
if response and response.is_a?(Net::HTTPSuccess)
|
55
61
|
directives = ScoutApm::Serializers::DirectiveSerializer.deserialize(response.body)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ScoutApm
|
2
|
+
module AttributeArranger
|
3
|
+
# pass in an array of symbols to return as hash keys
|
4
|
+
# if the symbol doesn't match the name of the method, pass an array: [:key, :method_name]
|
5
|
+
def self.call(subject, attributes_list)
|
6
|
+
attributes_list.inject({}) do |attribute_hash, attribute|
|
7
|
+
case attribute
|
8
|
+
when Array
|
9
|
+
attribute_hash[attribute[0]] = subject.send(attribute[1])
|
10
|
+
when Symbol
|
11
|
+
attribute_hash[attribute] = subject.send(attribute)
|
12
|
+
end
|
13
|
+
attribute_hash
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module ScoutApm
|
2
|
+
module BucketNameSplitter
|
3
|
+
def bucket
|
4
|
+
split_metric_name(metric_name).first
|
5
|
+
end
|
6
|
+
|
7
|
+
def name
|
8
|
+
split_metric_name(metric_name).last
|
9
|
+
end
|
10
|
+
|
11
|
+
def key
|
12
|
+
{:bucket => bucket, :name => name}
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def split_metric_name(name)
|
17
|
+
name.to_s.split(/\//, 2)
|
18
|
+
end
|
19
|
+
|
20
|
+
def scope_hash
|
21
|
+
if scope
|
22
|
+
scope_bucket, scope_name = split_metric_name(scope)
|
23
|
+
{:bucket => scope_bucket, :name => scope_name}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/scout_apm/context.rb
CHANGED
@@ -81,7 +81,7 @@ module ScoutApm
|
|
81
81
|
value = key_value.values.last
|
82
82
|
if !valid_type?([String, Symbol, Numeric, Time, Date, TrueClass, FalseClass],value)
|
83
83
|
ScoutApm::Agent.instance.logger.warn "The value for [#{key_value.keys.first}] is not a valid type [#{value.class}]."
|
84
|
-
|
84
|
+
false
|
85
85
|
else
|
86
86
|
true
|
87
87
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# Contains the meta information associated with a metric. Used to lookup Metrics in to Store's metric_hash.
|
2
2
|
class ScoutApm::MetricMeta
|
3
|
+
include ScoutApm::BucketNameSplitter
|
4
|
+
|
3
5
|
def initialize(metric_name, options = {})
|
4
6
|
@metric_name = metric_name
|
5
7
|
@metric_id = nil
|
@@ -31,4 +33,10 @@ class ScoutApm::MetricMeta
|
|
31
33
|
def eql?(o)
|
32
34
|
self.class == o.class && metric_name.downcase.eql?(o.metric_name.downcase) && scope == o.scope && client_id == o.client_id && desc == o.desc
|
33
35
|
end
|
36
|
+
|
37
|
+
def as_json
|
38
|
+
json_attributes = [:bucket, :name, :desc, :extra, [:scope, :scope_hash]]
|
39
|
+
# query, stack_trace
|
40
|
+
ScoutApm::AttributeArranger.call(self, json_attributes)
|
41
|
+
end
|
34
42
|
end # class MetricMeta
|
@@ -46,4 +46,10 @@ class ScoutApm::MetricStats
|
|
46
46
|
def to_json(*a)
|
47
47
|
%Q[{"total_exclusive_time":#{total_exclusive_time*1000},"min_call_time":#{min_call_time*1000},"call_count":#{call_count},"sum_of_squares":#{sum_of_squares*1000},"total_call_time":#{total_call_time*1000},"max_call_time":#{max_call_time*1000}}]
|
48
48
|
end
|
49
|
+
|
50
|
+
def as_json
|
51
|
+
json_attributes = [:call_count, :total_call_time, :total_exclusive_time, :min_call_time, :max_call_time]
|
52
|
+
# uri, context
|
53
|
+
ScoutApm::AttributeArranger.call(self, json_attributes)
|
54
|
+
end
|
49
55
|
end # class MetricStats
|
@@ -3,7 +3,11 @@ module ScoutApm
|
|
3
3
|
module Serializers
|
4
4
|
class PayloadSerializer
|
5
5
|
def self.serialize(metadata, metrics, slow_transactions)
|
6
|
-
|
6
|
+
if ScoutApm::Agent.instance.config.value("report_format") == 'json'
|
7
|
+
ScoutApm::Serializers::PayloadSerializerToJson.serialize(metadata, metrics, slow_transactions)
|
8
|
+
else
|
9
|
+
Marshal.dump(:metadata => metadata, :metrics => metrics, :slow_transactions => slow_transactions)
|
10
|
+
end
|
7
11
|
end
|
8
12
|
|
9
13
|
def self.deserialize(data)
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module ScoutApm
|
2
|
+
module Serializers
|
3
|
+
module PayloadSerializerToJson
|
4
|
+
class << self
|
5
|
+
def serialize(metadata, metrics, slow_transactions)
|
6
|
+
rearranged_metrics = rearrange_the_metrics(metrics)
|
7
|
+
rearranged_slow_transactions = rearrange_the_slow_transactions(slow_transactions)
|
8
|
+
jsonify_hash({:metadata => metadata, :metrics => rearranged_metrics, :slow_transactions => rearranged_slow_transactions})
|
9
|
+
end
|
10
|
+
|
11
|
+
def rearrange_the_metrics(metrics)
|
12
|
+
metrics.to_a.map do |meta, stats|
|
13
|
+
stats.as_json.merge(key: meta.as_json)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def rearrange_the_slow_transactions(slow_transactions)
|
18
|
+
slow_transactions.to_a.map do |slow_t|
|
19
|
+
slow_t.as_json.merge(metrics: rearrange_the_metrics(slow_t.metrics))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def jsonify_hash(hash)
|
24
|
+
str_parts = []
|
25
|
+
hash.each do |key, value|
|
26
|
+
formatted_key = format_by_type(key)
|
27
|
+
formatted_value = format_by_type(value)
|
28
|
+
str_parts << "#{formatted_key}:#{formatted_value}"
|
29
|
+
end
|
30
|
+
"{#{str_parts.join(",")}}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def escape(string)
|
34
|
+
string = string.to_s
|
35
|
+
escapers = {
|
36
|
+
'\b' => '\\b',
|
37
|
+
'\t' => '\\t',
|
38
|
+
'\n' => '\\n',
|
39
|
+
'\f' => '\\f',
|
40
|
+
'\r' => '\\r',
|
41
|
+
'"' => '\\"',
|
42
|
+
'\\' => '\\\\'
|
43
|
+
}
|
44
|
+
# TODO escape control chars
|
45
|
+
escapers.each {|bad, good| string = string.gsub(bad, good)}
|
46
|
+
string
|
47
|
+
end
|
48
|
+
|
49
|
+
def format_by_type(formatee)
|
50
|
+
case formatee
|
51
|
+
when Hash
|
52
|
+
jsonify_hash(formatee)
|
53
|
+
when Array
|
54
|
+
all_the_elements = formatee.map {|value_guy| format_by_type(value_guy)}
|
55
|
+
"[#{all_the_elements.join(",")}]"
|
56
|
+
when Numeric
|
57
|
+
formatee
|
58
|
+
when nil
|
59
|
+
"null"
|
60
|
+
else # strings and everything
|
61
|
+
%Q["#{escape(formatee)}"]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module ScoutApm
|
2
2
|
class SlowTransaction
|
3
|
+
include ScoutApm::BucketNameSplitter
|
4
|
+
|
3
5
|
BACKTRACE_THRESHOLD = 0.5 # the minimum threshold to record the backtrace for a metric.
|
4
6
|
BACKTRACE_LIMIT = 5 # Max length of callers to display
|
5
7
|
MAX_SIZE = 100 # Limits the size of the metric hash to prevent a metric explosion.
|
@@ -45,5 +47,14 @@ module ScoutApm
|
|
45
47
|
@metrics = nil
|
46
48
|
self
|
47
49
|
end
|
50
|
+
|
51
|
+
def as_json
|
52
|
+
json_attributes = [:key, :time, :total_call_time, :uri, [:context, :context_hash], :prof]
|
53
|
+
ScoutApm::AttributeArranger.call(self, json_attributes)
|
54
|
+
end
|
55
|
+
|
56
|
+
def context_hash
|
57
|
+
context.to_hash
|
58
|
+
end
|
48
59
|
end
|
49
60
|
end
|
data/lib/scout_apm/store.rb
CHANGED
@@ -150,7 +150,7 @@ module ScoutApm
|
|
150
150
|
parent_stat.total_call_time,
|
151
151
|
transaction_hash.dup,
|
152
152
|
ScoutApm::Context.current,
|
153
|
-
|
153
|
+
Time.now,
|
154
154
|
Thread::current[:scout_apm_prof])
|
155
155
|
@slow_transactions.push(slow_transaction)
|
156
156
|
ScoutApm::Agent.instance.logger.debug "Slow transaction sample added. [URI: #{uri}] [Context: #{ScoutApm::Context.current.to_hash}] Array Size: #{@slow_transactions.size}"
|
data/lib/scout_apm/tracer.rb
CHANGED
@@ -22,7 +22,6 @@ module ScoutApm
|
|
22
22
|
# TODO - wrap a lot of this into a Trace class, store that as a Thread var.
|
23
23
|
ScoutApm::Agent.instance.store.reset_transaction!
|
24
24
|
ScoutApm::Context.current.add_user(:ip => options[:ip]) if options[:ip]
|
25
|
-
Thread::current[:scout_apm_trace_time] = Time.now.utc
|
26
25
|
ScoutApm::Agent.instance.capacity.start_transaction!
|
27
26
|
e = nil
|
28
27
|
instrument(metric_name, options) do
|
@@ -34,7 +33,6 @@ module ScoutApm
|
|
34
33
|
end
|
35
34
|
Thread::current[:scout_apm_scope_name] = nil
|
36
35
|
end
|
37
|
-
Thread::current[:scout_apm_trace_time] = nil
|
38
36
|
ScoutApm::Agent.instance.capacity.finish_transaction!
|
39
37
|
# The context is cleared after instrumentation (rather than before) as tracing controller-actions doesn't occur until the controller-action is called.
|
40
38
|
# It does not trace before filters, which is a likely spot to add context. This means that any context applied during before_filters would be cleared.
|
data/lib/scout_apm/version.rb
CHANGED
@@ -0,0 +1,212 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'scout_apm/attribute_arranger'
|
3
|
+
require 'scout_apm/bucket_name_splitter'
|
4
|
+
require 'scout_apm/serializers/payload_serializer'
|
5
|
+
require 'scout_apm/serializers/payload_serializer_to_json'
|
6
|
+
require 'scout_apm/slow_transaction'
|
7
|
+
require 'scout_apm/metric_meta'
|
8
|
+
require 'scout_apm/metric_stats'
|
9
|
+
require 'scout_apm/stackprof_tree_collapser'
|
10
|
+
require 'scout_apm/utils/fake_stack_prof'
|
11
|
+
require 'scout_apm/context'
|
12
|
+
require 'ostruct'
|
13
|
+
require 'json' # to deserialize what has been manually serialized by the production code
|
14
|
+
|
15
|
+
# stub the report_format value
|
16
|
+
class ScoutApm::Agent
|
17
|
+
module Config
|
18
|
+
def self.value(key)
|
19
|
+
'json'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.instance
|
24
|
+
OpenStruct.new(:config => Config)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class PayloadSerializerTest < Minitest::Test
|
29
|
+
|
30
|
+
def test_serializes_metadata_as_json
|
31
|
+
metadata = {
|
32
|
+
:app_root => "/srv/app/rootz",
|
33
|
+
:unique_id => "unique_idz",
|
34
|
+
:agent_version => 123
|
35
|
+
}
|
36
|
+
payload = ScoutApm::Serializers::PayloadSerializer.serialize(metadata, {}, {})
|
37
|
+
|
38
|
+
# symbol keys turn to strings
|
39
|
+
formatted_metadata = {
|
40
|
+
"app_root" => "/srv/app/rootz",
|
41
|
+
"unique_id" => "unique_idz",
|
42
|
+
"agent_version" => 123
|
43
|
+
}
|
44
|
+
assert_equal formatted_metadata, JSON.parse(payload)["metadata"]
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_serializes_metrics_as_json
|
48
|
+
metrics = {
|
49
|
+
ScoutApm::MetricMeta.new('ActiveRecord/all').tap { |meta|
|
50
|
+
meta.desc = "SELECT * from users where filter=?"
|
51
|
+
meta.extra = {user: 'cooluser'}
|
52
|
+
meta.metric_id = nil
|
53
|
+
meta.scope = "Controller/apps/checkin"
|
54
|
+
} => ScoutApm::MetricStats.new.tap { |stats|
|
55
|
+
stats.call_count = 16
|
56
|
+
stats.max_call_time = 0.005338062
|
57
|
+
stats.min_call_time = 0.000613518
|
58
|
+
stats.sum_of_squares = 9.8040860751126e-05
|
59
|
+
stats.total_call_time = 0.033245704
|
60
|
+
stats.total_exclusive_time = 0.033245704
|
61
|
+
},
|
62
|
+
ScoutApm::MetricMeta.new("Controller/apps/checkin").tap { |meta|
|
63
|
+
meta.desc = nil
|
64
|
+
meta.extra = {}
|
65
|
+
meta.metric_id = nil
|
66
|
+
meta.scope = nil
|
67
|
+
} => ScoutApm::MetricStats.new.tap { |stats|
|
68
|
+
stats.call_count = 2
|
69
|
+
stats.max_call_time = 0.078521419
|
70
|
+
stats.min_call_time = 0.034881757
|
71
|
+
stats.sum_of_squares = 0.007382350213180609
|
72
|
+
stats.total_call_time = 0.113403176
|
73
|
+
stats.total_exclusive_time = 0.07813208899999999
|
74
|
+
}
|
75
|
+
}
|
76
|
+
payload = ScoutApm::Serializers::PayloadSerializer.serialize({}, metrics, {})
|
77
|
+
formatted_metrics = [
|
78
|
+
{
|
79
|
+
"key" => {
|
80
|
+
"bucket" => "ActiveRecord",
|
81
|
+
"name" => "all",
|
82
|
+
"desc" => "SELECT * from users where filter=?",
|
83
|
+
"extra" => {
|
84
|
+
"user" => "cooluser",
|
85
|
+
},
|
86
|
+
"scope" => {
|
87
|
+
"bucket" => "Controller",
|
88
|
+
"name" => "apps/checkin",
|
89
|
+
},
|
90
|
+
},
|
91
|
+
"call_count" => 16,
|
92
|
+
"max_call_time" => 0.005338062,
|
93
|
+
"min_call_time" => 0.000613518,
|
94
|
+
"total_call_time" => 0.033245704,
|
95
|
+
"total_exclusive_time" => 0.033245704,
|
96
|
+
},
|
97
|
+
{
|
98
|
+
"key" => {
|
99
|
+
"bucket" => "Controller",
|
100
|
+
"name" => "apps/checkin",
|
101
|
+
"desc" => nil,
|
102
|
+
"extra" => {},
|
103
|
+
"scope" => nil,
|
104
|
+
},
|
105
|
+
"call_count" => 2,
|
106
|
+
"max_call_time" => 0.078521419,
|
107
|
+
"min_call_time" => 0.034881757,
|
108
|
+
"total_call_time" => 0.113403176,
|
109
|
+
"total_exclusive_time" => 0.07813208899999999,
|
110
|
+
}
|
111
|
+
]
|
112
|
+
assert_equal formatted_metrics, JSON.parse(payload)["metrics"]
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_serializes_slow_transactions_as_json
|
116
|
+
slow_transaction_metrics = {
|
117
|
+
ScoutApm::MetricMeta.new('ActiveRecord/all').tap { |meta|
|
118
|
+
meta.desc = "SELECT * from users where filter=?"
|
119
|
+
meta.extra = {user: 'cooluser'}
|
120
|
+
meta.metric_id = nil
|
121
|
+
meta.scope = "Controller/apps/checkin"
|
122
|
+
} => ScoutApm::MetricStats.new.tap { |stats|
|
123
|
+
stats.call_count = 16
|
124
|
+
stats.max_call_time = 0.005338062
|
125
|
+
stats.min_call_time = 0.000613518
|
126
|
+
stats.sum_of_squares = 9.8040860751126e-05
|
127
|
+
stats.total_call_time = 0.033245704
|
128
|
+
stats.total_exclusive_time = 0.033245704
|
129
|
+
},
|
130
|
+
ScoutApm::MetricMeta.new("Controller/apps/checkin").tap { |meta|
|
131
|
+
meta.desc = nil
|
132
|
+
meta.extra = {}
|
133
|
+
meta.metric_id = nil
|
134
|
+
meta.scope = nil
|
135
|
+
} => ScoutApm::MetricStats.new.tap { |stats|
|
136
|
+
stats.call_count = 2
|
137
|
+
stats.max_call_time = 0.078521419
|
138
|
+
stats.min_call_time = 0.034881757
|
139
|
+
stats.sum_of_squares = 0.007382350213180609
|
140
|
+
stats.total_call_time = 0.113403176
|
141
|
+
stats.total_exclusive_time = 0.07813208899999999
|
142
|
+
}
|
143
|
+
}
|
144
|
+
context = ScoutApm::Context.new
|
145
|
+
context.add({"this" => "that"})
|
146
|
+
context.add_user({"hello" => "goodbye"})
|
147
|
+
slow_t = ScoutApm::SlowTransaction.new("http://example.com/blabla", "Buckethead/something/else", 1.23, slow_transaction_metrics, context, Time.at(1448198788), StackProf.new)
|
148
|
+
payload = ScoutApm::Serializers::PayloadSerializer.serialize({}, {}, [slow_t])
|
149
|
+
formatted_slow_transactions = [
|
150
|
+
{
|
151
|
+
"key" => {
|
152
|
+
"bucket" => "Buckethead",
|
153
|
+
"name" => "something/else"
|
154
|
+
},
|
155
|
+
"time" => "2015-11-22 06:26:28 -0700",
|
156
|
+
"total_call_time" => 1.23,
|
157
|
+
"uri" => "http://example.com/blabla",
|
158
|
+
"context" => {"this"=>"that", "user"=>{"hello"=>"goodbye"}},
|
159
|
+
"prof" => [],
|
160
|
+
"metrics" => [
|
161
|
+
{
|
162
|
+
"key" => {
|
163
|
+
"bucket" => "ActiveRecord",
|
164
|
+
"name" => "all",
|
165
|
+
"desc" => "SELECT * from users where filter=?",
|
166
|
+
"extra" => {
|
167
|
+
"user" => "cooluser",
|
168
|
+
},
|
169
|
+
"scope" => {
|
170
|
+
"bucket" => "Controller",
|
171
|
+
"name" => "apps/checkin",
|
172
|
+
},
|
173
|
+
},
|
174
|
+
"call_count" => 16,
|
175
|
+
"max_call_time" => 0.005338062,
|
176
|
+
"min_call_time" => 0.000613518,
|
177
|
+
"total_call_time" => 0.033245704,
|
178
|
+
"total_exclusive_time" => 0.033245704,
|
179
|
+
},
|
180
|
+
{
|
181
|
+
"key" => {
|
182
|
+
"bucket" => "Controller",
|
183
|
+
"name" => "apps/checkin",
|
184
|
+
"desc" => nil,
|
185
|
+
"extra" => {},
|
186
|
+
"scope" => nil,
|
187
|
+
},
|
188
|
+
"call_count" => 2,
|
189
|
+
"max_call_time" => 0.078521419,
|
190
|
+
"min_call_time" => 0.034881757,
|
191
|
+
"total_call_time" => 0.113403176,
|
192
|
+
"total_exclusive_time" => 0.07813208899999999,
|
193
|
+
}
|
194
|
+
]
|
195
|
+
}
|
196
|
+
]
|
197
|
+
assert_equal formatted_slow_transactions, JSON.parse(payload)["slow_transactions"]
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_escapes_json_quotes
|
201
|
+
metadata = {
|
202
|
+
:quotie => "here are some \"quotes\"",
|
203
|
+
}
|
204
|
+
payload = ScoutApm::Serializers::PayloadSerializer.serialize(metadata, {}, {})
|
205
|
+
|
206
|
+
# symbol keys turn to strings
|
207
|
+
formatted_metadata = {
|
208
|
+
"quotie" => "here are some \"quotes\""
|
209
|
+
}
|
210
|
+
assert_equal formatted_metadata, JSON.parse(payload)["metadata"]
|
211
|
+
end
|
212
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scout_apm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.1.0.pre1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Derek Haynes
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-12-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: minitest
|
@@ -71,7 +71,9 @@ files:
|
|
71
71
|
- lib/scout_apm/agent/logging.rb
|
72
72
|
- lib/scout_apm/agent/reporting.rb
|
73
73
|
- lib/scout_apm/app_server_load.rb
|
74
|
+
- lib/scout_apm/attribute_arranger.rb
|
74
75
|
- lib/scout_apm/background_worker.rb
|
76
|
+
- lib/scout_apm/bucket_name_splitter.rb
|
75
77
|
- lib/scout_apm/capacity.rb
|
76
78
|
- lib/scout_apm/config.rb
|
77
79
|
- lib/scout_apm/context.rb
|
@@ -106,6 +108,7 @@ files:
|
|
106
108
|
- lib/scout_apm/serializers/deploy_serializer.rb
|
107
109
|
- lib/scout_apm/serializers/directive_serializer.rb
|
108
110
|
- lib/scout_apm/serializers/payload_serializer.rb
|
111
|
+
- lib/scout_apm/serializers/payload_serializer_to_json.rb
|
109
112
|
- lib/scout_apm/server_integrations/null.rb
|
110
113
|
- lib/scout_apm/server_integrations/passenger.rb
|
111
114
|
- lib/scout_apm/server_integrations/puma.rb
|
@@ -133,6 +136,7 @@ files:
|
|
133
136
|
- test/unit/config_test.rb
|
134
137
|
- test/unit/environment_test.rb
|
135
138
|
- test/unit/instruments/active_record_instruments_test.rb
|
139
|
+
- test/unit/serializers/payload_serializer_test.rb
|
136
140
|
- test/unit/sql_sanitizer_test.rb
|
137
141
|
homepage: https://github.com/scoutapp/scout_apm_ruby
|
138
142
|
licenses: []
|
@@ -149,9 +153,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
149
153
|
version: '0'
|
150
154
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
155
|
requirements:
|
152
|
-
- - "
|
156
|
+
- - ">"
|
153
157
|
- !ruby/object:Gem::Version
|
154
|
-
version:
|
158
|
+
version: 1.3.1
|
155
159
|
requirements: []
|
156
160
|
rubyforge_project: scout_apm
|
157
161
|
rubygems_version: 2.2.2
|
@@ -164,4 +168,5 @@ test_files:
|
|
164
168
|
- test/unit/config_test.rb
|
165
169
|
- test/unit/environment_test.rb
|
166
170
|
- test/unit/instruments/active_record_instruments_test.rb
|
171
|
+
- test/unit/serializers/payload_serializer_test.rb
|
167
172
|
- test/unit/sql_sanitizer_test.rb
|