appsignal 3.0.12 → 3.0.16
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -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
|
-
|
331
|
-
|
332
|
-
|
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
|
-
|
385
|
-
|
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
|
-
|
392
|
-
|
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
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
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
|
-
|
436
|
+
agent_architecture = Appsignal::System.agent_architecture
|
437
|
+
save :architecture, agent_architecture
|
438
|
+
puts_format "Architecture", agent_architecture
|
421
439
|
|
422
|
-
|
423
|
-
os_label =
|
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
|
-
|
428
|
-
|
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
|
-
|
431
|
-
save :heroku,
|
450
|
+
heroku = Appsignal::System.heroku?
|
451
|
+
save :heroku, heroku
|
452
|
+
puts_format "Heroku", true if Appsignal::System.heroku?
|
432
453
|
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
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 "
|
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
|
-
|
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
|
-
|
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
|
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
|
|
data/lib/appsignal/config.rb
CHANGED
@@ -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
|
-
:
|
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
|
-
:
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
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
|
-
:
|
31
|
-
:
|
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
|
-
"
|
50
|
+
"APPSIGNAL_CA_FILE_PATH" => :ca_file_path,
|
50
51
|
"APPSIGNAL_DEBUG" => :debug,
|
51
|
-
"
|
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
|
-
"
|
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["
|
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
|
data/lib/appsignal/extension.rb
CHANGED
@@ -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
|
data/lib/appsignal/hooks.rb
CHANGED
@@ -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
|