appsignal 3.0.0.beta.1 → 3.0.0.rc.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/.rubocop_todo.yml +1 -1
- data/.semaphore/semaphore.yml +88 -88
- data/CHANGELOG.md +20 -0
- data/appsignal.gemspec +1 -1
- data/build_matrix.yml +11 -11
- data/lib/appsignal.rb +1 -2
- data/lib/appsignal/helpers/instrumentation.rb +69 -5
- data/lib/appsignal/hooks.rb +16 -0
- data/lib/appsignal/hooks/action_cable.rb +10 -2
- data/lib/appsignal/hooks/sidekiq.rb +9 -142
- data/lib/appsignal/integrations/object.rb +21 -43
- data/lib/appsignal/integrations/sidekiq.rb +171 -0
- data/lib/appsignal/minutely.rb +6 -0
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/hooks/action_cable_spec.rb +88 -0
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +60 -458
- data/spec/lib/appsignal/hooks_spec.rb +41 -0
- data/spec/lib/appsignal/integrations/object_spec.rb +91 -4
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +524 -0
- data/spec/lib/appsignal_spec.rb +162 -47
- data/spec/lib/puma/appsignal_spec.rb +28 -0
- metadata +7 -4
data/spec/lib/appsignal_spec.rb
CHANGED
@@ -686,6 +686,9 @@ describe Appsignal do
|
|
686
686
|
)
|
687
687
|
end
|
688
688
|
let(:error) { ExampleException.new }
|
689
|
+
let(:err_stream) { std_stream }
|
690
|
+
let(:stderr) { err_stream.read }
|
691
|
+
around { |example| keep_transactions { example.run } }
|
689
692
|
|
690
693
|
it "sends the error to AppSignal" do
|
691
694
|
expect(Appsignal::Transaction).to receive(:new).with(
|
@@ -719,30 +722,60 @@ describe Appsignal do
|
|
719
722
|
|
720
723
|
context "with tags" do
|
721
724
|
let(:tags) { { :a => "a", :b => "b" } }
|
722
|
-
before do
|
723
|
-
allow(Appsignal::Transaction).to receive(:new).and_return(transaction)
|
724
|
-
end
|
725
725
|
|
726
|
-
it "
|
727
|
-
|
728
|
-
|
726
|
+
it "prints a deprecation warning and tags the transaction" do
|
727
|
+
logs = capture_logs do
|
728
|
+
expect do
|
729
|
+
capture_std_streams(std_stream, err_stream) do
|
730
|
+
Appsignal.send_error(error, tags)
|
731
|
+
end
|
732
|
+
end.to change { created_transactions.count }.by(1)
|
733
|
+
end
|
734
|
+
|
735
|
+
transaction = last_transaction
|
736
|
+
transaction_hash = transaction.to_h
|
737
|
+
expect(transaction_hash).to include(
|
738
|
+
"sample_data" => hash_including(
|
739
|
+
"tags" => { "a" => "a", "b" => "b" }
|
740
|
+
)
|
741
|
+
)
|
729
742
|
|
730
|
-
Appsignal.send_error
|
743
|
+
message = "The tags argument for `Appsignal.send_error` is deprecated. " \
|
744
|
+
"Please use the block method to set tags instead.\n\n" \
|
745
|
+
" Appsignal.send_error(error) do |transaction|\n" \
|
746
|
+
" transaction.set_tags(#{tags.inspect})\n" \
|
747
|
+
" end\n\n" \
|
748
|
+
"Appsignal.send_error called on location: #{__FILE__}:"
|
749
|
+
expect(stderr).to include("appsignal WARNING: #{message}")
|
750
|
+
expect(logs).to include(message)
|
731
751
|
end
|
732
752
|
end
|
733
753
|
|
734
754
|
context "with namespace" do
|
735
755
|
let(:namespace) { "admin" }
|
736
756
|
|
737
|
-
it "sets the namespace on the transaction" do
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
757
|
+
it "prints a deprecation warning and sets the namespace on the transaction" do
|
758
|
+
logs = capture_logs do
|
759
|
+
expect do
|
760
|
+
capture_std_streams(std_stream, err_stream) do
|
761
|
+
Appsignal.send_error(error, nil, namespace)
|
762
|
+
end
|
763
|
+
end.to change { created_transactions.count }.by(1)
|
764
|
+
end
|
765
|
+
|
766
|
+
transaction = last_transaction
|
767
|
+
transaction_hash = transaction.to_h
|
768
|
+
expect(transaction_hash).to include("namespace" => namespace)
|
744
769
|
|
745
|
-
|
770
|
+
message = "The namespace argument for `Appsignal.send_error` is deprecated. " \
|
771
|
+
"Please use the block method to set the namespace instead.\n\n" \
|
772
|
+
" Appsignal.send_error(error) do |transaction|\n" \
|
773
|
+
" transaction.namespace(#{namespace.inspect})\n" \
|
774
|
+
" end\n\n" \
|
775
|
+
"Appsignal.send_error called on location: #{__FILE__}:"
|
776
|
+
expect(stderr).to include("appsignal WARNING: #{message}")
|
777
|
+
expect(logs).to include(message)
|
778
|
+
end
|
746
779
|
end
|
747
780
|
|
748
781
|
context "when given a block" do
|
@@ -769,53 +802,85 @@ describe Appsignal do
|
|
769
802
|
end
|
770
803
|
|
771
804
|
describe ".listen_for_error" do
|
805
|
+
around { |example| keep_transactions { example.run } }
|
806
|
+
|
772
807
|
it "records the error and re-raise it" do
|
773
|
-
expect(Appsignal).to receive(:send_error).with(
|
774
|
-
kind_of(ExampleException),
|
775
|
-
nil,
|
776
|
-
Appsignal::Transaction::HTTP_REQUEST
|
777
|
-
)
|
778
808
|
expect do
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
809
|
+
expect do
|
810
|
+
Appsignal.listen_for_error do
|
811
|
+
raise ExampleException, "I am an exception"
|
812
|
+
end
|
813
|
+
end.to raise_error(ExampleException, "I am an exception")
|
814
|
+
end.to change { created_transactions.count }.by(1)
|
815
|
+
|
816
|
+
expect(last_transaction.to_h).to include(
|
817
|
+
"error" => {
|
818
|
+
"name" => "ExampleException",
|
819
|
+
"message" => "I am an exception",
|
820
|
+
"backtrace" => kind_of(String)
|
821
|
+
},
|
822
|
+
"namespace" => Appsignal::Transaction::HTTP_REQUEST, # Default namespace
|
823
|
+
"sample_data" => hash_including(
|
824
|
+
"tags" => {}
|
825
|
+
)
|
826
|
+
)
|
783
827
|
end
|
784
828
|
|
785
829
|
context "with tags" do
|
786
830
|
it "adds tags to the transaction" do
|
787
|
-
expect(Appsignal).to receive(:send_error).with(
|
788
|
-
kind_of(ExampleException),
|
789
|
-
{ "foo" => "bar" },
|
790
|
-
Appsignal::Transaction::HTTP_REQUEST
|
791
|
-
)
|
792
831
|
expect do
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
832
|
+
expect do
|
833
|
+
Appsignal.listen_for_error("foo" => "bar") do
|
834
|
+
raise ExampleException, "I am an exception"
|
835
|
+
end
|
836
|
+
end.to raise_error(ExampleException, "I am an exception")
|
837
|
+
end.to change { created_transactions.count }.by(1)
|
838
|
+
|
839
|
+
expect(last_transaction.to_h).to include(
|
840
|
+
"error" => {
|
841
|
+
"name" => "ExampleException",
|
842
|
+
"message" => "I am an exception",
|
843
|
+
"backtrace" => kind_of(String)
|
844
|
+
},
|
845
|
+
"namespace" => Appsignal::Transaction::HTTP_REQUEST, # Default namespace
|
846
|
+
"sample_data" => hash_including(
|
847
|
+
"tags" => { "foo" => "bar" }
|
848
|
+
)
|
849
|
+
)
|
797
850
|
end
|
798
851
|
end
|
799
852
|
|
800
853
|
context "with a custom namespace" do
|
801
854
|
it "adds the namespace to the transaction" do
|
802
|
-
expect(Appsignal).to receive(:send_error).with(
|
803
|
-
kind_of(ExampleException),
|
804
|
-
nil,
|
805
|
-
"custom_namespace"
|
806
|
-
)
|
807
855
|
expect do
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
856
|
+
expect do
|
857
|
+
Appsignal.listen_for_error(nil, "custom_namespace") do
|
858
|
+
raise ExampleException, "I am an exception"
|
859
|
+
end
|
860
|
+
end.to raise_error(ExampleException, "I am an exception")
|
861
|
+
end.to change { created_transactions.count }.by(1)
|
862
|
+
|
863
|
+
expect(last_transaction.to_h).to include(
|
864
|
+
"error" => {
|
865
|
+
"name" => "ExampleException",
|
866
|
+
"message" => "I am an exception",
|
867
|
+
"backtrace" => kind_of(String)
|
868
|
+
},
|
869
|
+
"namespace" => "custom_namespace",
|
870
|
+
"sample_data" => hash_including(
|
871
|
+
"tags" => {}
|
872
|
+
)
|
873
|
+
)
|
812
874
|
end
|
813
875
|
end
|
814
876
|
end
|
815
877
|
|
816
878
|
describe ".set_error" do
|
879
|
+
let(:err_stream) { std_stream }
|
880
|
+
let(:stderr) { err_stream.read }
|
881
|
+
let(:error) { ExampleException.new("I am an exception") }
|
817
882
|
before { allow(Appsignal::Transaction).to receive(:current).and_return(transaction) }
|
818
|
-
|
883
|
+
around { |example| keep_transactions { example.run } }
|
819
884
|
|
820
885
|
context "when there is an active transaction" do
|
821
886
|
it "adds the error to the active transaction" do
|
@@ -845,24 +910,74 @@ describe Appsignal do
|
|
845
910
|
context "with tags" do
|
846
911
|
let(:tags) { { "foo" => "bar" } }
|
847
912
|
|
848
|
-
it "
|
913
|
+
it "prints a deprecation warning and tags the transaction" do
|
849
914
|
expect(transaction).to receive(:set_error).with(error)
|
850
915
|
expect(transaction).to receive(:set_tags).with(tags)
|
851
916
|
expect(transaction).to_not receive(:set_namespace)
|
852
917
|
|
853
|
-
|
918
|
+
logs = capture_logs do
|
919
|
+
capture_std_streams(std_stream, err_stream) do
|
920
|
+
Appsignal.set_error(error, tags)
|
921
|
+
end
|
922
|
+
end
|
923
|
+
|
924
|
+
message = "The tags argument for `Appsignal.set_error` is deprecated. " \
|
925
|
+
"Please use the block method to set tags instead.\n\n" \
|
926
|
+
" Appsignal.set_error(error) do |transaction|\n" \
|
927
|
+
" transaction.set_tags(#{tags.inspect})\n" \
|
928
|
+
" end\n\n" \
|
929
|
+
"Appsignal.set_error called on location: #{__FILE__}:"
|
930
|
+
expect(stderr).to include("appsignal WARNING: #{message}")
|
931
|
+
expect(logs).to include(message)
|
854
932
|
end
|
855
933
|
end
|
856
934
|
|
857
935
|
context "with namespace" do
|
858
936
|
let(:namespace) { "admin" }
|
859
937
|
|
860
|
-
it "
|
938
|
+
it "prints a deprecation warning andsets the namespace on the transaction" do
|
861
939
|
expect(transaction).to receive(:set_error).with(error)
|
862
940
|
expect(transaction).to_not receive(:set_tags)
|
863
941
|
expect(transaction).to receive(:set_namespace).with(namespace)
|
864
942
|
|
865
|
-
|
943
|
+
logs = capture_logs do
|
944
|
+
capture_std_streams(std_stream, err_stream) do
|
945
|
+
Appsignal.set_error(error, nil, namespace)
|
946
|
+
end
|
947
|
+
end
|
948
|
+
|
949
|
+
message = "The namespace argument for `Appsignal.set_error` is deprecated. " \
|
950
|
+
"Please use the block method to set the namespace instead.\n\n" \
|
951
|
+
" Appsignal.set_error(error) do |transaction|\n" \
|
952
|
+
" transaction.namespace(#{namespace.inspect})\n" \
|
953
|
+
" end\n\n" \
|
954
|
+
"Appsignal.set_error called on location: #{__FILE__}:"
|
955
|
+
expect(stderr).to include("appsignal WARNING: #{message}")
|
956
|
+
expect(logs).to include(message)
|
957
|
+
end
|
958
|
+
end
|
959
|
+
|
960
|
+
context "when given a block" do
|
961
|
+
it "yields the transaction and allows additional metadata to be set" do
|
962
|
+
captured_transaction = nil
|
963
|
+
keep_transactions do
|
964
|
+
Appsignal.set_error(StandardError.new("my_error")) do |transaction|
|
965
|
+
captured_transaction = transaction
|
966
|
+
transaction.set_action("my_action")
|
967
|
+
transaction.set_namespace("my_namespace")
|
968
|
+
end
|
969
|
+
end
|
970
|
+
|
971
|
+
expect(transaction).to eql(captured_transaction)
|
972
|
+
expect(captured_transaction.to_h).to include(
|
973
|
+
"namespace" => "my_namespace",
|
974
|
+
"action" => "my_action",
|
975
|
+
"error" => {
|
976
|
+
"name" => "StandardError",
|
977
|
+
"message" => "my_error",
|
978
|
+
"backtrace" => kind_of(String)
|
979
|
+
}
|
980
|
+
)
|
866
981
|
end
|
867
982
|
end
|
868
983
|
end
|
@@ -23,6 +23,27 @@ RSpec.describe "Puma plugin" do
|
|
23
23
|
def self.stats
|
24
24
|
end
|
25
25
|
|
26
|
+
def self.run
|
27
|
+
# Capture threads running before application is preloaded
|
28
|
+
before = Thread.list.reject { |t| t.thread_variable_get(:fork_safe) }
|
29
|
+
|
30
|
+
# An abbreviated version of what happens in Puma::Cluster#run
|
31
|
+
launcher = MockPumaLauncher.new
|
32
|
+
plugin = Plugin.plugin.new
|
33
|
+
plugin.start(launcher)
|
34
|
+
launcher.events.on_booted.call
|
35
|
+
|
36
|
+
# Wait for minutely probe thread to finish starting
|
37
|
+
sleep 0.005
|
38
|
+
|
39
|
+
# Capture any new threads running after application is preloaded.
|
40
|
+
# Any threads created during the preloading phase will not be
|
41
|
+
# carried over into the forked workers. Puma warns about these
|
42
|
+
# but the minutely probe thread should only exist in the main process.
|
43
|
+
after = Thread.list.reject { |t| t.thread_variable_get(:fork_safe) }
|
44
|
+
$stdout.puts "! WARNING: Detected #{after.size - before.size} Thread(s) started in app boot" if after.size > before.size
|
45
|
+
end
|
46
|
+
|
26
47
|
class Plugin
|
27
48
|
class << self
|
28
49
|
attr_reader :plugin
|
@@ -68,6 +89,13 @@ RSpec.describe "Puma plugin" do
|
|
68
89
|
wait_for("enough probe calls") { probe.calls >= 2 }
|
69
90
|
end
|
70
91
|
|
92
|
+
it "marks the PumaProbe thread as fork-safe", :not_ruby19 do
|
93
|
+
out_stream = std_stream
|
94
|
+
capture_stdout(out_stream) { Puma.run }
|
95
|
+
|
96
|
+
expect(out_stream.read).not_to include("WARNING: Detected 1 Thread")
|
97
|
+
end
|
98
|
+
|
71
99
|
context "without Puma.stats" do
|
72
100
|
before { Puma.singleton_class.send(:remove_method, :stats) }
|
73
101
|
|
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: 3.0.0.
|
4
|
+
version: 3.0.0.rc.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Beekman
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-
|
13
|
+
date: 2021-02-23 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rack
|
@@ -241,6 +241,7 @@ files:
|
|
241
241
|
- lib/appsignal/integrations/rake.rb
|
242
242
|
- lib/appsignal/integrations/redis.rb
|
243
243
|
- lib/appsignal/integrations/resque.rb
|
244
|
+
- lib/appsignal/integrations/sidekiq.rb
|
244
245
|
- lib/appsignal/integrations/sinatra.rb
|
245
246
|
- lib/appsignal/integrations/unicorn.rb
|
246
247
|
- lib/appsignal/integrations/webmachine.rb
|
@@ -326,6 +327,7 @@ files:
|
|
326
327
|
- spec/lib/appsignal/integrations/padrino_spec.rb
|
327
328
|
- spec/lib/appsignal/integrations/que_spec.rb
|
328
329
|
- spec/lib/appsignal/integrations/railtie_spec.rb
|
330
|
+
- spec/lib/appsignal/integrations/sidekiq_spec.rb
|
329
331
|
- spec/lib/appsignal/integrations/sinatra_spec.rb
|
330
332
|
- spec/lib/appsignal/integrations/webmachine_spec.rb
|
331
333
|
- spec/lib/appsignal/logger_spec.rb
|
@@ -404,14 +406,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
404
406
|
requirements:
|
405
407
|
- - ">="
|
406
408
|
- !ruby/object:Gem::Version
|
407
|
-
version: '
|
409
|
+
version: '2.0'
|
408
410
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
409
411
|
requirements:
|
410
412
|
- - ">"
|
411
413
|
- !ruby/object:Gem::Version
|
412
414
|
version: 1.3.1
|
413
415
|
requirements: []
|
414
|
-
rubygems_version: 3.2.
|
416
|
+
rubygems_version: 3.2.8
|
415
417
|
signing_key:
|
416
418
|
specification_version: 4
|
417
419
|
summary: Logs performance and exception data from your app to appsignal.com
|
@@ -473,6 +475,7 @@ test_files:
|
|
473
475
|
- spec/lib/appsignal/integrations/padrino_spec.rb
|
474
476
|
- spec/lib/appsignal/integrations/que_spec.rb
|
475
477
|
- spec/lib/appsignal/integrations/railtie_spec.rb
|
478
|
+
- spec/lib/appsignal/integrations/sidekiq_spec.rb
|
476
479
|
- spec/lib/appsignal/integrations/sinatra_spec.rb
|
477
480
|
- spec/lib/appsignal/integrations/webmachine_spec.rb
|
478
481
|
- spec/lib/appsignal/logger_spec.rb
|