appsignal 3.0.12-java → 3.0.16-java
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/.semaphore/semaphore.yml +3 -7
- data/CHANGELOG.md +61 -0
- data/build_matrix.yml +3 -7
- data/ext/agent.yml +29 -25
- data/ext/appsignal_extension.c +201 -0
- data/lib/appsignal/cli/diagnose.rb +69 -34
- data/lib/appsignal/config.rb +64 -55
- data/lib/appsignal/extension/jruby.rb +147 -0
- data/lib/appsignal/extension.rb +5 -0
- data/lib/appsignal/hooks/mri.rb +16 -0
- data/lib/appsignal/hooks.rb +1 -0
- data/lib/appsignal/probes/mri.rb +26 -0
- data/lib/appsignal/probes.rb +1 -0
- data/lib/appsignal/span.rb +92 -0
- data/lib/appsignal/transaction.rb +12 -1
- data/lib/appsignal/version.rb +1 -1
- data/script/{install_lintje → lint_git} +4 -0
- data/spec/lib/appsignal/cli/diagnose_spec.rb +27 -23
- data/spec/lib/appsignal/config_spec.rb +26 -19
- data/spec/lib/appsignal/hooks/mri_spec.rb +23 -0
- data/spec/lib/appsignal/probes/mri_spec.rb +33 -0
- data/spec/lib/appsignal/span_spec.rb +141 -0
- data/spec/lib/appsignal/transaction_spec.rb +25 -0
- data/spec/support/helpers/dependency_helper.rb +4 -0
- metadata +13 -4
@@ -0,0 +1,92 @@
|
|
1
|
+
module Appsignal
|
2
|
+
class Span
|
3
|
+
def initialize(namespace = nil, ext = nil)
|
4
|
+
@ext = if ext
|
5
|
+
ext
|
6
|
+
else
|
7
|
+
Appsignal::Extension::Span.root(namespace || "")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def child
|
12
|
+
Span.new(nil, @ext.child)
|
13
|
+
end
|
14
|
+
|
15
|
+
def name=(value)
|
16
|
+
@ext.set_name(value)
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_error(error)
|
20
|
+
unless error.is_a?(Exception)
|
21
|
+
Appsignal.logger.error "Appsignal::Span#add_error: Cannot add error. " \
|
22
|
+
"The given value is not an exception: #{error.inspect}"
|
23
|
+
return
|
24
|
+
end
|
25
|
+
return unless error
|
26
|
+
|
27
|
+
backtrace = cleaned_backtrace(error.backtrace)
|
28
|
+
@ext.add_error(
|
29
|
+
error.class.name,
|
30
|
+
error.message.to_s,
|
31
|
+
backtrace ? Appsignal::Utils::Data.generate(backtrace) : Appsignal::Extension.data_array_new
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
def set_sample_data(key, data)
|
36
|
+
return unless key && data && (data.is_a?(Array) || data.is_a?(Hash))
|
37
|
+
@ext.set_sample_data(
|
38
|
+
key.to_s,
|
39
|
+
Appsignal::Utils::Data.generate(data)
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def []=(key, value)
|
44
|
+
case value
|
45
|
+
when String
|
46
|
+
@ext.set_attribute_string(key.to_s, value)
|
47
|
+
when Integer
|
48
|
+
begin
|
49
|
+
@ext.set_attribute_int(key.to_s, value)
|
50
|
+
rescue RangeError
|
51
|
+
@ext.set_attribute_string(key.to_s, "bigint:#{value}")
|
52
|
+
end
|
53
|
+
when TrueClass, FalseClass
|
54
|
+
@ext.set_attribute_bool(key.to_s, value)
|
55
|
+
when Float
|
56
|
+
@ext.set_attribute_double(key.to_s, value)
|
57
|
+
else
|
58
|
+
raise TypeError, "value needs to be a string, int, bool or float"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_h
|
63
|
+
json = @ext.to_json
|
64
|
+
return unless json
|
65
|
+
JSON.parse(json)
|
66
|
+
end
|
67
|
+
|
68
|
+
def instrument
|
69
|
+
yield self
|
70
|
+
ensure
|
71
|
+
close
|
72
|
+
end
|
73
|
+
|
74
|
+
def close
|
75
|
+
@ext.close
|
76
|
+
end
|
77
|
+
|
78
|
+
def closed?
|
79
|
+
to_h.nil?
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def cleaned_backtrace(backtrace)
|
85
|
+
if defined?(::Rails) && backtrace
|
86
|
+
::Rails.backtrace_cleaner.clean(backtrace, nil)
|
87
|
+
else
|
88
|
+
backtrace
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -333,7 +333,7 @@ module Appsignal
|
|
333
333
|
backtrace = cleaned_backtrace(error.backtrace)
|
334
334
|
@ext.set_error(
|
335
335
|
error.class.name,
|
336
|
-
error
|
336
|
+
cleaned_error_message(error),
|
337
337
|
backtrace ? Appsignal::Utils::Data.generate(backtrace) : Appsignal::Extension.data_array_new
|
338
338
|
)
|
339
339
|
end
|
@@ -533,6 +533,17 @@ module Appsignal
|
|
533
533
|
end
|
534
534
|
end
|
535
535
|
|
536
|
+
# Clean error messages that are known to potentially contain user data.
|
537
|
+
# Returns an unchanged message otherwise.
|
538
|
+
def cleaned_error_message(error)
|
539
|
+
case error.class.to_s
|
540
|
+
when "PG::UniqueViolation"
|
541
|
+
error.message.to_s.gsub(/\)=\(.*\)/, ")=(?)")
|
542
|
+
else
|
543
|
+
error.message.to_s
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
536
547
|
# Stub that is returned by {Transaction.current} if there is no current
|
537
548
|
# transaction, so that it's still safe to call methods on it if there is no
|
538
549
|
# current transaction.
|
data/lib/appsignal/version.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
set -eu
|
4
4
|
|
5
|
+
LINTJE_VERSION="0.6.1"
|
6
|
+
|
5
7
|
mkdir -p $HOME/bin
|
6
8
|
cache_key=v1-lintje-$LINTJE_VERSION
|
7
9
|
cache restore $cache_key
|
@@ -16,3 +18,5 @@ else
|
|
16
18
|
tar -xz --directory $HOME/bin
|
17
19
|
cache store $cache_key $HOME/bin/lintje
|
18
20
|
fi
|
21
|
+
|
22
|
+
$HOME/bin/lintje $SEMAPHORE_GIT_COMMIT_RANGE
|
@@ -115,7 +115,6 @@ describe Appsignal::CLI::Diagnose, :api_stub => true, :send_report => :yes_cli_i
|
|
115
115
|
it "logs to the log file" do
|
116
116
|
run
|
117
117
|
log_contents = File.read(config.log_file_path)
|
118
|
-
p log_contents
|
119
118
|
expect(log_contents).to contains_log :info, "Starting AppSignal diagnose"
|
120
119
|
end
|
121
120
|
|
@@ -192,8 +191,8 @@ describe Appsignal::CLI::Diagnose, :api_stub => true, :send_report => :yes_cli_i
|
|
192
191
|
|
193
192
|
it "outputs version numbers" do
|
194
193
|
expect(output).to include \
|
195
|
-
"Gem version: #{Appsignal::VERSION}",
|
196
|
-
"Agent version: #{Appsignal::Extension.agent_version}"
|
194
|
+
"Gem version: \"#{Appsignal::VERSION}\"",
|
195
|
+
"Agent version: \"#{Appsignal::Extension.agent_version}\""
|
197
196
|
end
|
198
197
|
|
199
198
|
it "transmits version numbers in report" do
|
@@ -295,18 +294,18 @@ describe Appsignal::CLI::Diagnose, :api_stub => true, :send_report => :yes_cli_i
|
|
295
294
|
"Installation result",
|
296
295
|
" Status: success",
|
297
296
|
"Language details",
|
298
|
-
" Implementation: #{jruby ? "jruby" : "ruby"}",
|
299
|
-
" Ruby version: #{"#{rbconfig["ruby_version"]}-p#{rbconfig["PATCHLEVEL"]}"}",
|
297
|
+
" Implementation: \"#{jruby ? "jruby" : "ruby"}\"",
|
298
|
+
" Ruby version: \"#{"#{rbconfig["ruby_version"]}-p#{rbconfig["PATCHLEVEL"]}"}\"",
|
300
299
|
"Download details",
|
301
|
-
" Download URL: https://",
|
302
|
-
" Checksum: verified",
|
300
|
+
" Download URL: \"https://",
|
301
|
+
" Checksum: \"verified\"",
|
303
302
|
"Build details",
|
304
|
-
" Install time: 20",
|
305
|
-
" Architecture: #{Appsignal::System.agent_architecture}",
|
306
|
-
" Target: #{Appsignal::System.agent_platform}",
|
303
|
+
" Install time: \"20",
|
304
|
+
" Architecture: \"#{Appsignal::System.agent_architecture}\"",
|
305
|
+
" Target: \"#{Appsignal::System.agent_platform}\"",
|
307
306
|
" Musl override: false",
|
308
307
|
" Linux ARM override: false",
|
309
|
-
" Library type: #{jruby ? "dynamic" : "static"}",
|
308
|
+
" Library type: \"#{jruby ? "dynamic" : "static"}\"",
|
310
309
|
" Dependencies: {",
|
311
310
|
" Flags: {",
|
312
311
|
"Host details",
|
@@ -611,9 +610,9 @@ describe Appsignal::CLI::Diagnose, :api_stub => true, :send_report => :yes_cli_i
|
|
611
610
|
run
|
612
611
|
expect(output).to include \
|
613
612
|
"Host information",
|
614
|
-
"Architecture: #{rbconfig["host_cpu"]}",
|
615
|
-
"Operating System: #{rbconfig["host_os"]}",
|
616
|
-
"Ruby version: #{language_version}"
|
613
|
+
"Architecture: \"#{rbconfig["host_cpu"]}\"",
|
614
|
+
"Operating System: \"#{rbconfig["host_os"]}\"",
|
615
|
+
"Ruby version: \"#{language_version}\""
|
617
616
|
end
|
618
617
|
|
619
618
|
context "when on Microsoft Windows" do
|
@@ -751,13 +750,13 @@ describe Appsignal::CLI::Diagnose, :api_stub => true, :send_report => :yes_cli_i
|
|
751
750
|
end
|
752
751
|
|
753
752
|
it "outputs a warning that no config is loaded" do
|
754
|
-
expect(output).to include "
|
753
|
+
expect(output).to include "environment: \"\"\n#{warning_message}"
|
755
754
|
expect(output).to_not have_color_markers
|
756
755
|
end
|
757
756
|
|
758
757
|
context "with color", :color => true do
|
759
758
|
it "outputs a warning that no config is loaded in color" do
|
760
|
-
expect(output).to include "
|
759
|
+
expect(output).to include "environment: \"\"\n"
|
761
760
|
expect(output).to have_colorized_text :red, warning_message
|
762
761
|
end
|
763
762
|
end
|
@@ -786,7 +785,7 @@ describe Appsignal::CLI::Diagnose, :api_stub => true, :send_report => :yes_cli_i
|
|
786
785
|
describe "environment" do
|
787
786
|
it "outputs environment" do
|
788
787
|
run
|
789
|
-
expect(output).to include(%(
|
788
|
+
expect(output).to include(%(environment: "production"))
|
790
789
|
end
|
791
790
|
|
792
791
|
context "when the source is a single source" do
|
@@ -794,7 +793,7 @@ describe Appsignal::CLI::Diagnose, :api_stub => true, :send_report => :yes_cli_i
|
|
794
793
|
|
795
794
|
it "outputs the label source after the value" do
|
796
795
|
expect(output).to include(
|
797
|
-
%(
|
796
|
+
%(environment: "#{Appsignal.config.env}" (Loaded from: initial)\n)
|
798
797
|
)
|
799
798
|
end
|
800
799
|
end
|
@@ -811,7 +810,7 @@ describe Appsignal::CLI::Diagnose, :api_stub => true, :send_report => :yes_cli_i
|
|
811
810
|
|
812
811
|
it "outputs a list of sources with their values" do
|
813
812
|
expect(output).to include(
|
814
|
-
%(
|
813
|
+
%( environment: "production"\n) +
|
815
814
|
%( Sources:\n) +
|
816
815
|
%( initial: "development"\n) +
|
817
816
|
%( env: "production"\n)
|
@@ -905,7 +904,7 @@ describe Appsignal::CLI::Diagnose, :api_stub => true, :send_report => :yes_cli_i
|
|
905
904
|
before { run_within_dir tmp_dir }
|
906
905
|
|
907
906
|
it "outputs environment" do
|
908
|
-
expect(output).to include(%(
|
907
|
+
expect(output).to include(%(environment: "foobar"))
|
909
908
|
end
|
910
909
|
|
911
910
|
it "outputs config defaults" do
|
@@ -1008,7 +1007,7 @@ describe Appsignal::CLI::Diagnose, :api_stub => true, :send_report => :yes_cli_i
|
|
1008
1007
|
|
1009
1008
|
it "outputs failure with status code" do
|
1010
1009
|
expect(output).to include "Validation",
|
1011
|
-
"Validating Push API key: Failed
|
1010
|
+
"Validating Push API key: Failed to validate: status 500\n" +
|
1012
1011
|
%("Could not confirm authorization: 500")
|
1013
1012
|
end
|
1014
1013
|
|
@@ -1016,14 +1015,19 @@ describe Appsignal::CLI::Diagnose, :api_stub => true, :send_report => :yes_cli_i
|
|
1016
1015
|
it "outputs error in color" do
|
1017
1016
|
expect(output).to include "Validation",
|
1018
1017
|
"Validating Push API key: " +
|
1019
|
-
colorize(
|
1018
|
+
colorize(
|
1019
|
+
"Failed to validate: status 500\n" +
|
1020
|
+
%("Could not confirm authorization: 500"),
|
1021
|
+
:red
|
1022
|
+
)
|
1020
1023
|
end
|
1021
1024
|
end
|
1022
1025
|
|
1023
1026
|
it "transmits validation in report" do
|
1024
1027
|
expect(received_report).to include(
|
1025
1028
|
"validation" => {
|
1026
|
-
"push_api_key" =>
|
1029
|
+
"push_api_key" => "Failed to validate: status 500\n" +
|
1030
|
+
%("Could not confirm authorization: 500")
|
1027
1031
|
}
|
1028
1032
|
)
|
1029
1033
|
end
|
@@ -151,33 +151,35 @@ describe Appsignal::Config do
|
|
151
151
|
|
152
152
|
it "merges with the default config" do
|
153
153
|
expect(config.config_hash).to eq(
|
154
|
+
:active => true,
|
155
|
+
:ca_file_path => File.join(resources_dir, "cacert.pem"),
|
154
156
|
:debug => false,
|
155
|
-
:
|
157
|
+
:dns_servers => [],
|
158
|
+
:enable_allocation_tracking => true,
|
159
|
+
:enable_gc_instrumentation => false,
|
160
|
+
:enable_host_metrics => true,
|
161
|
+
:enable_minutely_probes => true,
|
162
|
+
:enable_statsd => true,
|
163
|
+
:endpoint => "https://push.appsignal.com",
|
164
|
+
:files_world_accessible => true,
|
165
|
+
:filter_parameters => [],
|
166
|
+
:filter_session_data => [],
|
156
167
|
:ignore_actions => [],
|
157
168
|
:ignore_errors => [],
|
158
169
|
:ignore_namespaces => [],
|
159
|
-
:filter_parameters => [],
|
160
|
-
:filter_session_data => [],
|
161
170
|
:instrument_net_http => true,
|
162
171
|
:instrument_redis => true,
|
163
172
|
:instrument_sequel => true,
|
164
|
-
:
|
165
|
-
:
|
166
|
-
:send_params => true,
|
167
|
-
:endpoint => "https://push.appsignal.com",
|
168
|
-
:push_api_key => "abc",
|
173
|
+
:log => "file",
|
174
|
+
:log_level => "info",
|
169
175
|
:name => "TestApp",
|
170
|
-
:
|
171
|
-
:
|
172
|
-
:enable_gc_instrumentation => false,
|
173
|
-
:enable_host_metrics => true,
|
174
|
-
:enable_minutely_probes => true,
|
175
|
-
:ca_file_path => File.join(resources_dir, "cacert.pem"),
|
176
|
-
:dns_servers => [],
|
177
|
-
:files_world_accessible => true,
|
178
|
-
:transaction_debug_mode => false,
|
176
|
+
:push_api_key => "abc",
|
177
|
+
:request_headers => [],
|
179
178
|
:revision => "v2.5.1",
|
180
|
-
:
|
179
|
+
:send_environment_metadata => true,
|
180
|
+
:send_params => true,
|
181
|
+
:skip_session_data => false,
|
182
|
+
:transaction_debug_mode => false
|
181
183
|
)
|
182
184
|
end
|
183
185
|
|
@@ -318,13 +320,15 @@ describe Appsignal::Config do
|
|
318
320
|
"non-existing-path",
|
319
321
|
"production",
|
320
322
|
:running_in_container => true,
|
321
|
-
:debug => true
|
323
|
+
:debug => true,
|
324
|
+
:log_level => "debug"
|
322
325
|
)
|
323
326
|
end
|
324
327
|
|
325
328
|
it "overrides system detected and defaults config" do
|
326
329
|
expect(config[:running_in_container]).to be_truthy
|
327
330
|
expect(config[:debug]).to be_truthy
|
331
|
+
expect(config[:log_level]).to eq("debug")
|
328
332
|
end
|
329
333
|
end
|
330
334
|
|
@@ -501,6 +505,7 @@ describe Appsignal::Config do
|
|
501
505
|
config[:log] = "stdout"
|
502
506
|
config[:log_path] = "/tmp"
|
503
507
|
config[:filter_parameters] = %w[password confirm_password]
|
508
|
+
config[:filter_session_data] = %w[key1 key2]
|
504
509
|
config[:running_in_container] = false
|
505
510
|
config[:dns_servers] = ["8.8.8.8", "8.8.4.4"]
|
506
511
|
config[:transaction_debug_mode] = true
|
@@ -534,6 +539,8 @@ describe Appsignal::Config do
|
|
534
539
|
expect(ENV["_APPSIGNAL_FILES_WORLD_ACCESSIBLE"]).to eq "true"
|
535
540
|
expect(ENV["_APPSIGNAL_TRANSACTION_DEBUG_MODE"]).to eq "true"
|
536
541
|
expect(ENV["_APPSIGNAL_SEND_ENVIRONMENT_METADATA"]).to eq "false"
|
542
|
+
expect(ENV["_APPSIGNAL_FILTER_PARAMETERS"]).to eq "password,confirm_password"
|
543
|
+
expect(ENV["_APPSIGNAL_FILTER_SESSION_DATA"]).to eq "key1,key2"
|
537
544
|
expect(ENV["_APP_REVISION"]).to eq "v2.5.1"
|
538
545
|
expect(ENV).to_not have_key("_APPSIGNAL_WORKING_DIR_PATH")
|
539
546
|
expect(ENV).to_not have_key("_APPSIGNAL_WORKING_DIRECTORY_PATH")
|
@@ -0,0 +1,23 @@
|
|
1
|
+
describe Appsignal::Hooks::MriHook do
|
2
|
+
describe "#dependencies_present?" do
|
3
|
+
subject { described_class.new.dependencies_present? }
|
4
|
+
|
5
|
+
if DependencyHelper.running_jruby?
|
6
|
+
it { is_expected.to be_falsy }
|
7
|
+
else
|
8
|
+
it { is_expected.to be_truthy }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
unless DependencyHelper.running_jruby?
|
13
|
+
context "install" do
|
14
|
+
before do
|
15
|
+
Appsignal::Hooks.load_hooks
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should be added to minutely probes" do
|
19
|
+
expect(Appsignal::Minutely.probes[:mri]).to be Appsignal::Probes::MriProbe
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
describe Appsignal::Probes::MriProbe do
|
2
|
+
let(:probe) { described_class.new }
|
3
|
+
|
4
|
+
describe ".dependencies_present?" do
|
5
|
+
if DependencyHelper.running_jruby? || DependencyHelper.running_ruby_2_0?
|
6
|
+
it "should not be present" do
|
7
|
+
expect(described_class.dependencies_present?).to be_falsy
|
8
|
+
end
|
9
|
+
else
|
10
|
+
it "should be present" do
|
11
|
+
expect(described_class.dependencies_present?).to be_truthy
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
unless DependencyHelper.running_jruby? || DependencyHelper.running_ruby_2_0?
|
17
|
+
describe "#call" do
|
18
|
+
it "should track vm metrics" do
|
19
|
+
expect_distribution_value(:class_serial)
|
20
|
+
expect_distribution_value(:global_constant_state)
|
21
|
+
|
22
|
+
probe.call
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def expect_distribution_value(metric)
|
27
|
+
expect(Appsignal).to receive(:add_distribution_value)
|
28
|
+
.with("ruby_vm", kind_of(Numeric), :metric => metric)
|
29
|
+
.and_call_original
|
30
|
+
.once
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require "appsignal/span"
|
2
|
+
|
3
|
+
describe Appsignal::Span do
|
4
|
+
before :context do
|
5
|
+
start_agent
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:namespace) { "web" }
|
9
|
+
let(:root) { Appsignal::Span.new(namespace) }
|
10
|
+
|
11
|
+
describe "creating a span" do
|
12
|
+
it "creates an empty span" do
|
13
|
+
expect(root.to_h["namespace"]).to eq "web"
|
14
|
+
expect(root.to_h["trace_id"].length).to eq 16
|
15
|
+
expect(root.to_h["span_id"].length).to eq 8
|
16
|
+
expect(root.to_h["parent_span_id"]).to be_empty
|
17
|
+
expect(root.to_h["name"]).to be_empty
|
18
|
+
expect(root.to_h["start_time"]).to be > 1_600_000_000
|
19
|
+
expect(root.to_h["closed"]).to be false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#child" do
|
24
|
+
let(:child) { root.child }
|
25
|
+
|
26
|
+
it "creates a child span" do
|
27
|
+
expect(child.to_h["namespace"]).to be_empty
|
28
|
+
expect(child.to_h["trace_id"].length).to eq 16
|
29
|
+
expect(child.to_h["span_id"].length).to eq 8
|
30
|
+
expect(child.to_h["parent_span_id"]).to eq root.to_h["span_id"]
|
31
|
+
expect(child.to_h["name"]).to be_empty
|
32
|
+
expect(child.to_h["start_time"]).to be > 1_600_000_000
|
33
|
+
expect(child.to_h["closed"]).to be false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#add_error" do
|
38
|
+
it "adds an error" do
|
39
|
+
begin
|
40
|
+
raise "Error"
|
41
|
+
rescue => error
|
42
|
+
root.add_error(error)
|
43
|
+
end
|
44
|
+
|
45
|
+
error = root.to_h["error"]
|
46
|
+
expect(error["name"]).to eq "RuntimeError"
|
47
|
+
expect(error["message"]).to eq "Error"
|
48
|
+
expect(error["backtrace"]).not_to be_empty
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "set_sample_data" do
|
53
|
+
it "sets sample data" do
|
54
|
+
root.set_sample_data(:params, "key" => "value")
|
55
|
+
|
56
|
+
sample_data = root.to_h["sample_data"]
|
57
|
+
expect(sample_data["params"]).to eq "{\"key\":\"value\"}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "#name=" do
|
62
|
+
it "sets the name" do
|
63
|
+
root.name = "Span name"
|
64
|
+
|
65
|
+
expect(root.to_h["name"]).to eq "Span name"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#[]=" do
|
70
|
+
let(:attributes) { root.to_h["attributes"] }
|
71
|
+
|
72
|
+
it "sets a string attribute" do
|
73
|
+
root["string"] = "attribute"
|
74
|
+
|
75
|
+
expect(attributes["string"]).to eq "attribute"
|
76
|
+
end
|
77
|
+
|
78
|
+
it "sets an integer attribute" do
|
79
|
+
root["integer"] = 1001
|
80
|
+
|
81
|
+
expect(attributes["integer"]).to eq 1001
|
82
|
+
end
|
83
|
+
|
84
|
+
it "sets a bigint attribute" do
|
85
|
+
root["bigint"] = 1 << 64
|
86
|
+
|
87
|
+
expect(attributes["bigint"]).to eq "bigint:#{1 << 64}"
|
88
|
+
end
|
89
|
+
|
90
|
+
it "sets a boolean attribute" do
|
91
|
+
root["true"] = true
|
92
|
+
root["false"] = false
|
93
|
+
|
94
|
+
expect(attributes["true"]).to eq true
|
95
|
+
expect(attributes["false"]).to eq false
|
96
|
+
end
|
97
|
+
|
98
|
+
it "sets a float attribute" do
|
99
|
+
root["float"] = 10.01
|
100
|
+
|
101
|
+
expect(attributes["float"]).to eq 10.01
|
102
|
+
end
|
103
|
+
|
104
|
+
it "raises an error for other types" do
|
105
|
+
expect do
|
106
|
+
root["something"] = Object.new
|
107
|
+
end.to raise_error TypeError
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe "#instrument" do
|
112
|
+
it "closes the span after yielding" do
|
113
|
+
root.instrument do
|
114
|
+
# Nothing happening
|
115
|
+
end
|
116
|
+
expect(root.closed?).to eq true
|
117
|
+
end
|
118
|
+
|
119
|
+
context "with an error raised in the passed block" do
|
120
|
+
it "closes the span after yielding" do
|
121
|
+
expect do
|
122
|
+
root.instrument do
|
123
|
+
raise ExampleException, "foo"
|
124
|
+
end
|
125
|
+
end.to raise_error(ExampleException, "foo")
|
126
|
+
expect(root.closed?).to eq true
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "#close" do
|
132
|
+
it "closes a span" do
|
133
|
+
expect(root.closed?).to eq false
|
134
|
+
|
135
|
+
root.close
|
136
|
+
|
137
|
+
expect(root.to_h).to be_nil
|
138
|
+
expect(root.closed?).to eq true
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -1341,6 +1341,31 @@ describe Appsignal::Transaction do
|
|
1341
1341
|
end
|
1342
1342
|
end
|
1343
1343
|
|
1344
|
+
describe "#cleaned_error_message" do
|
1345
|
+
let(:error) { StandardError.new("Error message") }
|
1346
|
+
subject { transaction.send(:cleaned_error_message, error) }
|
1347
|
+
|
1348
|
+
it "returns the error message" do
|
1349
|
+
expect(subject).to eq "Error message"
|
1350
|
+
end
|
1351
|
+
|
1352
|
+
context "with a PG::UniqueViolation" do
|
1353
|
+
module PG
|
1354
|
+
class UniqueViolation < StandardError; end
|
1355
|
+
end
|
1356
|
+
|
1357
|
+
let(:error) do
|
1358
|
+
PG::UniqueViolation.new(
|
1359
|
+
"ERROR: duplicate key value violates unique constraint \"index_users_on_email\" DETAIL: Key (email)=(test@test.com) already exists."
|
1360
|
+
)
|
1361
|
+
end
|
1362
|
+
|
1363
|
+
it "returns a sanizited error message" do
|
1364
|
+
expect(subject).to eq "ERROR: duplicate key value violates unique constraint \"index_users_on_email\" DETAIL: Key (email)=(?) already exists."
|
1365
|
+
end
|
1366
|
+
end
|
1367
|
+
end
|
1368
|
+
|
1344
1369
|
describe ".to_hash / .to_h" do
|
1345
1370
|
subject { transaction.to_hash }
|
1346
1371
|
|