appsignal 2.10.9-java → 2.11.0.alpha.1-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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 471917b7c9708ab3978364fac0ae7e1c87a61ba0ec596e3ca5b6227784fa6779
4
- data.tar.gz: 360aaf2f25e55c285b708cd8f379f6305bd04a4094cdb95d9cb64e0f2d772483
3
+ metadata.gz: 6a9839a7b5f0bfb83a80cbfbf7f7b9165d99a85ea477b911034742c52e158269
4
+ data.tar.gz: 1753bb37eaeadc98397573098a3b9cf1d718c072074ff3a2d45d3251e75db5f2
5
5
  SHA512:
6
- metadata.gz: 4f19363c45bb5a089f1ce255b84b8282be1cee8ab60d9276212e2ee5849f3e1840d0f5ab33506416eb7d1e4ff4b09d5d1119d8a1cd0ba11398d9d23318099aba
7
- data.tar.gz: 8a61386562b1fd28dfa9b90493729a5392b448ad281527caaa71401a2b98fd10018e2680e920c10127dafe94da23c08ace32d681659586ab3029239bf97ae9d0
6
+ metadata.gz: 4b3a00048ae78fab6cd1f258682a47215745e2f24bb9e29f119a9b0867caed5eaa39693214a7901b0d8f126bc4abba257318b1ac1e16364b6064d3a0857f51d2
7
+ data.tar.gz: e82a5e2dee87442a90ab2a67b0627f4d4d787243bde54d0ee78420f8286c97f53ca97c97e0283f6991ad123180ab6303564a610159d862e2a1ffbd5921d534f8
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ # 2.11.0
4
+ - Track queue time regardless of namespace. Support custom namespaces. PR #602
5
+ - Report Ruby environment metadata. PR #621
6
+
3
7
  # 2.10.9
4
8
  - Use http proxy if configured when downloading agent. PR #606
5
9
  - Clear event details cache every 48 hours.
@@ -1,70 +1,70 @@
1
1
  ---
2
- version: 6ced5a6
2
+ version: 38a8a6f
3
3
  mirrors:
4
4
  - https://appsignal-agent-releases.global.ssl.fastly.net
5
5
  - https://d135dj0rjqvssy.cloudfront.net
6
6
  triples:
7
7
  x86_64-darwin:
8
8
  static:
9
- checksum: dcc623a7eea18727c8628cf29d30e61379e543328a53d91bcf0c5751f3f9f313
9
+ checksum: 47f24cd09ab00fe3419a313c52d97170c9555d3ea85c8bd98cbb295df29456dd
10
10
  filename: appsignal-x86_64-darwin-all-static.tar.gz
11
11
  dynamic:
12
- checksum: 63f2ba8289390df75b72f414ed026acca07f26ac52bd25cd679c6de776b53ca4
12
+ checksum: a26437fbd4c97ff0b69bf42e83d968647532648313227224df1bbbd0ed105104
13
13
  filename: appsignal-x86_64-darwin-all-dynamic.tar.gz
14
14
  universal-darwin:
15
15
  static:
16
- checksum: dcc623a7eea18727c8628cf29d30e61379e543328a53d91bcf0c5751f3f9f313
16
+ checksum: 47f24cd09ab00fe3419a313c52d97170c9555d3ea85c8bd98cbb295df29456dd
17
17
  filename: appsignal-x86_64-darwin-all-static.tar.gz
18
18
  dynamic:
19
- checksum: 63f2ba8289390df75b72f414ed026acca07f26ac52bd25cd679c6de776b53ca4
19
+ checksum: a26437fbd4c97ff0b69bf42e83d968647532648313227224df1bbbd0ed105104
20
20
  filename: appsignal-x86_64-darwin-all-dynamic.tar.gz
21
21
  i686-linux:
22
22
  static:
23
- checksum: 8941c1d0a546da8f63bc65953afc439987616c62f2d5307856728ae4f2e0b2f5
23
+ checksum: ae37b329907cead537cf2a87a562ee92120add6c8874bc2e9235e5c537bca692
24
24
  filename: appsignal-i686-linux-all-static.tar.gz
25
25
  dynamic:
26
- checksum: ccb59ee85f8ba8790482db9de29be6936e92c395bb6306f0fecefbc4de50f78d
26
+ checksum: ee5da14c7b5d2cc2dc2ae345d19c33a08c7e4861975e34878c1c295e57b2d8bc
27
27
  filename: appsignal-i686-linux-all-dynamic.tar.gz
28
28
  x86-linux:
29
29
  static:
30
- checksum: 8941c1d0a546da8f63bc65953afc439987616c62f2d5307856728ae4f2e0b2f5
30
+ checksum: ae37b329907cead537cf2a87a562ee92120add6c8874bc2e9235e5c537bca692
31
31
  filename: appsignal-i686-linux-all-static.tar.gz
32
32
  dynamic:
33
- checksum: ccb59ee85f8ba8790482db9de29be6936e92c395bb6306f0fecefbc4de50f78d
33
+ checksum: ee5da14c7b5d2cc2dc2ae345d19c33a08c7e4861975e34878c1c295e57b2d8bc
34
34
  filename: appsignal-i686-linux-all-dynamic.tar.gz
35
35
  i686-linux-musl:
36
36
  static:
37
- checksum: 9cfe62cfd0559b900c37b256a2ffc95021007cf3f365152b62af74b55da465a9
37
+ checksum: d2d6dfd5d86b229449c73c74ac6b922eeff981f451dd599cbc8b9f2b7a715931
38
38
  filename: appsignal-i686-linux-musl-all-static.tar.gz
39
39
  x86-linux-musl:
40
40
  static:
41
- checksum: 9cfe62cfd0559b900c37b256a2ffc95021007cf3f365152b62af74b55da465a9
41
+ checksum: d2d6dfd5d86b229449c73c74ac6b922eeff981f451dd599cbc8b9f2b7a715931
42
42
  filename: appsignal-i686-linux-musl-all-static.tar.gz
43
43
  x86_64-linux:
44
44
  static:
45
- checksum: fe74119337cfb8353c64707e4689dc398df1adf2d4bb1bf7750e9a71cca39b3a
45
+ checksum: 6b05c04df7de65be742942926c79e4d322a02dd3b18552b4eb42b420b67df214
46
46
  filename: appsignal-x86_64-linux-all-static.tar.gz
47
47
  dynamic:
48
- checksum: 6816b709ca388421906b178ae592f565ebc433b59cc50223de8c914e44c75d7a
48
+ checksum: de2f7325d2d7d01632abe9eb135f51376ed3769167e0675b7e7c6de9702c057c
49
49
  filename: appsignal-x86_64-linux-all-dynamic.tar.gz
50
50
  x86_64-linux-musl:
51
51
  static:
52
- checksum: 5382a1b0933a2b4d8fae74f89c1af7a21176a1bc100bb245078a1b369b91caca
52
+ checksum: 2a852991c740f93d83dbd3b34daaef45f2ebb02a921200734a6f715790d44968
53
53
  filename: appsignal-x86_64-linux-musl-all-static.tar.gz
54
54
  dynamic:
55
- checksum: e222dd4b09d5042e5315512353f987b1be0302c457285de0bfaeb911d72a8e3e
55
+ checksum: 03fc01d09698b95a5686fc08e4cd1f35913a53413e0ae8ced877c0e7f8ca260e
56
56
  filename: appsignal-x86_64-linux-musl-all-dynamic.tar.gz
57
57
  x86_64-freebsd:
58
58
  static:
59
- checksum: b98fcf6490cb5d1485e96656992ee083f534ec43d67caf015f72b8f4cc6e8fa6
59
+ checksum: 3a26b9a4a1c7e412f6602f4bbae8dd95ad248b41e033b967163bae2f6fac0e96
60
60
  filename: appsignal-x86_64-freebsd-all-static.tar.gz
61
61
  dynamic:
62
- checksum: 28e8cab256c3550e249e0768dc9cb0f352396e972186e1ccf9f2c02461a87345
62
+ checksum: 4eda2bdb88670854abb07ad716e2d46de298dd8549835468c4a778f74c6a7b0e
63
63
  filename: appsignal-x86_64-freebsd-all-dynamic.tar.gz
64
64
  amd64-freebsd:
65
65
  static:
66
- checksum: b98fcf6490cb5d1485e96656992ee083f534ec43d67caf015f72b8f4cc6e8fa6
66
+ checksum: 3a26b9a4a1c7e412f6602f4bbae8dd95ad248b41e033b967163bae2f6fac0e96
67
67
  filename: appsignal-x86_64-freebsd-all-static.tar.gz
68
68
  dynamic:
69
- checksum: 28e8cab256c3550e249e0768dc9cb0f352396e972186e1ccf9f2c02461a87345
69
+ checksum: 4eda2bdb88670854abb07ad716e2d46de298dd8549835468c4a778f74c6a7b0e
70
70
  filename: appsignal-x86_64-freebsd-all-dynamic.tar.gz
@@ -639,6 +639,14 @@ static VALUE running_in_container() {
639
639
  return appsignal_running_in_container() == 1 ? Qtrue : Qfalse;
640
640
  }
641
641
 
642
+ static VALUE set_environment_metadata(VALUE self, VALUE key, VALUE value) {
643
+ appsignal_set_environment_metadata(
644
+ make_appsignal_string(key),
645
+ make_appsignal_string(value)
646
+ );
647
+ return Qnil;
648
+ }
649
+
642
650
  void Init_appsignal_extension(void) {
643
651
  Appsignal = rb_define_module("Appsignal");
644
652
  Extension = rb_define_class_under(Appsignal, "Extension", rb_cObject);
@@ -697,9 +705,10 @@ void Init_appsignal_extension(void) {
697
705
  // Get JSON content of a data
698
706
  rb_define_method(Data, "to_s", data_to_s, 0);
699
707
 
700
- // Event hook installation
708
+ // Other helper methods
701
709
  rb_define_singleton_method(Extension, "install_allocation_event_hook", install_allocation_event_hook, 0);
702
710
  rb_define_singleton_method(Extension, "running_in_container?", running_in_container, 0);
711
+ rb_define_singleton_method(Extension, "set_environment_metadata", set_environment_metadata, 2);
703
712
 
704
713
  // Metrics
705
714
  rb_define_singleton_method(Extension, "set_gauge", set_gauge, 3);
@@ -134,11 +134,17 @@ module Appsignal
134
134
 
135
135
  if config[:enable_allocation_tracking] && !Appsignal::System.jruby?
136
136
  Appsignal::Extension.install_allocation_event_hook
137
+ Appsignal::Environment.report_enabled("allocation_tracking")
137
138
  end
138
139
 
139
- GC::Profiler.enable if config[:enable_gc_instrumentation]
140
+ if config[:enable_gc_instrumentation]
141
+ GC::Profiler.enable
142
+ Appsignal::Environment.report_enabled("gc_instrumentation")
143
+ end
140
144
 
141
145
  Appsignal::Minutely.start if config[:enable_minutely_probes]
146
+
147
+ collect_environment_metadata
142
148
  else
143
149
  logger.info("Not starting, not active for #{config.env}")
144
150
  end
@@ -309,9 +315,23 @@ module Appsignal
309
315
  logger.warn "Unable to start logger with log path '#{path}'."
310
316
  logger.warn error
311
317
  end
318
+
319
+ def collect_environment_metadata
320
+ Appsignal::Environment.report("ruby_version") do
321
+ "#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}"
322
+ end
323
+ Appsignal::Environment.report("ruby_engine") { RUBY_ENGINE }
324
+ if defined?(RUBY_ENGINE_VERSION)
325
+ Appsignal::Environment.report("ruby_engine_version") do
326
+ RUBY_ENGINE_VERSION
327
+ end
328
+ end
329
+ Appsignal::Environment.report_supported_gems
330
+ end
312
331
  end
313
332
  end
314
333
 
334
+ require "appsignal/environment"
315
335
  require "appsignal/system"
316
336
  require "appsignal/utils"
317
337
  require "appsignal/extension"
@@ -3,6 +3,8 @@
3
3
  require "appsignal"
4
4
  require "capistrano/version"
5
5
 
6
+ Appsignal::Environment.report_enabled("capistrano")
7
+
6
8
  if defined?(Capistrano::VERSION) && Gem::Version.new(Capistrano::VERSION) >= Gem::Version.new(3)
7
9
  # Capistrano 3+
8
10
  load File.expand_path("../integrations/capistrano/appsignal.cap", __FILE__)
@@ -18,6 +18,7 @@ module Appsignal
18
18
  :ignore_namespaces => [],
19
19
  :filter_parameters => [],
20
20
  :filter_session_data => [],
21
+ :send_environment_metadata => true,
21
22
  :send_params => true,
22
23
  :request_headers => %w[
23
24
  HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING
@@ -62,6 +63,7 @@ module Appsignal
62
63
  "APPSIGNAL_IGNORE_NAMESPACES" => :ignore_namespaces,
63
64
  "APPSIGNAL_FILTER_PARAMETERS" => :filter_parameters,
64
65
  "APPSIGNAL_FILTER_SESSION_DATA" => :filter_session_data,
66
+ "APPSIGNAL_SEND_ENVIRONMENT_METADATA" => :send_environment_metadata,
65
67
  "APPSIGNAL_SEND_PARAMS" => :send_params,
66
68
  "APPSIGNAL_HTTP_PROXY" => :http_proxy,
67
69
  "APPSIGNAL_ENABLE_ALLOCATION_TRACKING" => :enable_allocation_tracking,
@@ -222,6 +224,7 @@ module Appsignal
222
224
  ENV["_APPSIGNAL_DNS_SERVERS"] = config_hash[:dns_servers].join(",")
223
225
  ENV["_APPSIGNAL_FILES_WORLD_ACCESSIBLE"] = config_hash[:files_world_accessible].to_s
224
226
  ENV["_APPSIGNAL_TRANSACTION_DEBUG_MODE"] = config_hash[:transaction_debug_mode].to_s
227
+ ENV["_APPSIGNAL_SEND_ENVIRONMENT_METADATA"] = config_hash[:send_environment_metadata].to_s
225
228
  ENV["_APP_REVISION"] = config_hash[:revision].to_s
226
229
  end
227
230
 
@@ -337,8 +340,9 @@ module Appsignal
337
340
  APPSIGNAL_SKIP_SESSION_DATA APPSIGNAL_ENABLE_FRONTEND_ERROR_CATCHING
338
341
  APPSIGNAL_ENABLE_ALLOCATION_TRACKING APPSIGNAL_ENABLE_GC_INSTRUMENTATION
339
342
  APPSIGNAL_RUNNING_IN_CONTAINER APPSIGNAL_ENABLE_HOST_METRICS
340
- APPSIGNAL_SEND_PARAMS APPSIGNAL_ENABLE_MINUTELY_PROBES
341
- APPSIGNAL_FILES_WORLD_ACCESSIBLE APPSIGNAL_TRANSACTION_DEBUG_MODE].each do |var|
343
+ APPSIGNAL_SEND_ENVIRONMENT_METADATA APPSIGNAL_SEND_PARAMS
344
+ APPSIGNAL_ENABLE_MINUTELY_PROBES APPSIGNAL_FILES_WORLD_ACCESSIBLE
345
+ APPSIGNAL_TRANSACTION_DEBUG_MODE].each do |var|
342
346
  env_var = ENV[var]
343
347
  next unless env_var
344
348
  config[ENV_TO_KEY_MAPPING[var]] = env_var.casecmp("true").zero?
@@ -0,0 +1,126 @@
1
+ module Appsignal
2
+ # @api private
3
+ class Environment
4
+ # Add environment metadata.
5
+ #
6
+ # The key and value of the environment metadata must be a String, even if
7
+ # it's actually of another type.
8
+ #
9
+ # The value of the environment metadata is given as a block that captures
10
+ # errors that might be raised while fetching the value. It will not
11
+ # re-raise errors, but instead log them using the {Appsignal.logger}. This
12
+ # ensures AppSignal will not cause an error in the application when
13
+ # collecting this metadata.
14
+ #
15
+ # @example Reporting a key and value
16
+ # Appsignal::Environment.report("ruby_version") { RUBY_VERSION }
17
+ #
18
+ # @example When a value is nil
19
+ # Appsignal::Environment.report("ruby_version") { nil }
20
+ # # Key and value do not get reported. A warning gets logged instead.
21
+ #
22
+ # @example When an error occurs
23
+ # Appsignal::Environment.report("ruby_version") { raise "uh oh" }
24
+ # # Error does not get reraised. A warning gets logged instead.
25
+ #
26
+ # @param key [String] The name of the key of the environment metadata value.
27
+ # @yieldreturn [String] The value of the key of the environment metadata.
28
+ # @return [void]
29
+ def self.report(key)
30
+ key =
31
+ case key
32
+ when String
33
+ key
34
+ else
35
+ Appsignal.logger.error "Unable to report on environment metadata: " \
36
+ "Unsupported value type for #{key.inspect}"
37
+ return
38
+ end
39
+
40
+ yielded_value =
41
+ begin
42
+ yield
43
+ rescue => e
44
+ Appsignal.logger.error \
45
+ "Unable to report on environment metadata #{key.inspect}:\n" \
46
+ "#{e.class}: #{e}"
47
+ return
48
+ end
49
+
50
+ value =
51
+ case yielded_value
52
+ when TrueClass, FalseClass
53
+ yielded_value.to_s
54
+ when String
55
+ yielded_value
56
+ else
57
+ Appsignal.logger.error "Unable to report on environment metadata " \
58
+ "#{key.inspect}: Unsupported value type for " \
59
+ "#{yielded_value.inspect}"
60
+ return
61
+ end
62
+
63
+ Appsignal::Extension.set_environment_metadata(key, value)
64
+ rescue => e
65
+ Appsignal.logger.error "Unable to report on environment metadata:\n" \
66
+ "#{e.class}: #{e}"
67
+ end
68
+
69
+ # @see report_supported_gems
70
+ SUPPORTED_GEMS = %w[
71
+ actioncable
72
+ activejob
73
+ capistrano
74
+ celluloid
75
+ data_mapper
76
+ delayed_job
77
+ mongo_ruby_driver
78
+ padrino
79
+ passenger
80
+ puma
81
+ que
82
+ rack
83
+ rails
84
+ rake
85
+ redis
86
+ resque
87
+ sequel
88
+ shoryuken
89
+ sidekiq
90
+ sinatra
91
+ unicorn
92
+ webmachine
93
+ ].freeze
94
+
95
+ # Report on the list of AppSignal supported gems
96
+ #
97
+ # This list is used to report if which AppSignal supported gems are present
98
+ # in this app and what version. This data will help AppSignal improve its
99
+ # support by knowing what gems and versions of gems it still needs to
100
+ # support or can drop support for.
101
+ #
102
+ # It will ask Bundler to report name and version information from the gems
103
+ # that are present in the app bundle.
104
+ def self.report_supported_gems
105
+ return unless defined?(Bundler) # Do nothing if Bundler is not present
106
+
107
+ bundle_gem_specs = ::Bundler.rubygems.all_specs
108
+ SUPPORTED_GEMS.each do |gem_name|
109
+ gem_spec = bundle_gem_specs.find { |spec| spec.name == gem_name }
110
+ next unless gem_spec
111
+
112
+ report("ruby_#{gem_name}_version") { gem_spec.version.to_s }
113
+ end
114
+ rescue => e
115
+ Appsignal.logger.error "Unable to report supported gems:\n" \
116
+ "#{e.class}: #{e}"
117
+ end
118
+
119
+ def self.report_enabled(feature)
120
+ Appsignal::Environment.report("ruby_#{feature}_enabled") { true }
121
+ rescue => e
122
+ Appsignal.logger.error "Unable to report integration enabled:\n" \
123
+ "#{e.class}: #{e}"
124
+ end
125
+ end
126
+ end
@@ -60,6 +60,9 @@ module Appsignal
60
60
  [:appsignal_string],
61
61
  :appsignal_string
62
62
  attach_function :appsignal_running_in_container, [], :bool
63
+ attach_function :appsignal_set_environment_metadata,
64
+ [:appsignal_string, :appsignal_string],
65
+ :void
63
66
 
64
67
  # Metrics methods
65
68
  attach_function :appsignal_set_gauge,
@@ -224,6 +227,13 @@ module Appsignal
224
227
  appsignal_running_in_container
225
228
  end
226
229
 
230
+ def set_environment_metadata(key, value)
231
+ appsignal_set_environment_metadata(
232
+ make_appsignal_string(key),
233
+ make_appsignal_string(value)
234
+ )
235
+ end
236
+
227
237
  def set_gauge(key, value, tags)
228
238
  appsignal_set_gauge(make_appsignal_string(key), value, tags.pointer)
229
239
  end
@@ -25,6 +25,8 @@ module Appsignal
25
25
  end
26
26
  end
27
27
  end
28
+
29
+ Appsignal::Environment.report_enabled("net_http")
28
30
  end
29
31
  end
30
32
  end
@@ -26,6 +26,8 @@ module Appsignal
26
26
  end
27
27
  end
28
28
  end
29
+
30
+ Appsignal::Environment.report_enabled("redis")
29
31
  end
30
32
  end
31
33
  end
@@ -56,6 +56,8 @@ module Appsignal
56
56
 
57
57
  # ... and automatically add it to future instances.
58
58
  ::Sequel::Database.extension(:appsignal_integration)
59
+
60
+ Appsignal::Environment.report_enabled("sequel")
59
61
  end
60
62
  end
61
63
  end
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ if defined?(Appsignal)
4
+ Appsignal::Environment.report_enabled("object_instrumentation")
5
+ end
6
+
3
7
  class Object
4
8
  def self.appsignal_instrument_class_method(method_name, options = {})
5
9
  singleton_class.send \
@@ -34,6 +34,8 @@ module Appsignal
34
34
  end
35
35
  end
36
36
  end
37
+
38
+ Appsignal::Environment.report("ruby_active_job_resque_enabled") { true }
37
39
  end
38
40
  end
39
41
  end
@@ -228,12 +228,27 @@ module Appsignal
228
228
  Appsignal.logger.warn("Queue start value #{start} is too big")
229
229
  end
230
230
 
231
+ # Set the queue time based on the HTTP header or `:queue_start` env key
232
+ # value.
233
+ #
234
+ # This method will first try to read the queue time from the HTTP headers
235
+ # `X-Request-Start` or `X-Queue-Start`. Which are parsed by Rack as
236
+ # `HTTP_X_QUEUE_START` and `HTTP_X_REQUEST_START`.
237
+ # The header value is parsed by AppSignal as either milliseconds or
238
+ # microseconds.
239
+ #
240
+ # If no headers are found, or the value could not be parsed, it falls back
241
+ # on the `:queue_start` env key on this Transaction's {request} environment
242
+ # (called like `request.env[:queue_start]`). This value is parsed by
243
+ # AppSignal as seconds.
244
+ #
245
+ # @see https://docs.appsignal.com/ruby/instrumentation/request-queue-time.html
246
+ # @return [void]
231
247
  def set_http_or_background_queue_start
232
- if namespace == HTTP_REQUEST
233
- set_queue_start(http_queue_start)
234
- elsif namespace == BACKGROUND_JOB
235
- set_queue_start(background_queue_start)
236
- end
248
+ start = http_queue_start || background_queue_start
249
+ return unless start
250
+
251
+ set_queue_start(start)
237
252
  end
238
253
 
239
254
  def set_metadata(key, value)
@@ -346,14 +361,14 @@ module Appsignal
346
361
  #
347
362
  # @return [nil] if no {#environment} is present.
348
363
  # @return [nil] if there is no `:queue_start` in the {#environment}.
349
- # @return [Integer]
364
+ # @return [Integer] `:queue_start` time (in seconds) converted to milliseconds
350
365
  def background_queue_start
351
366
  env = environment
352
367
  return unless env
353
368
  queue_start = env[:queue_start]
354
369
  return unless queue_start
355
370
 
356
- (queue_start.to_f * 1000.0).to_i
371
+ (queue_start.to_f * 1000.0).to_i # Convert seconds to milliseconds
357
372
  end
358
373
 
359
374
  # Returns HTTP queue start time in milliseconds.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Appsignal
4
- VERSION = "2.10.9".freeze
4
+ VERSION = "2.11.0.alpha.1".freeze
5
5
  end
@@ -148,6 +148,7 @@ describe Appsignal::Config do
148
148
  :instrument_redis => true,
149
149
  :instrument_sequel => true,
150
150
  :skip_session_data => false,
151
+ :send_environment_metadata => true,
151
152
  :send_params => true,
152
153
  :endpoint => "https://push.appsignal.com",
153
154
  :push_api_key => "abc",
@@ -411,7 +412,8 @@ describe Appsignal::Config do
411
412
  :instrument_sequel => false,
412
413
  :files_world_accessible => false,
413
414
  :request_headers => %w[accept accept-charset],
414
- :revision => "v2.5.1"
415
+ :revision => "v2.5.1",
416
+ :send_environment_metadata => false
415
417
  }
416
418
  end
417
419
  before do
@@ -428,6 +430,7 @@ describe Appsignal::Config do
428
430
  ENV["APPSIGNAL_INSTRUMENT_SEQUEL"] = "false"
429
431
  ENV["APPSIGNAL_FILES_WORLD_ACCESSIBLE"] = "false"
430
432
  ENV["APPSIGNAL_REQUEST_HEADERS"] = "accept,accept-charset"
433
+ ENV["APPSIGNAL_SEND_ENVIRONMENT_METADATA"] = "false"
431
434
  ENV["APP_REVISION"] = "v2.5.1"
432
435
  end
433
436
 
@@ -527,6 +530,7 @@ describe Appsignal::Config do
527
530
  config[:running_in_container] = false
528
531
  config[:dns_servers] = ["8.8.8.8", "8.8.4.4"]
529
532
  config[:transaction_debug_mode] = true
533
+ config[:send_environment_metadata] = false
530
534
  config[:revision] = "v2.5.1"
531
535
  config.write_to_environment
532
536
  end
@@ -555,6 +559,7 @@ describe Appsignal::Config do
555
559
  expect(ENV["_APPSIGNAL_DNS_SERVERS"]).to eq "8.8.8.8,8.8.4.4"
556
560
  expect(ENV["_APPSIGNAL_FILES_WORLD_ACCESSIBLE"]).to eq "true"
557
561
  expect(ENV["_APPSIGNAL_TRANSACTION_DEBUG_MODE"]).to eq "true"
562
+ expect(ENV["_APPSIGNAL_SEND_ENVIRONMENT_METADATA"]).to eq "false"
558
563
  expect(ENV["_APP_REVISION"]).to eq "v2.5.1"
559
564
  expect(ENV).to_not have_key("_APPSIGNAL_WORKING_DIR_PATH")
560
565
  expect(ENV).to_not have_key("_APPSIGNAL_WORKING_DIRECTORY_PATH")
@@ -0,0 +1,167 @@
1
+ describe Appsignal::Environment do
2
+ include EnvironmentMetadataHelper
3
+
4
+ before(:context) { start_agent }
5
+ before { capture_environment_metadata_report_calls }
6
+
7
+ def report(key, &value_block)
8
+ described_class.report(key, &value_block)
9
+ end
10
+
11
+ describe ".report" do
12
+ it "sends environment metadata to the extension" do
13
+ logs =
14
+ capture_logs do
15
+ report("_test_ruby_version") { "1.0.0" }
16
+ expect_environment_metadata("_test_ruby_version", "1.0.0")
17
+ end
18
+ expect(logs).to be_empty
19
+ end
20
+
21
+ context "when the key is a non String type" do
22
+ it "does not set the value" do
23
+ logs =
24
+ capture_logs do
25
+ report(:_test_symbol) { "1.0.0" }
26
+ expect_not_environment_metadata(:_test_symbol)
27
+ expect_not_environment_metadata("_test_symbol")
28
+ end
29
+ expect(logs).to contains_log(
30
+ :error,
31
+ "Unable to report on environment metadata: Unsupported value type for :_test_symbol"
32
+ )
33
+ end
34
+ end
35
+
36
+ context "when the key is nil" do
37
+ it "does not set the value" do
38
+ logs =
39
+ capture_logs do
40
+ report(nil) { "1" }
41
+ expect_not_environment_metadata(nil)
42
+ end
43
+ expect(logs).to contains_log(
44
+ :error,
45
+ "Unable to report on environment metadata: Unsupported value type for nil"
46
+ )
47
+ end
48
+ end
49
+
50
+ context "when the value is true or false" do
51
+ it "reports true or false as Strings" do
52
+ logs =
53
+ capture_logs do
54
+ report("_test_true") { true }
55
+ report("_test_false") { false }
56
+ expect_environment_metadata("_test_true", "true")
57
+ expect_environment_metadata("_test_false", "false")
58
+ end
59
+ expect(logs).to be_empty
60
+ end
61
+ end
62
+
63
+ context "when the value is nil" do
64
+ it "does not set the value" do
65
+ logs =
66
+ capture_logs do
67
+ report("_test_ruby_version") { nil }
68
+ expect_not_environment_metadata("_test_ruby_version")
69
+ end
70
+ expect(logs).to contains_log(
71
+ :error,
72
+ "Unable to report on environment metadata \"_test_ruby_version\": " \
73
+ "Unsupported value type for nil"
74
+ )
75
+ end
76
+ end
77
+
78
+ context "when the value block raises an error" do
79
+ it "does not re-raise the error and writes it to the log" do
80
+ logs =
81
+ capture_logs do
82
+ report("_test_error") { raise "uh oh" }
83
+ expect_not_environment_metadata("_test_error")
84
+ end
85
+ expect(logs).to contains_log(
86
+ :error,
87
+ "Unable to report on environment metadata \"_test_error\":\n" \
88
+ "RuntimeError: uh oh"
89
+ )
90
+ end
91
+ end
92
+
93
+ context "when something unforseen errors" do
94
+ it "does not re-raise the error and writes it to the log" do
95
+ klass = Class.new do
96
+ def inspect
97
+ raise "inspect error"
98
+ end
99
+ end
100
+
101
+ logs =
102
+ capture_logs do
103
+ report(klass.new) { raise "value error" }
104
+ expect(Appsignal::Extension).to_not have_received(:set_environment_metadata)
105
+ end
106
+ expect(logs).to contains_log(
107
+ :error,
108
+ "Unable to report on environment metadata:\n" \
109
+ "RuntimeError: inspect error"
110
+ )
111
+ end
112
+ end
113
+ end
114
+
115
+ describe ".report_supported_gems" do
116
+ it "reports about all AppSignal supported gems in the bundle" do
117
+ logs = capture_logs { described_class.report_supported_gems }
118
+
119
+ expect(logs).to be_empty
120
+
121
+ bundle_gem_specs = ::Bundler.rubygems.all_specs
122
+ rack_spec = bundle_gem_specs.find { |s| s.name == "rack" }
123
+ rake_spec = bundle_gem_specs.find { |s| s.name == "rake" }
124
+ expect_environment_metadata("ruby_rack_version", rack_spec.version.to_s)
125
+ expect_environment_metadata("ruby_rake_version", rake_spec.version.to_s)
126
+ expect(rack_spec.version.to_s).to_not be_empty
127
+ expect(rake_spec.version.to_s).to_not be_empty
128
+ end
129
+
130
+ context "when something unforseen errors" do
131
+ it "does not re-raise the error and writes it to the log" do
132
+ expect(Bundler).to receive(:rubygems).and_raise(RuntimeError, "bundler error")
133
+
134
+ logs = capture_logs { described_class.report_supported_gems }
135
+ expect(logs).to contains_log(
136
+ :error,
137
+ "Unable to report supported gems:\nRuntimeError: bundler error"
138
+ )
139
+ end
140
+ end
141
+ end
142
+
143
+ describe ".report_enabled" do
144
+ it "reports a feature being enabled" do
145
+ logs = capture_logs { described_class.report_enabled("a_test") }
146
+
147
+ expect(logs).to be_empty
148
+ expect_environment_metadata("ruby_a_test_enabled", "true")
149
+ end
150
+
151
+ context "when something unforseen errors" do
152
+ it "does not re-raise the error and writes it to the log" do
153
+ klass = Class.new do
154
+ def to_s
155
+ raise "to_s error"
156
+ end
157
+ end
158
+
159
+ logs = capture_logs { described_class.report_enabled(klass.new) }
160
+ expect(logs).to contains_log(
161
+ :error,
162
+ "Unable to report integration enabled:\nRuntimeError: to_s error"
163
+ )
164
+ end
165
+ end
166
+ end
167
+ end
@@ -500,23 +500,40 @@ describe Appsignal::Transaction do
500
500
  end
501
501
 
502
502
  describe "#set_http_or_background_queue_start" do
503
- context "for a http transaction" do
504
- let(:namespace) { Appsignal::Transaction::HTTP_REQUEST }
505
- let(:env) { { "HTTP_X_REQUEST_START" => (fixed_time * 1000).to_s } }
503
+ let(:header_factor) { 1_000 }
504
+ let(:env_queue_start) { fixed_time + 20 } # in seconds
506
505
 
507
- it "should set the queue start on the transaction" do
508
- expect(transaction).to receive(:set_queue_start).with(13_897_836_000)
506
+ context "when a queue time is found in a request header" do
507
+ let(:header_time) { ((fixed_time + 10) * header_factor).to_i } # in milliseconds
508
+ let(:env) { { "HTTP_X_REQUEST_START" => "t=#{header_time}" } }
509
+
510
+ it "sets the http header value in milliseconds on the transaction" do
511
+ expect(transaction).to receive(:set_queue_start).with(1_389_783_610_000)
509
512
 
510
513
  transaction.set_http_or_background_queue_start
511
514
  end
515
+
516
+ context "when a :queue_start key is found in the transaction environment" do
517
+ let(:env) do
518
+ {
519
+ "HTTP_X_REQUEST_START" => "t=#{header_time}",
520
+ :queue_start => env_queue_start
521
+ }
522
+ end
523
+
524
+ it "sets the http header value in milliseconds on the transaction" do
525
+ expect(transaction).to receive(:set_queue_start).with(1_389_783_610_000)
526
+
527
+ transaction.set_http_or_background_queue_start
528
+ end
529
+ end
512
530
  end
513
531
 
514
- context "for a background transaction" do
515
- let(:namespace) { Appsignal::Transaction::BACKGROUND_JOB }
516
- let(:env) { { :queue_start => fixed_time } }
532
+ context "when a :queue_start key is found in the transaction environment" do
533
+ let(:env) { { :queue_start => env_queue_start } } # in seconds
517
534
 
518
- it "should set the queue start on the transaction" do
519
- expect(transaction).to receive(:set_queue_start).with(1_389_783_600_000)
535
+ it "sets the :queue_start value in milliseconds on the transaction" do
536
+ expect(transaction).to receive(:set_queue_start).with(1_389_783_620_000)
520
537
 
521
538
  transaction.set_http_or_background_queue_start
522
539
  end
@@ -910,7 +927,7 @@ describe Appsignal::Transaction do
910
927
  context "when queue start is set" do
911
928
  let(:env) { background_env_with_data }
912
929
 
913
- it { is_expected.to eq 1_389_783_590_000 }
930
+ it { is_expected.to eq 1_389_783_600_000 }
914
931
  end
915
932
  end
916
933
 
@@ -949,7 +966,7 @@ describe Appsignal::Transaction do
949
966
  it { is_expected.to be_nil }
950
967
  end
951
968
 
952
- context "with some cruft" do
969
+ context "with unparsable content at the end" do
953
970
  let(:env) { { "HTTP_X_REQUEST_START" => "t=#{slightly_earlier_time_value}aaaa" } }
954
971
 
955
972
  it { is_expected.to eq 1_389_783_599_600 }
@@ -969,7 +986,7 @@ describe Appsignal::Transaction do
969
986
  end
970
987
  end
971
988
 
972
- context "time in miliseconds" do
989
+ context "time in milliseconds" do
973
990
  let(:factor) { 1_000 }
974
991
 
975
992
  it_should_behave_like "http queue start"
@@ -1,4 +1,6 @@
1
1
  describe Appsignal do
2
+ include EnvironmentMetadataHelper
3
+
2
4
  before do
3
5
  # Make sure we have a clean state because we want to test
4
6
  # initialization here.
@@ -80,18 +82,22 @@ describe Appsignal do
80
82
  allow(GC::Profiler).to receive(:enable)
81
83
  Appsignal.config.config_hash[:enable_allocation_tracking] = true
82
84
  Appsignal.config.config_hash[:enable_gc_instrumentation] = true
85
+ capture_environment_metadata_report_calls
83
86
  end
84
87
 
85
88
  it "should enable Ruby's GC::Profiler" do
86
89
  expect(GC::Profiler).to receive(:enable)
87
90
  Appsignal.start
91
+ expect_environment_metadata("ruby_gc_instrumentation_enabled", "true")
88
92
  end
89
93
 
90
94
  unless Appsignal::System.jruby?
95
+
91
96
  it "installs the allocation event hook" do
92
97
  expect(Appsignal::Extension).to receive(:install_allocation_event_hook)
93
98
  .and_call_original
94
99
  Appsignal.start
100
+ expect_environment_metadata("ruby_allocation_tracking_enabled", "true")
95
101
  end
96
102
  end
97
103
  end
@@ -100,6 +106,7 @@ describe Appsignal do
100
106
  before do
101
107
  Appsignal.config.config_hash[:enable_allocation_tracking] = false
102
108
  Appsignal.config.config_hash[:enable_gc_instrumentation] = false
109
+ capture_environment_metadata_report_calls
103
110
  end
104
111
 
105
112
  it "should not enable Ruby's GC::Profiler" do
@@ -110,11 +117,13 @@ describe Appsignal do
110
117
  it "should not install the allocation event hook" do
111
118
  expect(Appsignal::Minutely).not_to receive(:install_allocation_event_hook)
112
119
  Appsignal.start
120
+ expect_not_environment_metadata("ruby_allocation_tracking_enabled")
113
121
  end
114
122
 
115
123
  it "should not add the gc probe to minutely" do
116
124
  expect(Appsignal::Minutely).not_to receive(:register_garbage_collection_probe)
117
125
  Appsignal.start
126
+ expect_not_environment_metadata("ruby_gc_instrumentation_enabled")
118
127
  end
119
128
  end
120
129
 
@@ -139,6 +148,19 @@ describe Appsignal do
139
148
  Appsignal.start
140
149
  end
141
150
  end
151
+
152
+ describe "environment metadata" do
153
+ before { capture_environment_metadata_report_calls }
154
+
155
+ it "collects and reports environment metadata" do
156
+ Appsignal.start
157
+ expect_environment_metadata("ruby_version", "#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}")
158
+ expect_environment_metadata("ruby_engine", RUBY_ENGINE)
159
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.3.0")
160
+ expect_environment_metadata("ruby_engine_version", RUBY_ENGINE_VERSION)
161
+ end
162
+ end
163
+ end
142
164
  end
143
165
 
144
166
  context "with debug logging" do
@@ -27,7 +27,7 @@ module EnvHelpers
27
27
  :priority => 1,
28
28
  :attempts => 0,
29
29
  :queue => "default",
30
- :queue_start => fixed_time - 10.0
30
+ :queue_start => fixed_time
31
31
  }.merge(args)
32
32
  end
33
33
  end
@@ -0,0 +1,16 @@
1
+ module EnvironmentMetadataHelper
2
+ def capture_environment_metadata_report_calls
3
+ allow(Appsignal::Extension).to receive(:set_environment_metadata)
4
+ .and_call_original
5
+ end
6
+
7
+ def expect_environment_metadata(key, value)
8
+ expect(Appsignal::Extension).to have_received(:set_environment_metadata)
9
+ .with(key, value)
10
+ end
11
+
12
+ def expect_not_environment_metadata(key)
13
+ expect(Appsignal::Extension).to_not have_received(:set_environment_metadata)
14
+ .with(key, anything)
15
+ end
16
+ 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: 2.10.9
4
+ version: 2.11.0.alpha.1
5
5
  platform: java
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: 2020-06-22 00:00:00.000000000 Z
13
+ date: 2020-06-29 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rack
@@ -204,6 +204,7 @@ files:
204
204
  - lib/appsignal/cli/notify_of_deploy.rb
205
205
  - lib/appsignal/config.rb
206
206
  - lib/appsignal/demo.rb
207
+ - lib/appsignal/environment.rb
207
208
  - lib/appsignal/event_formatter.rb
208
209
  - lib/appsignal/event_formatter/action_view/render_formatter.rb
209
210
  - lib/appsignal/event_formatter/active_record/instantiation_formatter.rb
@@ -288,6 +289,7 @@ files:
288
289
  - spec/lib/appsignal/cli_spec.rb
289
290
  - spec/lib/appsignal/config_spec.rb
290
291
  - spec/lib/appsignal/demo_spec.rb
292
+ - spec/lib/appsignal/environment_spec.rb
291
293
  - spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb
292
294
  - spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb
293
295
  - spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb
@@ -362,6 +364,7 @@ files:
362
364
  - spec/support/helpers/dependency_helper.rb
363
365
  - spec/support/helpers/directory_helper.rb
364
366
  - spec/support/helpers/env_helpers.rb
367
+ - spec/support/helpers/environment_metdata_helper.rb
365
368
  - spec/support/helpers/example_exception.rb
366
369
  - spec/support/helpers/example_standard_error.rb
367
370
  - spec/support/helpers/log_helpers.rb
@@ -405,9 +408,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
405
408
  version: '1.9'
406
409
  required_rubygems_version: !ruby/object:Gem::Requirement
407
410
  requirements:
408
- - - ">="
411
+ - - ">"
409
412
  - !ruby/object:Gem::Version
410
- version: '0'
413
+ version: 1.3.1
411
414
  requirements: []
412
415
  rubygems_version: 3.1.4
413
416
  signing_key:
@@ -428,6 +431,7 @@ test_files:
428
431
  - spec/lib/appsignal/cli_spec.rb
429
432
  - spec/lib/appsignal/config_spec.rb
430
433
  - spec/lib/appsignal/demo_spec.rb
434
+ - spec/lib/appsignal/environment_spec.rb
431
435
  - spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb
432
436
  - spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb
433
437
  - spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb
@@ -502,6 +506,7 @@ test_files:
502
506
  - spec/support/helpers/dependency_helper.rb
503
507
  - spec/support/helpers/directory_helper.rb
504
508
  - spec/support/helpers/env_helpers.rb
509
+ - spec/support/helpers/environment_metdata_helper.rb
505
510
  - spec/support/helpers/example_exception.rb
506
511
  - spec/support/helpers/example_standard_error.rb
507
512
  - spec/support/helpers/log_helpers.rb