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.
@@ -143,7 +143,7 @@ module Appsignal
143
143
  def transmit_report_to_appsignal
144
144
  puts " Transmitting diagnostics report"
145
145
  transmitter = Transmitter.new(
146
- DIAGNOSE_ENDPOINT,
146
+ ENV.fetch("APPSIGNAL_DIAGNOSE_ENDPOINT", DIAGNOSE_ENDPOINT),
147
147
  Appsignal.config
148
148
  )
149
149
  response = transmitter.transmit(:diagnose => data)
@@ -171,11 +171,18 @@ module Appsignal
171
171
  puts_value label, value
172
172
  end
173
173
 
174
+ # Prints values as given. Does no formatting on the value
174
175
  def puts_value(label, value, options = {})
175
176
  options[:level] ||= 1
176
177
  puts "#{" " * options[:level]}#{label}: #{value}"
177
178
  end
178
179
 
180
+ # Print values as inspected.
181
+ # Surrounds Strings in quotes.
182
+ def puts_format(label, value, options = {})
183
+ puts_value label, value.inspect, options
184
+ end
185
+
179
186
  def configure_appsignal(options)
180
187
  current_path = Dir.pwd
181
188
  initial_config = {}
@@ -327,9 +334,18 @@ module Appsignal
327
334
  data_section :library do
328
335
  save :language, "ruby"
329
336
  puts_value "Language", "Ruby"
330
- puts_and_save :package_version, "Gem version", Appsignal::VERSION
331
- puts_and_save :agent_version, "Agent version", Appsignal::Extension.agent_version
332
- puts_and_save :extension_loaded, "Extension loaded", Appsignal.extension_loaded
337
+
338
+ package_version = Appsignal::VERSION
339
+ save :package_version, package_version
340
+ puts_format "Gem version", package_version
341
+
342
+ agent_version = Appsignal::Extension.agent_version
343
+ save :agent_version, agent_version
344
+ puts_format "Agent version", agent_version
345
+
346
+ extension_loaded = Appsignal.extension_loaded
347
+ save :extension_loaded, extension_loaded
348
+ puts_format "Extension loaded", extension_loaded
333
349
  end
334
350
  end
335
351
 
@@ -381,29 +397,29 @@ module Appsignal
381
397
  def print_installation_language_report(report)
382
398
  report = report.fetch("language", {})
383
399
  puts " Language details"
384
- puts " Implementation: #{report["implementation"]}"
385
- puts " Ruby version: #{report["version"]}"
400
+ puts_format "Implementation", report["implementation"], :level => 2
401
+ puts_format "Ruby version", report["version"], :level => 2
386
402
  end
387
403
 
388
404
  def print_installation_download_report(report)
389
405
  report = report.fetch("download", {})
390
406
  puts " Download details"
391
- puts " Download URL: #{report["download_url"]}"
392
- puts " Checksum: #{report["checksum"]}"
407
+ puts_format "Download URL", report["download_url"], :level => 2
408
+ puts_format "Checksum", report["checksum"], :level => 2
393
409
  end
394
410
 
395
411
  def print_installation_build_report(report)
396
412
  report = report.fetch("build", {})
397
413
  puts " Build details"
398
- puts " Install time: #{report["time"]}"
399
- puts " Architecture: #{report["architecture"]}"
400
- puts " Target: #{report["target"]}"
401
- puts " Musl override: #{report["musl_override"]}"
402
- puts " Linux ARM override: #{report["linux_arm_override"]}"
403
- puts " Library type: #{report["library_type"]}"
404
- puts " Source: #{report["source"]}" if report["source"] != "remote"
405
- puts " Dependencies: #{report["dependencies"]}"
406
- puts " Flags: #{report["flags"]}"
414
+ puts_format "Install time", report["time"].to_s, :level => 2
415
+ puts_format "Architecture", report["architecture"], :level => 2
416
+ puts_format "Target", report["target"], :level => 2
417
+ puts_format "Musl override", report["musl_override"], :level => 2
418
+ puts_format "Linux ARM override", report["linux_arm_override"], :level => 2
419
+ puts_format "Library type", report["library_type"], :level => 2
420
+ puts_format "Source", report["source"], :level => 2 if report["source"] != "remote"
421
+ puts_format "Dependencies", report["dependencies"], :level => 2
422
+ puts_format "Flags", report["flags"], :level => 2
407
423
  end
408
424
 
409
425
  def print_installation_host_report(report)
@@ -417,24 +433,31 @@ module Appsignal
417
433
  rbconfig = RbConfig::CONFIG
418
434
  puts "Host information"
419
435
  data_section :host do
420
- puts_and_save :architecture, "Architecture", Appsignal::System.agent_architecture
436
+ agent_architecture = Appsignal::System.agent_architecture
437
+ save :architecture, agent_architecture
438
+ puts_format "Architecture", agent_architecture
421
439
 
422
- os_label = os = rbconfig["host_os"]
423
- os_label = "#{os} (Microsoft Windows is not supported.)" if Gem.win_platform?
440
+ os = rbconfig["host_os"]
441
+ os_label = os.inspect
442
+ os_label = "#{os_label} (Microsoft Windows is not supported.)" if Gem.win_platform?
424
443
  save :os, os
425
444
  puts_value "Operating System", os_label
426
445
 
427
- puts_and_save :language_version, "Ruby version",
428
- "#{rbconfig["ruby_version"]}-p#{rbconfig["PATCHLEVEL"]}"
446
+ language_version = "#{rbconfig["ruby_version"]}-p#{rbconfig["PATCHLEVEL"]}"
447
+ save :language_version, language_version
448
+ puts_format "Ruby version", language_version
429
449
 
430
- puts_value "Heroku", "true" if Appsignal::System.heroku?
431
- save :heroku, Appsignal::System.heroku?
450
+ heroku = Appsignal::System.heroku?
451
+ save :heroku, heroku
452
+ puts_format "Heroku", true if Appsignal::System.heroku?
432
453
 
433
- save :root, Process.uid.zero?
434
- puts_value "Root user",
435
- Process.uid.zero? ? "true (not recommended)" : "false"
436
- puts_and_save :running_in_container, "Running in container",
437
- Appsignal::Extension.running_in_container?
454
+ root = Process.uid.zero?
455
+ save :root, root
456
+ puts_value "Root user", root ? "true (not recommended)" : "false"
457
+
458
+ running_in_container = Appsignal::Extension.running_in_container?
459
+ save :running_in_container, running_in_container
460
+ puts_format "Running in container", running_in_container
438
461
  end
439
462
  end
440
463
 
@@ -451,7 +474,6 @@ module Appsignal
451
474
  :env => config.env_config
452
475
  }
453
476
  }
454
- print_environment(config)
455
477
  print_config_options(config)
456
478
  end
457
479
 
@@ -460,7 +482,7 @@ module Appsignal
460
482
  option = :env
461
483
  option_sources = sources_for_option(option)
462
484
  sources_label = config_sources_label(option, option_sources)
463
- print " Environment: #{format_config_option(env)}"
485
+ print " environment: #{format_config_option(env)}"
464
486
 
465
487
  if env == ""
466
488
  message = " Warning: No environment set, no config loaded!\n" \
@@ -474,10 +496,22 @@ module Appsignal
474
496
  end
475
497
 
476
498
  def print_config_options(config)
477
- config.config_hash.each do |key, value|
499
+ # We add the nullified "environment" key to print it ordered
500
+ # instead of adding it at the top of the list.
501
+ ordered_config_options = config
502
+ .config_hash
503
+ .merge(:environment => nil)
504
+ .sort
505
+
506
+ ordered_config_options.each do |key, value|
478
507
  option_sources = sources_for_option(key)
479
508
  sources_label = config_sources_label(key, option_sources)
480
- puts " #{key}: #{format_config_option(value)}#{sources_label}"
509
+
510
+ if key == :environment
511
+ print_environment(config)
512
+ else
513
+ puts " #{key}: #{format_config_option(value)}#{sources_label}"
514
+ end
481
515
  end
482
516
 
483
517
  puts "\nRead more about how the diagnose config output is rendered\n"\
@@ -543,7 +577,7 @@ module Appsignal
543
577
  when "401"
544
578
  ["invalid", :red]
545
579
  else
546
- ["Failed with status #{status}\n#{error.inspect}", :red]
580
+ ["Failed to validate: status #{status}\n#{error.inspect}", :red]
547
581
  end
548
582
  data[:validation][:push_api_key] = result
549
583
  puts_value "Validating Push API key", colorize(result, color)
@@ -563,6 +597,7 @@ module Appsignal
563
597
 
564
598
  unless path[:exists]
565
599
  puts_value "Exists?", path[:exists], :level => 2
600
+ print_empty_line
566
601
  return
567
602
  end
568
603
 
@@ -11,15 +11,26 @@ module Appsignal
11
11
  include Appsignal::Utils::DeprecationMessage
12
12
 
13
13
  DEFAULT_CONFIG = {
14
+ :ca_file_path => File.expand_path(File.join("../../../resources/cacert.pem"), __FILE__),
14
15
  :debug => false,
15
- :log => "file",
16
+ :dns_servers => [],
17
+ :enable_allocation_tracking => true,
18
+ :enable_gc_instrumentation => false,
19
+ :enable_host_metrics => true,
20
+ :enable_minutely_probes => true,
21
+ :enable_statsd => true,
22
+ :endpoint => "https://push.appsignal.com",
23
+ :files_world_accessible => true,
24
+ :filter_parameters => [],
25
+ :filter_session_data => [],
16
26
  :ignore_actions => [],
17
27
  :ignore_errors => [],
18
28
  :ignore_namespaces => [],
19
- :filter_parameters => [],
20
- :filter_session_data => [],
21
- :send_environment_metadata => true,
22
- :send_params => true,
29
+ :instrument_net_http => true,
30
+ :instrument_redis => true,
31
+ :instrument_sequel => true,
32
+ :log => "file",
33
+ :log_level => "info",
23
34
  :request_headers => %w[
24
35
  HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING
25
36
  HTTP_ACCEPT_LANGUAGE HTTP_CACHE_CONTROL HTTP_CONNECTION
@@ -27,54 +38,47 @@ module Appsignal
27
38
  REQUEST_METHOD REQUEST_URI SERVER_NAME SERVER_PORT
28
39
  SERVER_PROTOCOL
29
40
  ],
30
- :endpoint => "https://push.appsignal.com",
31
- :instrument_net_http => true,
32
- :instrument_redis => true,
33
- :instrument_sequel => true,
41
+ :send_environment_metadata => true,
42
+ :send_params => true,
34
43
  :skip_session_data => false,
35
- :enable_allocation_tracking => true,
36
- :enable_gc_instrumentation => false,
37
- :enable_host_metrics => true,
38
- :enable_minutely_probes => true,
39
- :ca_file_path => File.expand_path(File.join("../../../resources/cacert.pem"), __FILE__),
40
- :dns_servers => [],
41
- :files_world_accessible => true,
42
44
  :transaction_debug_mode => false
43
45
  }.freeze
44
46
 
45
47
  ENV_TO_KEY_MAPPING = {
46
48
  "APPSIGNAL_ACTIVE" => :active,
47
- "APPSIGNAL_PUSH_API_KEY" => :push_api_key,
48
49
  "APPSIGNAL_APP_NAME" => :name,
49
- "APPSIGNAL_PUSH_API_ENDPOINT" => :endpoint,
50
+ "APPSIGNAL_CA_FILE_PATH" => :ca_file_path,
50
51
  "APPSIGNAL_DEBUG" => :debug,
51
- "APPSIGNAL_LOG" => :log,
52
- "APPSIGNAL_LOG_PATH" => :log_path,
53
- "APPSIGNAL_INSTRUMENT_NET_HTTP" => :instrument_net_http,
54
- "APPSIGNAL_INSTRUMENT_REDIS" => :instrument_redis,
55
- "APPSIGNAL_INSTRUMENT_SEQUEL" => :instrument_sequel,
56
- "APPSIGNAL_SKIP_SESSION_DATA" => :skip_session_data,
57
- "APPSIGNAL_IGNORE_ACTIONS" => :ignore_actions,
58
- "APPSIGNAL_IGNORE_ERRORS" => :ignore_errors,
59
- "APPSIGNAL_IGNORE_NAMESPACES" => :ignore_namespaces,
60
- "APPSIGNAL_FILTER_PARAMETERS" => :filter_parameters,
61
- "APPSIGNAL_FILTER_SESSION_DATA" => :filter_session_data,
62
- "APPSIGNAL_SEND_ENVIRONMENT_METADATA" => :send_environment_metadata,
63
- "APPSIGNAL_SEND_PARAMS" => :send_params,
64
- "APPSIGNAL_HTTP_PROXY" => :http_proxy,
52
+ "APPSIGNAL_DNS_SERVERS" => :dns_servers,
65
53
  "APPSIGNAL_ENABLE_ALLOCATION_TRACKING" => :enable_allocation_tracking,
66
54
  "APPSIGNAL_ENABLE_GC_INSTRUMENTATION" => :enable_gc_instrumentation,
67
- "APPSIGNAL_RUNNING_IN_CONTAINER" => :running_in_container,
68
- "APPSIGNAL_WORKING_DIR_PATH" => :working_dir_path,
69
- "APPSIGNAL_WORKING_DIRECTORY_PATH" => :working_directory_path,
70
55
  "APPSIGNAL_ENABLE_HOST_METRICS" => :enable_host_metrics,
71
56
  "APPSIGNAL_ENABLE_MINUTELY_PROBES" => :enable_minutely_probes,
72
- "APPSIGNAL_HOSTNAME" => :hostname,
73
- "APPSIGNAL_CA_FILE_PATH" => :ca_file_path,
74
- "APPSIGNAL_DNS_SERVERS" => :dns_servers,
57
+ "APPSIGNAL_ENABLE_STATSD" => :enable_statsd,
75
58
  "APPSIGNAL_FILES_WORLD_ACCESSIBLE" => :files_world_accessible,
59
+ "APPSIGNAL_FILTER_PARAMETERS" => :filter_parameters,
60
+ "APPSIGNAL_FILTER_SESSION_DATA" => :filter_session_data,
61
+ "APPSIGNAL_HOSTNAME" => :hostname,
62
+ "APPSIGNAL_HTTP_PROXY" => :http_proxy,
63
+ "APPSIGNAL_IGNORE_ACTIONS" => :ignore_actions,
64
+ "APPSIGNAL_IGNORE_ERRORS" => :ignore_errors,
65
+ "APPSIGNAL_IGNORE_NAMESPACES" => :ignore_namespaces,
66
+ "APPSIGNAL_INSTRUMENT_NET_HTTP" => :instrument_net_http,
67
+ "APPSIGNAL_INSTRUMENT_REDIS" => :instrument_redis,
68
+ "APPSIGNAL_INSTRUMENT_SEQUEL" => :instrument_sequel,
69
+ "APPSIGNAL_LOG" => :log,
70
+ "APPSIGNAL_LOG_LEVEL" => :log_level,
71
+ "APPSIGNAL_LOG_PATH" => :log_path,
72
+ "APPSIGNAL_PUSH_API_ENDPOINT" => :endpoint,
73
+ "APPSIGNAL_PUSH_API_KEY" => :push_api_key,
76
74
  "APPSIGNAL_REQUEST_HEADERS" => :request_headers,
75
+ "APPSIGNAL_RUNNING_IN_CONTAINER" => :running_in_container,
76
+ "APPSIGNAL_SEND_ENVIRONMENT_METADATA" => :send_environment_metadata,
77
+ "APPSIGNAL_SEND_PARAMS" => :send_params,
78
+ "APPSIGNAL_SKIP_SESSION_DATA" => :skip_session_data,
77
79
  "APPSIGNAL_TRANSACTION_DEBUG_MODE" => :transaction_debug_mode,
80
+ "APPSIGNAL_WORKING_DIRECTORY_PATH" => :working_directory_path,
81
+ "APPSIGNAL_WORKING_DIR_PATH" => :working_dir_path,
78
82
  "APP_REVISION" => :revision
79
83
  }.freeze
80
84
  # @api private
@@ -84,6 +88,7 @@ module Appsignal
84
88
  APPSIGNAL_HOSTNAME
85
89
  APPSIGNAL_HTTP_PROXY
86
90
  APPSIGNAL_LOG
91
+ APPSIGNAL_LOG_LEVEL
87
92
  APPSIGNAL_LOG_PATH
88
93
  APPSIGNAL_PUSH_API_ENDPOINT
89
94
  APPSIGNAL_PUSH_API_KEY
@@ -99,6 +104,7 @@ module Appsignal
99
104
  APPSIGNAL_ENABLE_GC_INSTRUMENTATION
100
105
  APPSIGNAL_ENABLE_HOST_METRICS
101
106
  APPSIGNAL_ENABLE_MINUTELY_PROBES
107
+ APPSIGNAL_ENABLE_STATSD
102
108
  APPSIGNAL_FILES_WORLD_ACCESSIBLE
103
109
  APPSIGNAL_INSTRUMENT_NET_HTTP
104
110
  APPSIGNAL_INSTRUMENT_REDIS
@@ -265,32 +271,35 @@ module Appsignal
265
271
 
266
272
  def write_to_environment # rubocop:disable Metrics/AbcSize
267
273
  ENV["_APPSIGNAL_ACTIVE"] = active?.to_s
268
- ENV["_APPSIGNAL_APP_PATH"] = root_path.to_s
269
274
  ENV["_APPSIGNAL_AGENT_PATH"] = File.expand_path("../../../ext", __FILE__).to_s
275
+ ENV["_APPSIGNAL_APP_NAME"] = config_hash[:name]
276
+ ENV["_APPSIGNAL_APP_PATH"] = root_path.to_s
277
+ ENV["_APPSIGNAL_CA_FILE_PATH"] = config_hash[:ca_file_path].to_s
278
+ ENV["_APPSIGNAL_DEBUG_LOGGING"] = config_hash[:debug].to_s
279
+ ENV["_APPSIGNAL_DNS_SERVERS"] = config_hash[:dns_servers].join(",")
280
+ ENV["_APPSIGNAL_ENABLE_HOST_METRICS"] = config_hash[:enable_host_metrics].to_s
281
+ ENV["_APPSIGNAL_ENABLE_STATSD"] = config_hash[:enable_statsd].to_s
270
282
  ENV["_APPSIGNAL_ENVIRONMENT"] = env
283
+ ENV["_APPSIGNAL_FILES_WORLD_ACCESSIBLE"] = config_hash[:files_world_accessible].to_s
284
+ ENV["_APPSIGNAL_FILTER_PARAMETERS"] = config_hash[:filter_parameters].join(",")
285
+ ENV["_APPSIGNAL_FILTER_SESSION_DATA"] = config_hash[:filter_session_data].join(",")
286
+ ENV["_APPSIGNAL_HOSTNAME"] = config_hash[:hostname].to_s
287
+ ENV["_APPSIGNAL_HTTP_PROXY"] = config_hash[:http_proxy]
288
+ ENV["_APPSIGNAL_IGNORE_ACTIONS"] = config_hash[:ignore_actions].join(",")
289
+ ENV["_APPSIGNAL_IGNORE_ERRORS"] = config_hash[:ignore_errors].join(",")
290
+ ENV["_APPSIGNAL_IGNORE_NAMESPACES"] = config_hash[:ignore_namespaces].join(",")
271
291
  ENV["_APPSIGNAL_LANGUAGE_INTEGRATION_VERSION"] = "ruby-#{Appsignal::VERSION}"
272
- ENV["_APPSIGNAL_DEBUG_LOGGING"] = config_hash[:debug].to_s
273
292
  ENV["_APPSIGNAL_LOG"] = config_hash[:log]
293
+ ENV["_APPSIGNAL_LOG_LEVEL"] = config_hash[:log_level]
274
294
  ENV["_APPSIGNAL_LOG_FILE_PATH"] = log_file_path.to_s if log_file_path
295
+ ENV["_APPSIGNAL_PROCESS_NAME"] = $PROGRAM_NAME
275
296
  ENV["_APPSIGNAL_PUSH_API_ENDPOINT"] = config_hash[:endpoint]
276
297
  ENV["_APPSIGNAL_PUSH_API_KEY"] = config_hash[:push_api_key]
277
- ENV["_APPSIGNAL_APP_NAME"] = config_hash[:name]
278
- ENV["_APPSIGNAL_HTTP_PROXY"] = config_hash[:http_proxy]
279
- ENV["_APPSIGNAL_IGNORE_ACTIONS"] = config_hash[:ignore_actions].join(",")
280
- ENV["_APPSIGNAL_IGNORE_ERRORS"] = config_hash[:ignore_errors].join(",")
281
- ENV["_APPSIGNAL_IGNORE_NAMESPACES"] = config_hash[:ignore_namespaces].join(",")
282
298
  ENV["_APPSIGNAL_RUNNING_IN_CONTAINER"] = config_hash[:running_in_container].to_s
283
- ENV["_APPSIGNAL_WORKING_DIR_PATH"] = config_hash[:working_dir_path] if config_hash[:working_dir_path]
284
- ENV["_APPSIGNAL_WORKING_DIRECTORY_PATH"] = config_hash[:working_directory_path] if config_hash[:working_directory_path]
285
- ENV["_APPSIGNAL_ENABLE_HOST_METRICS"] = config_hash[:enable_host_metrics].to_s
286
- ENV["_APPSIGNAL_HOSTNAME"] = config_hash[:hostname].to_s
287
- ENV["_APPSIGNAL_PROCESS_NAME"] = $PROGRAM_NAME
288
- ENV["_APPSIGNAL_CA_FILE_PATH"] = config_hash[:ca_file_path].to_s
289
- ENV["_APPSIGNAL_DNS_SERVERS"] = config_hash[:dns_servers].join(",")
290
- ENV["_APPSIGNAL_FILES_WORLD_ACCESSIBLE"] = config_hash[:files_world_accessible].to_s
291
- ENV["_APPSIGNAL_TRANSACTION_DEBUG_MODE"] = config_hash[:transaction_debug_mode].to_s
292
299
  ENV["_APPSIGNAL_SEND_ENVIRONMENT_METADATA"] = config_hash[:send_environment_metadata].to_s
293
- ENV["_APPSIGNAL_ENABLE_STATSD"] = "true"
300
+ ENV["_APPSIGNAL_TRANSACTION_DEBUG_MODE"] = config_hash[:transaction_debug_mode].to_s
301
+ ENV["_APPSIGNAL_WORKING_DIRECTORY_PATH"] = config_hash[:working_directory_path] if config_hash[:working_directory_path]
302
+ ENV["_APPSIGNAL_WORKING_DIR_PATH"] = config_hash[:working_dir_path] if config_hash[:working_dir_path]
294
303
  ENV["_APP_REVISION"] = config_hash[:revision].to_s
295
304
  end
296
305
 
@@ -131,6 +131,65 @@ module Appsignal
131
131
  [:pointer],
132
132
  :appsignal_string
133
133
 
134
+ # Span methods
135
+ attach_function :appsignal_create_root_span,
136
+ [:appsignal_string],
137
+ :pointer
138
+ attach_function :appsignal_create_root_span_with_timestamp,
139
+ [:appsignal_string, :int64, :int64],
140
+ :pointer
141
+ attach_function :appsignal_create_child_span,
142
+ [:pointer],
143
+ :pointer
144
+ attach_function :appsignal_create_child_span_with_timestamp,
145
+ [:pointer, :int64, :int64],
146
+ :pointer
147
+ attach_function :appsignal_create_span_from_traceparent,
148
+ [:appsignal_string],
149
+ :pointer
150
+ attach_function :appsignal_span_id,
151
+ [:pointer],
152
+ :appsignal_string
153
+ attach_function :appsignal_span_to_json,
154
+ [:pointer],
155
+ :appsignal_string
156
+ attach_function :appsignal_set_span_name,
157
+ [:pointer, :appsignal_string],
158
+ :void
159
+ attach_function :appsignal_set_span_namespace,
160
+ [:pointer, :appsignal_string],
161
+ :void
162
+ attach_function :appsignal_add_span_error,
163
+ [:pointer, :appsignal_string, :appsignal_string, :pointer],
164
+ :void
165
+ attach_function :appsignal_set_span_sample_data,
166
+ [:pointer, :appsignal_string, :pointer],
167
+ :void
168
+ attach_function :appsignal_set_span_attribute_string,
169
+ [:pointer, :appsignal_string, :appsignal_string],
170
+ :void
171
+ attach_function :appsignal_set_span_attribute_sql_string,
172
+ [:pointer, :appsignal_string, :appsignal_string],
173
+ :void
174
+ attach_function :appsignal_set_span_attribute_int,
175
+ [:pointer, :appsignal_string, :int64],
176
+ :void
177
+ attach_function :appsignal_set_span_attribute_bool,
178
+ [:pointer, :appsignal_string, :bool],
179
+ :void
180
+ attach_function :appsignal_set_span_attribute_double,
181
+ [:pointer, :appsignal_string, :double],
182
+ :void
183
+ attach_function :appsignal_close_span,
184
+ [:pointer],
185
+ :void
186
+ attach_function :appsignal_close_span_with_timestamp,
187
+ [:pointer, :int64, :int64],
188
+ :void
189
+ attach_function :appsignal_free_span,
190
+ [:pointer],
191
+ :void
192
+
134
193
  # Data struct methods
135
194
  attach_function :appsignal_free_data, [], :void
136
195
  attach_function :appsignal_data_map_new, [], :pointer
@@ -375,6 +434,94 @@ module Appsignal
375
434
  end
376
435
  end
377
436
 
437
+ class Span
438
+ include StringHelpers
439
+ extend StringHelpers
440
+
441
+ attr_reader :pointer
442
+
443
+ def initialize(pointer)
444
+ @pointer = FFI::AutoPointer.new(
445
+ pointer,
446
+ Extension.method(:appsignal_free_span)
447
+ )
448
+ end
449
+
450
+ def self.root(namespace)
451
+ namespace = make_appsignal_string(namespace)
452
+ Span.new(Extension.appsignal_create_root_span(namespace))
453
+ end
454
+
455
+ def child
456
+ Span.new(Extension.appsignal_create_child_span(pointer))
457
+ end
458
+
459
+ def add_error(name, message, backtrace)
460
+ Extension.appsignal_add_span_error(
461
+ pointer,
462
+ make_appsignal_string(name),
463
+ make_appsignal_string(message),
464
+ backtrace.pointer
465
+ )
466
+ end
467
+
468
+ def set_sample_data(key, payload)
469
+ Extension.appsignal_set_span_sample_data(
470
+ pointer,
471
+ make_appsignal_string(key),
472
+ payload.pointer
473
+ )
474
+ end
475
+
476
+ def set_name(name) # rubocop:disable Naming/AccessorMethodName
477
+ Extension.appsignal_set_span_name(
478
+ pointer,
479
+ make_appsignal_string(name)
480
+ )
481
+ end
482
+
483
+ def set_attribute_string(key, value)
484
+ Extension.appsignal_set_span_attribute_string(
485
+ pointer,
486
+ make_appsignal_string(key),
487
+ make_appsignal_string(value)
488
+ )
489
+ end
490
+
491
+ def set_attribute_int(key, value)
492
+ Extension.appsignal_set_span_attribute_int(
493
+ pointer,
494
+ make_appsignal_string(key),
495
+ value
496
+ )
497
+ end
498
+
499
+ def set_attribute_bool(key, value)
500
+ Extension.appsignal_set_span_attribute_bool(
501
+ pointer,
502
+ make_appsignal_string(key),
503
+ value
504
+ )
505
+ end
506
+
507
+ def set_attribute_double(key, value)
508
+ Extension.appsignal_set_span_attribute_double(
509
+ pointer,
510
+ make_appsignal_string(key),
511
+ value
512
+ )
513
+ end
514
+
515
+ def to_json
516
+ json = Extension.appsignal_span_to_json(pointer)
517
+ make_ruby_string(json) if json[:len] > 0
518
+ end
519
+
520
+ def close
521
+ Extension.appsignal_close_span(pointer)
522
+ end
523
+ end
524
+
378
525
  class Data
379
526
  include StringHelpers
380
527
  attr_reader :pointer
@@ -60,6 +60,11 @@ module Appsignal
60
60
  # Makes sure the generated docs aren't always overwritten with the JRuby
61
61
  # version.
62
62
  Transaction = Jruby::Transaction
63
+ # Reassign Span class for JRuby extension usage.
64
+ #
65
+ # Makes sure the generated docs aren't always overwritten with the JRuby
66
+ # version.
67
+ Span = Jruby::Span
63
68
  # Reassign Data class for JRuby extension usage.
64
69
  #
65
70
  # Makes sure the generated docs aren't always overwritten with the JRuby
@@ -0,0 +1,16 @@
1
+ module Appsignal
2
+ class Hooks
3
+ # @api private
4
+ class MriHook < Appsignal::Hooks::Hook
5
+ register :mri
6
+
7
+ def dependencies_present?
8
+ defined?(::RubyVM)
9
+ end
10
+
11
+ def install
12
+ Appsignal::Minutely.probes.register :mri, Appsignal::Probes::MriProbe
13
+ end
14
+ end
15
+ end
16
+ end
@@ -94,6 +94,7 @@ require "appsignal/hooks/active_job"
94
94
  require "appsignal/hooks/active_support_notifications"
95
95
  require "appsignal/hooks/celluloid"
96
96
  require "appsignal/hooks/delayed_job"
97
+ require "appsignal/hooks/mri"
97
98
  require "appsignal/hooks/net_http"
98
99
  require "appsignal/hooks/passenger"
99
100
  require "appsignal/hooks/puma"
@@ -0,0 +1,26 @@
1
+ module Appsignal
2
+ module Probes
3
+ class MriProbe
4
+ # @api private
5
+ def self.dependencies_present?
6
+ defined?(::RubyVM) && ::RubyVM.respond_to?(:stat)
7
+ end
8
+
9
+ def initialize
10
+ Appsignal.logger.debug("Initializing VM probe")
11
+ end
12
+
13
+ # @api private
14
+ def call
15
+ stat = RubyVM.stat
16
+ [:class_serial, :global_constant_state].each do |metric|
17
+ Appsignal.add_distribution_value(
18
+ "ruby_vm",
19
+ stat[metric],
20
+ :metric => metric
21
+ )
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -3,4 +3,5 @@ module Appsignal
3
3
  end
4
4
  end
5
5
 
6
+ require "appsignal/probes/mri"
6
7
  require "appsignal/probes/sidekiq"