appsignal 3.0.7 → 3.0.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -105,7 +105,6 @@ module Appsignal
105
105
  paths_report = Paths.new
106
106
  data[:paths] = paths_report.report
107
107
  print_paths_section(paths_report)
108
- print_empty_line
109
108
 
110
109
  transmit_report_to_appsignal if send_report_to_appsignal?(options)
111
110
  end
@@ -327,6 +326,7 @@ module Appsignal
327
326
  puts "AppSignal library"
328
327
  data_section :library do
329
328
  save :language, "ruby"
329
+ puts_value "Language", "Ruby"
330
330
  puts_and_save :package_version, "Gem version", Appsignal::VERSION
331
331
  puts_and_save :agent_version, "Agent version", Appsignal::Extension.agent_version
332
332
  puts_and_save :extension_loaded, "Extension loaded", Appsignal.extension_loaded
@@ -399,6 +399,7 @@ module Appsignal
399
399
  puts " Architecture: #{report["architecture"]}"
400
400
  puts " Target: #{report["target"]}"
401
401
  puts " Musl override: #{report["musl_override"]}"
402
+ puts " Linux ARM override: #{report["linux_arm_override"]}"
402
403
  puts " Library type: #{report["library_type"]}"
403
404
  puts " Source: #{report["source"]}" if report["source"] != "remote"
404
405
  puts " Dependencies: #{report["dependencies"]}"
@@ -416,7 +417,7 @@ module Appsignal
416
417
  rbconfig = RbConfig::CONFIG
417
418
  puts "Host information"
418
419
  data_section :host do
419
- puts_and_save :architecture, "Architecture", rbconfig["host_cpu"]
420
+ puts_and_save :architecture, "Architecture", Appsignal::System.agent_architecture
420
421
 
421
422
  os_label = os = rbconfig["host_os"]
422
423
  os_label = "#{os} (Microsoft Windows is not supported.)" if Gem.win_platform?
@@ -573,9 +574,13 @@ module Appsignal
573
574
  "(file: #{ownership[:user]}:#{ownership[:uid]}, " \
574
575
  "process: #{process_user[:user]}:#{process_user[:uid]})"
575
576
  puts_value "Ownership?", owner, :level => 2
576
- return unless path.key?(:content)
577
- puts " Contents (last 10 lines):"
578
- puts path[:content].last(10)
577
+
578
+ if path.key?(:content)
579
+ puts " Contents (last 10 lines):"
580
+ puts path[:content].last(10)
581
+ else
582
+ print_empty_line
583
+ end
579
584
  end
580
585
 
581
586
  def print_empty_line
@@ -8,6 +8,7 @@ module Appsignal
8
8
  # @api private
9
9
  module System
10
10
  LINUX_TARGET = "linux".freeze
11
+ LINUX_ARM_ARCHITECTURE = "aarch64".freeze
11
12
  MUSL_TARGET = "linux-musl".freeze
12
13
  FREEBSD_TARGET = "freebsd".freeze
13
14
  GEM_EXT_PATH = File.expand_path("../../../ext", __FILE__).freeze
@@ -18,15 +19,18 @@ module Appsignal
18
19
 
19
20
  # Detect agent and extension platform build
20
21
  #
21
- # Used by `ext/extconf.rb` to select which build it should download and
22
+ # Used by `ext/*` to select which build it should download and
22
23
  # install.
23
24
  #
24
- # Use `export APPSIGNAL_BUILD_FOR_MUSL=1` if the detection doesn't work
25
- # and to force selection of the musl build.
25
+ # - Use `export APPSIGNAL_BUILD_FOR_MUSL=1` if the detection doesn't work
26
+ # and to force selection of the musl build.
27
+ # - Use `export APPSIGNAL_BUILD_FOR_LINUX_ARM=1` to enable the experimental
28
+ # Linux ARM build.
26
29
  #
27
30
  # @api private
28
31
  # @return [String]
29
32
  def self.agent_platform
33
+ return LINUX_TARGET if force_linux_arm_build?
30
34
  return MUSL_TARGET if force_musl_build?
31
35
 
32
36
  host_os = RbConfig::CONFIG["host_os"].downcase
@@ -53,6 +57,22 @@ module Appsignal
53
57
  local_os
54
58
  end
55
59
 
60
+ # Detect agent and extension architecture build
61
+ #
62
+ # Used by the `ext/*` tasks to select which architecture build it should download and install.
63
+ #
64
+ # - Use `export APPSIGNAL_BUILD_FOR_LINUX_ARM=1` to enable the experimental
65
+ # Linux ARM build.
66
+ #
67
+ # @api private
68
+ # @return [String]
69
+ def self.agent_architecture
70
+ return LINUX_ARM_ARCHITECTURE if force_linux_arm_build?
71
+
72
+ # Fallback on the Ruby
73
+ RbConfig::CONFIG["host_cpu"]
74
+ end
75
+
56
76
  # Returns whether or not the musl build was forced by the user.
57
77
  #
58
78
  # @api private
@@ -60,6 +80,13 @@ module Appsignal
60
80
  %w[true 1].include?(ENV["APPSIGNAL_BUILD_FOR_MUSL"])
61
81
  end
62
82
 
83
+ # Returns whether or not the linux ARM build was selected by the user.
84
+ #
85
+ # @api private
86
+ def self.force_linux_arm_build?
87
+ %w[true 1].include?(ENV["APPSIGNAL_BUILD_FOR_LINUX_ARM"])
88
+ end
89
+
63
90
  # @api private
64
91
  def self.versionify(version)
65
92
  Gem::Version.new(version)
@@ -526,7 +526,7 @@ module Appsignal
526
526
  end
527
527
 
528
528
  def cleaned_backtrace(backtrace)
529
- if defined?(::Rails) && backtrace
529
+ if defined?(::Rails) && Rails.respond_to?(:backtrace_cleaner) && backtrace
530
530
  ::Rails.backtrace_cleaner.clean(backtrace, nil)
531
531
  else
532
532
  backtrace
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Appsignal
4
- VERSION = "3.0.7".freeze
4
+ VERSION = "3.0.11".freeze
5
5
  end
@@ -0,0 +1,18 @@
1
+ #!/bin/bash
2
+
3
+ set -eu
4
+
5
+ mkdir -p $HOME/bin
6
+ cache_key=v1-lintje-$LINTJE_VERSION
7
+ cache restore $cache_key
8
+
9
+ # File exists and is executable
10
+ if [ -x "$HOME/bin/lintje" ]; then
11
+ echo "Restored Lintje $LINTJE_VERSION from cache"
12
+ else
13
+ echo "Downloading Lintje $LINTJE_VERSION"
14
+ curl -L \
15
+ https://github.com/tombruijn/lintje/releases/download/v$LINTJE_VERSION/x86_64-unknown-linux-gnu.tar.gz | \
16
+ tar -xz --directory $HOME/bin
17
+ cache store $cache_key $HOME/bin/lintje
18
+ fi
@@ -270,9 +270,10 @@ describe Appsignal::CLI::Diagnose, :api_stub => true, :send_report => :yes_cli_i
270
270
  "build" => {
271
271
  "time" => kind_of(String),
272
272
  "package_path" => File.expand_path("../../../../../", __FILE__),
273
- "architecture" => rbconfig["host_cpu"],
273
+ "architecture" => Appsignal::System.agent_architecture,
274
274
  "target" => Appsignal::System.agent_platform,
275
275
  "musl_override" => false,
276
+ "linux_arm_override" => false,
276
277
  "library_type" => jruby ? "dynamic" : "static",
277
278
  "source" => "remote",
278
279
  "dependencies" => kind_of(Hash),
@@ -301,9 +302,10 @@ describe Appsignal::CLI::Diagnose, :api_stub => true, :send_report => :yes_cli_i
301
302
  " Checksum: verified",
302
303
  "Build details",
303
304
  " Install time: 20",
304
- " Architecture: #{rbconfig["host_cpu"]}",
305
+ " Architecture: #{Appsignal::System.agent_architecture}",
305
306
  " Target: #{Appsignal::System.agent_platform}",
306
307
  " Musl override: false",
308
+ " Linux ARM override: false",
307
309
  " Library type: #{jruby ? "dynamic" : "static"}",
308
310
  " Dependencies: {",
309
311
  " Flags: {",
@@ -43,6 +43,14 @@ describe Appsignal::System do
43
43
  end
44
44
  end
45
45
 
46
+ context "when using the APPSIGNAL_BUILD_FOR_LINUX_ARM env var" do
47
+ it "returns the linux build" do
48
+ ENV["APPSIGNAL_BUILD_FOR_LINUX_ARM"] = "1"
49
+ is_expected.to eq("linux")
50
+ ENV.delete("APPSIGNAL_BUILD_FOR_LINUX_ARM")
51
+ end
52
+ end
53
+
46
54
  context "when on a musl system" do
47
55
  let(:ldd_output) { "musl libc (x86_64)\nVersion 1.1.16" }
48
56
 
@@ -93,4 +101,26 @@ describe Appsignal::System do
93
101
  end
94
102
  end
95
103
  end
104
+
105
+ describe ".agent_architecture" do
106
+ let(:architecture) { "x86_64" }
107
+ let(:ldd_output) { "" }
108
+ before do
109
+ allow(RbConfig::CONFIG).to receive(:[])
110
+ allow(RbConfig::CONFIG).to receive(:[]).with("host_cpu").and_return(architecture)
111
+ end
112
+ subject { described_class.agent_architecture }
113
+
114
+ it "returns the host CPU value" do
115
+ is_expected.to eq(architecture)
116
+ end
117
+
118
+ context "when using the APPSIGNAL_BUILD_FOR_LINUX_ARM env var" do
119
+ it "returns ARM 64 bit" do
120
+ ENV["APPSIGNAL_BUILD_FOR_LINUX_ARM"] = "1"
121
+ is_expected.to eq("aarch64")
122
+ ENV.delete("APPSIGNAL_BUILD_FOR_LINUX_ARM")
123
+ end
124
+ end
125
+ end
96
126
  end
@@ -1321,6 +1321,13 @@ describe Appsignal::Transaction do
1321
1321
  expect(subject).to eq ["line 1", "line 2"]
1322
1322
  end
1323
1323
 
1324
+ context "with Rails module but without backtrace_cleaner method" do
1325
+ it "returns the backtrace uncleaned" do
1326
+ stub_const("Rails", Module.new)
1327
+ expect(subject).to eq ["line 1", "line 2"]
1328
+ end
1329
+ end
1330
+
1324
1331
  if rails_present?
1325
1332
  context "with rails" do
1326
1333
  it "cleans the backtrace with the Rails backtrace cleaner" do
@@ -1,4 +1,6 @@
1
1
  RSpec.describe "Puma plugin" do
2
+ include WaitForHelper
3
+
2
4
  class MockPumaLauncher
3
5
  def events
4
6
  return @events if defined?(@events)
@@ -50,7 +52,7 @@ RSpec.describe "Puma plugin" do
50
52
  end
51
53
 
52
54
  def stop
53
- @socket && @socket.close
55
+ defined?(@socket) && @socket && @socket.close
54
56
  ensure
55
57
  @socket = nil
56
58
  end
@@ -72,6 +74,9 @@ RSpec.describe "Puma plugin" do
72
74
  let(:hostname) { Socket.gethostname }
73
75
  let(:expected_default_tags) { { "hostname" => hostname } }
74
76
  let(:stats_data) { { :backlog => 1 } }
77
+ before :context do
78
+ Appsignal.stop
79
+ end
75
80
  before do
76
81
  module Puma
77
82
  def self.stats
@@ -117,10 +122,10 @@ RSpec.describe "Puma plugin" do
117
122
  Object.send(:remove_const, :AppsignalPumaPlugin)
118
123
  end
119
124
 
120
- def run(plugin)
125
+ def run_plugin(plugin, &block)
121
126
  @client_thread = Thread.new { start_plugin(plugin) }
122
127
  @client_thread.abort_on_exception = true
123
- sleep 0.03
128
+ wait_for(:puma_client_wait, &block)
124
129
  ensure
125
130
  stop_all
126
131
  end
@@ -206,16 +211,16 @@ RSpec.describe "Puma plugin" do
206
211
  end
207
212
 
208
213
  it "collects puma stats as guage metrics with the (summed) worker metrics" do
209
- run(appsignal_plugin)
210
-
211
- expect(logs).to_not include([:error, kind_of(String)])
212
- expect_gauge(:workers, 2, "type" => "count")
213
- expect_gauge(:workers, 2, "type" => "booted")
214
- expect_gauge(:workers, 0, "type" => "old")
215
- expect_gauge(:connection_backlog, 0)
216
- expect_gauge(:pool_capacity, 10)
217
- expect_gauge(:threads, 10, "type" => "running")
218
- expect_gauge(:threads, 10, "type" => "max")
214
+ run_plugin(appsignal_plugin) do
215
+ expect(logs).to_not include([:error, kind_of(String)])
216
+ expect_gauge(:workers, 2, "type" => "count")
217
+ expect_gauge(:workers, 2, "type" => "booted")
218
+ expect_gauge(:workers, 0, "type" => "old")
219
+ expect_gauge(:connection_backlog, 0)
220
+ expect_gauge(:pool_capacity, 10)
221
+ expect_gauge(:threads, 10, "type" => "running")
222
+ expect_gauge(:threads, 10, "type" => "max")
223
+ end
219
224
  end
220
225
  end
221
226
 
@@ -230,13 +235,13 @@ RSpec.describe "Puma plugin" do
230
235
  end
231
236
 
232
237
  it "calls `puma_gauge` with the (summed) worker metrics" do
233
- run(appsignal_plugin)
234
-
235
- expect(logs).to_not include([:error, kind_of(String)])
236
- expect_gauge(:connection_backlog, 0)
237
- expect_gauge(:pool_capacity, 5)
238
- expect_gauge(:threads, 5, "type" => "running")
239
- expect_gauge(:threads, 5, "type" => "max")
238
+ run_plugin(appsignal_plugin) do
239
+ expect(logs).to_not include([:error, kind_of(String)])
240
+ expect_gauge(:connection_backlog, 0)
241
+ expect_gauge(:pool_capacity, 5)
242
+ expect_gauge(:threads, 5, "type" => "running")
243
+ expect_gauge(:threads, 5, "type" => "max")
244
+ end
240
245
  end
241
246
  end
242
247
 
@@ -246,10 +251,10 @@ RSpec.describe "Puma plugin" do
246
251
  after { ENV.delete("APPSIGNAL_HOSTNAME") }
247
252
 
248
253
  it "reports the APPSIGNAL_HOSTNAME as the hostname tag value" do
249
- run(appsignal_plugin)
250
-
251
- expect(logs).to_not include([:error, kind_of(String)])
252
- expect_gauge(:connection_backlog, 1)
254
+ run_plugin(appsignal_plugin) do
255
+ expect(logs).to_not include([:error, kind_of(String)])
256
+ expect_gauge(:connection_backlog, 1)
257
+ end
253
258
  end
254
259
  end
255
260
 
@@ -259,11 +264,11 @@ RSpec.describe "Puma plugin" do
259
264
  end
260
265
 
261
266
  it "fetches metrics from Puma.stats instead" do
262
- run(appsignal_plugin)
263
-
264
- expect(logs).to_not include([:error, kind_of(String)])
265
- expect(logs).to_not include([kind_of(Symbol), "AppSignal: No Puma stats to report."])
266
- expect_gauge(:connection_backlog, 1)
267
+ run_plugin(appsignal_plugin) do
268
+ expect(logs).to_not include([:error, kind_of(String)])
269
+ expect(logs).to_not include([kind_of(Symbol), "AppSignal: No Puma stats to report."])
270
+ expect_gauge(:connection_backlog, 1)
271
+ end
267
272
  end
268
273
  end
269
274
 
@@ -274,22 +279,21 @@ RSpec.describe "Puma plugin" do
274
279
  end
275
280
 
276
281
  it "does not fetch metrics" do
277
- run(appsignal_plugin)
278
-
279
- expect(logs).to_not include([:error, kind_of(String)])
280
- expect(logs).to include([:log, "AppSignal: No Puma stats to report."])
281
- expect(messages).to be_empty
282
+ run_plugin(appsignal_plugin) do
283
+ expect(logs).to_not include([:error, kind_of(String)])
284
+ expect(logs).to include([:log, "AppSignal: No Puma stats to report."])
285
+ expect(messages).to be_empty
286
+ end
282
287
  end
283
288
  end
284
289
 
285
290
  context "without running StatsD server" do
286
291
  it "does nothing" do
287
- Appsignal.stop
288
292
  stop_all
289
- run(appsignal_plugin)
290
-
291
- expect(logs).to_not include([:error, kind_of(String)])
292
- expect(messages).to be_empty
293
+ run_plugin(appsignal_plugin) do
294
+ expect(logs).to_not include([:error, kind_of(String)])
295
+ expect(messages).to be_empty
296
+ end
293
297
  end
294
298
  end
295
299
  end
@@ -16,13 +16,25 @@ module WaitForHelper
16
16
  def wait_for(name)
17
17
  max_wait = 5_000
18
18
  i = 0
19
+ error = nil
19
20
  while i < max_wait
20
- break if yield
21
- i += 1
22
- sleep 0.001
21
+ begin
22
+ result = yield
23
+ break if result
24
+ rescue Exception => e # rubocop:disable Lint/RescueException
25
+ # Capture error so we know if it exited with an error
26
+ error = e
27
+ ensure
28
+ i += 1
29
+ sleep 0.001
30
+ end
23
31
  end
24
32
 
25
33
  return unless i >= max_wait
26
- raise "Waited 5 seconds for #{name} condition, but was not met."
34
+ error_message =
35
+ if error
36
+ "\nError: #{error.class}: #{error.message}\n#{error.backtrace.join("\n")}"
37
+ end
38
+ raise "Waited 5 seconds for #{name} condition, but was not met.#{error_message}"
27
39
  end
28
40
  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: 3.0.7
4
+ version: 3.0.11
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-06-15 00:00:00.000000000 Z
13
+ date: 2021-07-26 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rack
@@ -136,6 +136,7 @@ files:
136
136
  - ".github/ISSUE_TEMPLATE/bug_report.md"
137
137
  - ".github/ISSUE_TEMPLATE/chore.md"
138
138
  - ".gitignore"
139
+ - ".gitmodules"
139
140
  - ".rspec"
140
141
  - ".rubocop.yml"
141
142
  - ".rubocop_todo.yml"
@@ -270,6 +271,7 @@ files:
270
271
  - mono.yml
271
272
  - resources/appsignal.yml.erb
272
273
  - resources/cacert.pem
274
+ - script/install_lintje
273
275
  - spec/.rubocop.yml
274
276
  - spec/lib/appsignal/auth_check_spec.rb
275
277
  - spec/lib/appsignal/capistrano2_spec.rb