appsignal 2.8.4 → 2.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.rubocop_todo.yml +7 -16
  4. data/.travis.yml +4 -1
  5. data/CHANGELOG.md +16 -0
  6. data/README.md +23 -0
  7. data/Rakefile +10 -7
  8. data/appsignal.gemspec +3 -0
  9. data/build_matrix.yml +5 -1
  10. data/ext/Rakefile +23 -16
  11. data/ext/agent.yml +37 -37
  12. data/ext/base.rb +86 -24
  13. data/ext/extconf.rb +33 -26
  14. data/gemfiles/rails-6.0.gemfile +5 -0
  15. data/lib/appsignal.rb +14 -489
  16. data/lib/appsignal/cli/diagnose.rb +84 -4
  17. data/lib/appsignal/cli/diagnose/paths.rb +0 -5
  18. data/lib/appsignal/cli/diagnose/utils.rb +17 -0
  19. data/lib/appsignal/cli/helpers.rb +6 -0
  20. data/lib/appsignal/cli/install.rb +13 -7
  21. data/lib/appsignal/config.rb +1 -2
  22. data/lib/appsignal/event_formatter.rb +4 -5
  23. data/lib/appsignal/event_formatter/moped/query_formatter.rb +60 -59
  24. data/lib/appsignal/extension.rb +2 -2
  25. data/lib/appsignal/helpers/instrumentation.rb +485 -0
  26. data/lib/appsignal/helpers/metrics.rb +55 -0
  27. data/lib/appsignal/hooks.rb +9 -8
  28. data/lib/appsignal/hooks/puma.rb +65 -9
  29. data/lib/appsignal/hooks/sidekiq.rb +90 -0
  30. data/lib/appsignal/integrations/mongo_ruby_driver.rb +7 -0
  31. data/lib/appsignal/integrations/railtie.rb +2 -1
  32. data/lib/appsignal/marker.rb +2 -3
  33. data/lib/appsignal/minutely.rb +164 -14
  34. data/lib/appsignal/rack/sinatra_instrumentation.rb +1 -1
  35. data/lib/appsignal/system.rb +16 -18
  36. data/lib/appsignal/utils/rails_helper.rb +16 -0
  37. data/lib/appsignal/version.rb +1 -1
  38. data/spec/lib/appsignal/cli/diagnose_spec.rb +129 -22
  39. data/spec/lib/appsignal/cli/install_spec.rb +6 -1
  40. data/spec/lib/appsignal/config_spec.rb +3 -3
  41. data/spec/lib/appsignal/event_formatter/moped/query_formatter_spec.rb +6 -0
  42. data/spec/lib/appsignal/event_formatter_spec.rb +168 -69
  43. data/spec/lib/appsignal/hooks/puma_spec.rb +129 -0
  44. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +147 -0
  45. data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +24 -1
  46. data/spec/lib/appsignal/minutely_spec.rb +251 -21
  47. data/spec/lib/appsignal/system_spec.rb +0 -35
  48. data/spec/lib/appsignal/utils/hash_sanitizer_spec.rb +39 -31
  49. data/spec/lib/appsignal/utils/json_spec.rb +7 -3
  50. data/spec/lib/appsignal_spec.rb +27 -2
  51. data/spec/spec_helper.rb +13 -0
  52. data/spec/support/helpers/log_helpers.rb +6 -0
  53. data/spec/support/project_fixture/config/appsignal.yml +1 -0
  54. data/spec/support/stubs/sidekiq/api.rb +4 -0
  55. metadata +8 -2
@@ -1,18 +1,24 @@
1
- require File.expand_path("../../lib/appsignal/version.rb", __FILE__)
2
1
  require File.expand_path("../base.rb", __FILE__)
3
2
 
4
- def install # rubocop:disable Metrics/CyclomaticComplexity
5
- logger.info "Installing appsignal agent #{Appsignal::VERSION} for Ruby #{RUBY_VERSION} on #{RUBY_PLATFORM}"
6
- write_agent_architecture
3
+ def local_build?
4
+ File.exist?(ext_path("appsignal-agent")) &&
5
+ File.exist?(ext_path("libappsignal.a")) &&
6
+ File.exist?(ext_path("appsignal.h"))
7
+ end
8
+
9
+ def install
10
+ library_type = "static"
11
+ report["language"]["implementation"] = "ruby"
12
+ report["build"]["library_type"] = library_type
7
13
  return unless check_architecture
8
14
  arch_config = AGENT_CONFIG["triples"][ARCH]
9
15
 
10
- unless File.exist?(ext_path("appsignal-agent")) &&
11
- File.exist?(ext_path("libappsignal.a")) &&
12
- File.exist?(ext_path("appsignal.h"))
13
- archive = download_archive(arch_config, "static")
16
+ if local_build?
17
+ report["build"]["source"] = "local"
18
+ else
19
+ archive = download_archive(arch_config, library_type)
14
20
  return unless archive
15
- return unless verify_archive(archive, arch_config, "static")
21
+ return unless verify_archive(archive, arch_config, library_type)
16
22
  unarchive(archive)
17
23
  end
18
24
 
@@ -21,15 +27,13 @@ def install # rubocop:disable Metrics/CyclomaticComplexity
21
27
  Appsignal::System::MUSL_TARGET
22
28
  ].include?(PLATFORM)
23
29
 
24
- logger.info "Creating makefile"
25
30
  require "mkmf"
26
-
27
31
  link_libraries if is_linux_system
28
32
 
29
33
  if !have_library("appsignal", "appsignal_start", "appsignal.h")
30
- installation_failed "Aborting installation, libappsignal.a or appsignal.h not found"
34
+ abort_installation("Library libappsignal.a or appsignal.h not found")
31
35
  elsif !find_executable("appsignal-agent", EXT_PATH)
32
- installation_failed "Aborting installation, appsignal-agent not found"
36
+ abort_installation("File appsignal-agent not found")
33
37
  else
34
38
  if is_linux_system
35
39
  # Statically link libgcc and libgcc_s libraries.
@@ -38,15 +42,16 @@ def install # rubocop:disable Metrics/CyclomaticComplexity
38
42
  # run on one that isn't the missing libraries will cause the extension
39
43
  # to fail on start.
40
44
  $LDFLAGS += " -static-libgcc" # rubocop:disable Style/GlobalVars
45
+ report["build"]["flags"]["LDFLAGS"] = $LDFLAGS # rubocop:disable Style/GlobalVars
41
46
  end
42
47
  create_makefile "appsignal_extension"
43
- logger.info "Successfully created Makefile for appsignal extension"
44
- end
45
- rescue => ex
46
- installation_failed "Exception while installing: #{ex}"
47
- ex.backtrace.each do |line|
48
- logger.error line
48
+ successful_installation
49
49
  end
50
+ rescue => error
51
+ fail_installation_with_error(error)
52
+ ensure
53
+ create_dummy_makefile unless installation_succeeded?
54
+ write_report
50
55
  end
51
56
 
52
57
  # Ruby 2.6 requires us to statically link more libraries we use in our
@@ -54,26 +59,28 @@ end
54
59
  # and musl builds.
55
60
  def link_libraries
56
61
  if RbConfig::CONFIG["THREAD_MODEL"] == "pthread"
57
- logger.info "Linking extension against 'pthread' library"
58
62
  # Link gem extension against pthread library
59
63
  have_library "pthread"
60
- have_required_function "pthread_create"
64
+ have_required_function "pthread", "pthread_create"
61
65
  end
62
66
 
63
67
  # Links gem extension against the `dl` library. This is needed when Ruby is
64
68
  # not linked against `dl` itself, so link it on the gem extension.
65
- logger.info "Linking extension against 'dl' library"
66
69
  have_library "dl"
67
70
  # Check if functions are available now from the linked library
68
71
  %w[dlopen dlclose dlsym].each do |func|
69
- have_required_function func
72
+ have_required_function "dl", func
70
73
  end
71
74
  end
72
75
 
73
- def have_required_function(func) # rubocop:disable Naming/PredicateName
74
- return if have_func(func)
76
+ def have_required_function(library, func) # rubocop:disable Naming/PredicateName
77
+ if have_func(func)
78
+ report["build"]["dependencies"][library] = "linked"
79
+ return
80
+ end
75
81
 
76
- installation_failed "Aborting installation, missing function '#{func}'"
82
+ report["build"]["dependencies"][library] = "not linked"
83
+ abort_installation("Missing function '#{func}'")
77
84
  # Exit with true/0/success because the AppSignal installation should never
78
85
  # break a build
79
86
  exit
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rails', '~> 6.0.0.beta.1'
4
+
5
+ gemspec :path => '../'
@@ -4,13 +4,20 @@ require "json"
4
4
  require "logger"
5
5
  require "securerandom"
6
6
 
7
+ require "appsignal/helpers/instrumentation"
8
+ require "appsignal/helpers/metrics"
9
+
7
10
  # AppSignal for Ruby gem's main module.
8
11
  #
9
- # Provides method to control the AppSignal instrumentation and the system agent.
10
- # Also provides instrumentation helpers for ease of use.
12
+ # Provides method to control the AppSignal instrumentation and the system
13
+ # agent. Also provides direct access to instrumentation helpers (from
14
+ # {Appsignal::Helpers::Instrumentation}) and metrics helpers (from
15
+ # {Appsignal::Helpers::Metrics}) for ease of use.
11
16
  module Appsignal
12
17
  class << self
13
18
  extend Gem::Deprecate
19
+ include Helpers::Instrumentation
20
+ include Helpers::Metrics
14
21
 
15
22
  # Accessor for the AppSignal configuration.
16
23
  # Return the current AppSignal configuration.
@@ -130,7 +137,7 @@ module Appsignal
130
137
 
131
138
  if config[:enable_gc_instrumentation]
132
139
  GC::Profiler.enable
133
- Appsignal::Minutely.add_gc_probe
140
+ Appsignal::Minutely.register_garbage_collection_probe
134
141
  end
135
142
 
136
143
  Appsignal::Minutely.start if config[:enable_minutely_probes]
@@ -176,471 +183,6 @@ module Appsignal
176
183
  Appsignal::Extension.get_server_state(key)
177
184
  end
178
185
 
179
- # Creates an AppSignal transaction for the given block.
180
- #
181
- # If AppSignal is not {.active?} it will still execute the block, but not
182
- # create a transaction for it.
183
- #
184
- # A event is created for this transaction with the name given in the `name`
185
- # argument. The event name must start with either `perform_job` or
186
- # `process_action` to differentiate between the "web" and "background"
187
- # namespace. Custom namespaces are not supported by this helper method.
188
- #
189
- # This helper method also captures any exception that occurs in the given
190
- # block.
191
- #
192
- # @example
193
- # Appsignal.monitor_transaction("perform_job.nightly_update") do
194
- # # your code
195
- # end
196
- #
197
- # @example with an environment
198
- # Appsignal.monitor_transaction(
199
- # "perform_job.nightly_update",
200
- # :metadata => { "user_id" => 1 }
201
- # ) do
202
- # # your code
203
- # end
204
- #
205
- # @param name [String] main event name.
206
- # @param env [Hash<Symbol, Object>]
207
- # @option env [Hash<Symbol/String, Object>] :params Params for the
208
- # monitored request/job, see {Appsignal::Transaction#params=} for more
209
- # information.
210
- # @option env [String] :controller name of the controller in which the
211
- # transaction was recorded.
212
- # @option env [String] :class name of the Ruby class in which the
213
- # transaction was recorded. If `:controller` is also given, `:controller`
214
- # is used instead.
215
- # @option env [String] :action name of the controller action in which the
216
- # transaction was recorded.
217
- # @option env [String] :method name of the Ruby method in which the
218
- # transaction was recorded. If `:action` is also given, `:action`
219
- # is used instead.
220
- # @option env [Integer] :queue_start the moment the request/job was queued.
221
- # Used to track how long requests/jobs were queued before being executed.
222
- # @option env [Hash<Symbol/String, String/Fixnum>] :metadata Additional
223
- # metadata for the transaction, see {Appsignal::Transaction#set_metadata}
224
- # for more information.
225
- # @yield the block to monitor.
226
- # @raise [Exception] any exception that occurs within the given block is re-raised by
227
- # this method.
228
- # @return [Object] the value of the given block is returned.
229
- # @since 0.10.0
230
- def monitor_transaction(name, env = {})
231
- return yield unless active?
232
-
233
- if name.start_with?("perform_job".freeze)
234
- namespace = Appsignal::Transaction::BACKGROUND_JOB
235
- request = Appsignal::Transaction::GenericRequest.new(env)
236
- elsif name.start_with?("process_action".freeze)
237
- namespace = Appsignal::Transaction::HTTP_REQUEST
238
- request = ::Rack::Request.new(env)
239
- else
240
- logger.error("Unrecognized name '#{name}'")
241
- return
242
- end
243
- transaction = Appsignal::Transaction.create(
244
- SecureRandom.uuid,
245
- namespace,
246
- request
247
- )
248
- begin
249
- Appsignal.instrument(name) do
250
- yield
251
- end
252
- rescue Exception => error # rubocop:disable Lint/RescueException
253
- transaction.set_error(error)
254
- raise error
255
- ensure
256
- transaction.set_http_or_background_action(request.env)
257
- transaction.set_http_or_background_queue_start
258
- Appsignal::Transaction.complete_current!
259
- end
260
- end
261
-
262
- # Monitor a transaction, stop AppSignal and wait for this single
263
- # transaction to be flushed.
264
- #
265
- # Useful for cases such as Rake tasks and Resque-like systems where a
266
- # process is forked and immediately exits after the transaction finishes.
267
- #
268
- # @see monitor_transaction
269
- def monitor_single_transaction(name, env = {}, &block)
270
- monitor_transaction(name, env, &block)
271
- ensure
272
- stop("monitor_single_transaction")
273
- end
274
-
275
- # Listen for an error to occur and send it to AppSignal.
276
- #
277
- # Uses {.send_error} to directly send the error in a separate transaction.
278
- # Does not add the error to the current transaction.
279
- #
280
- # Make sure that AppSignal is integrated in your application beforehand.
281
- # AppSignal won't record errors unless {Config#active?} is `true`.
282
- #
283
- # @example
284
- # # my_app.rb
285
- # # setup AppSignal beforehand
286
- #
287
- # Appsignal.listen_for_error do
288
- # # my code
289
- # raise "foo"
290
- # end
291
- #
292
- # @see Transaction.set_tags
293
- # @see Transaction.set_namespace
294
- # @see .send_error
295
- # @see https://docs.appsignal.com/ruby/instrumentation/integrating-appsignal.html
296
- # AppSignal integration guide
297
- #
298
- # @param tags [Hash, nil]
299
- # @param namespace [String] the namespace for this error.
300
- # @yield yields the given block.
301
- # @return [Object] returns the return value of the given block.
302
- def listen_for_error(tags = nil, namespace = Appsignal::Transaction::HTTP_REQUEST)
303
- yield
304
- rescue Exception => error # rubocop:disable Lint/RescueException
305
- send_error(error, tags, namespace)
306
- raise error
307
- end
308
- alias :listen_for_exception :listen_for_error
309
-
310
- # Send an error to AppSignal regardless of the context.
311
- #
312
- # Records and send the exception to AppSignal.
313
- #
314
- # This instrumentation helper does not require a transaction to be active,
315
- # it starts a new transaction by itself.
316
- #
317
- # Use {.set_error} if your want to add an exception to the current
318
- # transaction.
319
- #
320
- # **Note**: Does not do anything if AppSignal is not active or when the
321
- # "error" is not a class extended from Ruby's Exception class.
322
- #
323
- # @example Send an exception
324
- # begin
325
- # raise "oh no!"
326
- # rescue => e
327
- # Appsignal.send_error(e)
328
- # end
329
- #
330
- # @example Send an exception with tags
331
- # begin
332
- # raise "oh no!"
333
- # rescue => e
334
- # Appsignal.send_error(e, :key => "value")
335
- # end
336
- #
337
- # @param error [Exception] The error to send to AppSignal.
338
- # @param tags [Hash{String, Symbol => String, Symbol, Integer}] Additional
339
- # tags to add to the error. See also {.tag_request}.
340
- # @param namespace [String] The namespace in which the error occurred.
341
- # See also {.set_namespace}.
342
- # @return [void]
343
- #
344
- # @see http://docs.appsignal.com/ruby/instrumentation/exception-handling.html
345
- # Exception handling guide
346
- # @see http://docs.appsignal.com/ruby/instrumentation/tagging.html
347
- # Tagging guide
348
- # @since 0.6.0
349
- def send_error(error, tags = nil, namespace = Appsignal::Transaction::HTTP_REQUEST)
350
- return unless active?
351
- unless error.is_a?(Exception)
352
- logger.error("Can't send error, given value is not an exception")
353
- return
354
- end
355
- transaction = Appsignal::Transaction.new(
356
- SecureRandom.uuid,
357
- namespace,
358
- Appsignal::Transaction::GenericRequest.new({})
359
- )
360
- transaction.set_tags(tags) if tags
361
- transaction.set_error(error)
362
- transaction.complete
363
- end
364
- alias :send_exception :send_error
365
-
366
- # Set an error on the current transaction.
367
- #
368
- # **Note**: Does not do anything if AppSignal is not active, no transaction
369
- # is currently active or when the "error" is not a class extended from
370
- # Ruby's Exception class.
371
- #
372
- # @example Manual instrumentation of set_error.
373
- # # Manually starting AppSignal here
374
- # # Manually starting a transaction here.
375
- # begin
376
- # raise "oh no!"
377
- # rescue => e
378
- # Appsignal.set_error(error)
379
- # end
380
- # # Manually completing the transaction here.
381
- # # Manually stopping AppSignal here
382
- #
383
- # @example In a Rails application
384
- # class SomeController < ApplicationController
385
- # # The AppSignal transaction is created by our integration for you.
386
- # def create
387
- # # Do something that breaks
388
- # rescue => e
389
- # Appsignal.set_error(e)
390
- # end
391
- # end
392
- #
393
- # @param exception [Exception] The error to add to the current transaction.
394
- # @param tags [Hash{String, Symbol => String, Symbol, Integer}] Additional
395
- # tags to add to the error. See also {.tag_request}.
396
- # @param namespace [String] The namespace in which the error occurred.
397
- # See also {.set_namespace}.
398
- # @return [void]
399
- #
400
- # @see Transaction#set_error
401
- # @see http://docs.appsignal.com/ruby/instrumentation/exception-handling.html
402
- # Exception handling guide
403
- # @since 0.6.6
404
- def set_error(exception, tags = nil, namespace = nil)
405
- return if !active? ||
406
- Appsignal::Transaction.current.nil? ||
407
- exception.nil?
408
- transaction = Appsignal::Transaction.current
409
- transaction.set_error(exception)
410
- transaction.set_tags(tags) if tags
411
- transaction.set_namespace(namespace) if namespace
412
- end
413
- alias :set_exception :set_error
414
- alias :add_exception :set_error
415
-
416
- # Set a custom action name for the current transaction.
417
- #
418
- # When using an integration such as the Rails or Sinatra AppSignal will try
419
- # to find the action name from the controller or endpoint for you.
420
- #
421
- # If you want to customize the action name as it appears on AppSignal.com
422
- # you can use this method. This overrides the action name AppSignal
423
- # generates in an integration.
424
- #
425
- # @example in a Rails controller
426
- # class SomeController < ApplicationController
427
- # before_action :set_appsignal_action
428
- #
429
- # def set_appsignal_action
430
- # Appsignal.set_action("DynamicController#dynamic_method")
431
- # end
432
- # end
433
- #
434
- # @param action [String]
435
- # @return [void]
436
- # @see Transaction#set_action
437
- # @since 2.2.0
438
- def set_action(action)
439
- return if !active? ||
440
- Appsignal::Transaction.current.nil? ||
441
- action.nil?
442
- Appsignal::Transaction.current.set_action(action)
443
- end
444
-
445
- # Set a custom namespace for the current transaction.
446
- #
447
- # When using an integration such as Rails or Sidekiq AppSignal will try to
448
- # find a appropriate namespace for the transaction.
449
- #
450
- # A Rails controller will be automatically put in the "http_request"
451
- # namespace, while a Sidekiq background job is put in the "background_job"
452
- # namespace.
453
- #
454
- # Note: The "http_request" namespace gets transformed on AppSignal.com to
455
- # "Web" and "background_job" gets transformed to "Background".
456
- #
457
- # If you want to customize the namespace in which transactions appear you
458
- # can use this method. This overrides the namespace AppSignal uses by
459
- # default.
460
- #
461
- # A common request we've seen is to split the administration panel from the
462
- # main application.
463
- #
464
- # @example create a custom admin namespace
465
- # class AdminController < ApplicationController
466
- # before_action :set_appsignal_namespace
467
- #
468
- # def set_appsignal_namespace
469
- # Appsignal.set_namespace("admin")
470
- # end
471
- # end
472
- #
473
- # @param namespace [String]
474
- # @return [void]
475
- # @see Transaction#set_namespace
476
- # @since 2.2.0
477
- def set_namespace(namespace)
478
- return if !active? ||
479
- Appsignal::Transaction.current.nil? ||
480
- namespace.nil?
481
- Appsignal::Transaction.current.set_namespace(namespace)
482
- end
483
-
484
- # Set tags on the current transaction.
485
- #
486
- # Tags are extra bits of information that are added to transaction and
487
- # appear on sample details pages on AppSignal.com.
488
- #
489
- # @example
490
- # Appsignal.tag_request(:locale => "en")
491
- # Appsignal.tag_request("locale" => "en")
492
- # Appsignal.tag_request("user_id" => 1)
493
- #
494
- # @example Nested hashes are not supported
495
- # # Bad
496
- # Appsignal.tag_request(:user => { :locale => "en" })
497
- #
498
- # @example in a Rails controller
499
- # class SomeController < ApplicationController
500
- # before_action :set_appsignal_tags
501
- #
502
- # def set_appsignal_tags
503
- # Appsignal.tag_request(:locale => I18n.locale)
504
- # end
505
- # end
506
- #
507
- # @param tags [Hash] Collection of tags.
508
- # @option tags [String, Symbol, Integer] :any
509
- # The name of the tag as a Symbol.
510
- # @option tags [String, Symbol, Integer] "any"
511
- # The name of the tag as a String.
512
- # @return [void]
513
- #
514
- # @see Transaction.set_tags
515
- # @see http://docs.appsignal.com/ruby/instrumentation/tagging.html
516
- # Tagging guide
517
- def tag_request(tags = {})
518
- return unless active?
519
- transaction = Appsignal::Transaction.current
520
- return false unless transaction
521
- transaction.set_tags(tags)
522
- end
523
- alias :tag_job :tag_request
524
-
525
- # Instrument helper for AppSignal.
526
- #
527
- # For more help, read our custom instrumentation guide, listed under "See
528
- # also".
529
- #
530
- # @example Simple instrumentation
531
- # Appsignal.instrument("fetch.issue_fetcher") do
532
- # # To be instrumented code
533
- # end
534
- #
535
- # @example Instrumentation with title and body
536
- # Appsignal.instrument(
537
- # "fetch.issue_fetcher",
538
- # "Fetching issue",
539
- # "GitHub API"
540
- # ) do
541
- # # To be instrumented code
542
- # end
543
- #
544
- # @param name [String] Name of the instrumented event. Read our event
545
- # naming guide listed under "See also".
546
- # @param title [String, nil] Human readable name of the event.
547
- # @param body [String, nil] Value of importance for the event, such as the
548
- # server against an API call is made.
549
- # @param body_format [Integer] Enum for the type of event that is
550
- # instrumented. Accepted values are {EventFormatter::DEFAULT} and
551
- # {EventFormatter::SQL_BODY_FORMAT}, but we recommend you use
552
- # {.instrument_sql} instead of {EventFormatter::SQL_BODY_FORMAT}.
553
- # @yield yields the given block of code instrumented in an AppSignal
554
- # event.
555
- # @return [Object] Returns the block's return value.
556
- #
557
- # @see Appsignal::Transaction#instrument
558
- # @see .instrument_sql
559
- # @see http://docs.appsignal.com/ruby/instrumentation/instrumentation.html
560
- # AppSignal custom instrumentation guide
561
- # @see http://docs.appsignal.com/api/event-names.html
562
- # AppSignal event naming guide
563
- # @since 1.3.0
564
- def instrument(name, title = nil, body = nil, body_format = Appsignal::EventFormatter::DEFAULT)
565
- Appsignal::Transaction.current.start_event
566
- yield if block_given?
567
- ensure
568
- Appsignal::Transaction.current.finish_event(name, title, body, body_format)
569
- end
570
-
571
- # Instrumentation helper for SQL queries.
572
- #
573
- # This helper filters out values from SQL queries so you don't have to.
574
- #
575
- # @example SQL query instrumentation
576
- # Appsignal.instrument_sql("perform.query", nil, "SELECT * FROM ...") do
577
- # # To be instrumented code
578
- # end
579
- #
580
- # @example SQL query instrumentation
581
- # Appsignal.instrument_sql("perform.query", nil, "WHERE email = 'foo@..'") do
582
- # # query value will replace 'foo..' with a question mark `?`.
583
- # end
584
- #
585
- # @param name [String] Name of the instrumented event. Read our event
586
- # naming guide listed under "See also".
587
- # @param title [String, nil] Human readable name of the event.
588
- # @param body [String, nil] SQL query that's being executed.
589
- # @yield yields the given block of code instrumented in an AppSignal event.
590
- # @return [Object] Returns the block's return value.
591
- #
592
- # @see .instrument
593
- # @see http://docs.appsignal.com/ruby/instrumentation/instrumentation.html
594
- # AppSignal custom instrumentation guide
595
- # @see http://docs.appsignal.com/api/event-names.html
596
- # AppSignal event naming guide
597
- # @since 2.0.0
598
- def instrument_sql(name, title = nil, body = nil, &block)
599
- instrument(name, title, body, Appsignal::EventFormatter::SQL_BODY_FORMAT, &block)
600
- end
601
-
602
- def set_gauge(key, value, tags = {})
603
- Appsignal::Extension.set_gauge(
604
- key.to_s,
605
- value.to_f,
606
- Appsignal::Utils::Data.generate(tags)
607
- )
608
- rescue RangeError
609
- Appsignal.logger.warn("Gauge value #{value} for key '#{key}' is too big")
610
- end
611
-
612
- def set_host_gauge(key, value)
613
- Appsignal::Extension.set_host_gauge(key.to_s, value.to_f)
614
- rescue RangeError
615
- Appsignal.logger.warn("Host gauge value #{value} for key '#{key}' is too big")
616
- end
617
-
618
- def set_process_gauge(key, value)
619
- Appsignal::Extension.set_process_gauge(key.to_s, value.to_f)
620
- rescue RangeError
621
- Appsignal.logger.warn("Process gauge value #{value} for key '#{key}' is too big")
622
- end
623
-
624
- def increment_counter(key, value = 1.0, tags = {})
625
- Appsignal::Extension.increment_counter(
626
- key.to_s,
627
- value.to_f,
628
- Appsignal::Utils::Data.generate(tags)
629
- )
630
- rescue RangeError
631
- Appsignal.logger.warn("Counter value #{value} for key '#{key}' is too big")
632
- end
633
-
634
- def add_distribution_value(key, value, tags = {})
635
- Appsignal::Extension.add_distribution_value(
636
- key.to_s,
637
- value.to_f,
638
- Appsignal::Utils::Data.generate(tags)
639
- )
640
- rescue RangeError
641
- Appsignal.logger.warn("Distribution value #{value} for key '#{key}' is too big")
642
- end
643
-
644
186
  # In memory logger used before any logger is started with {.start_logger}.
645
187
  #
646
188
  # The contents of this logger are flushed to the logger in {.start_logger}.
@@ -681,6 +223,10 @@ module Appsignal
681
223
  # @return [void]
682
224
  # @since 0.7.0
683
225
  def start_logger(path_arg = nil)
226
+ if path_arg
227
+ logger.info("Setting the path in start_logger has no effect anymore, set it in the config instead")
228
+ end
229
+
684
230
  if config && config[:log] == "file" && config.log_file_path
685
231
  start_file_logger(config.log_file_path)
686
232
  else
@@ -695,10 +241,6 @@ module Appsignal
695
241
  end
696
242
 
697
243
  logger << @in_memory_log.string if @in_memory_log
698
-
699
- if path_arg
700
- logger.info("Setting the path in start_logger has no effect anymore, set it in the config instead")
701
- end
702
244
  end
703
245
 
704
246
  # Returns if the C-extension was loaded properly.
@@ -752,23 +294,6 @@ module Appsignal
752
294
  end
753
295
  deprecate :is_ignored_action?, :none, 2017, 3
754
296
 
755
- # Convenience method for skipping instrumentation around a block of code.
756
- #
757
- # @example
758
- # Appsignal.without_instrumentation do
759
- # # Complex code here
760
- # end
761
- #
762
- # @yield block of code that shouldn't be instrumented.
763
- # @return [Object] Returns the return value of the block.
764
- # @since 0.8.7
765
- def without_instrumentation
766
- Appsignal::Transaction.current.pause! if Appsignal::Transaction.current
767
- yield
768
- ensure
769
- Appsignal::Transaction.current.resume! if Appsignal::Transaction.current
770
- end
771
-
772
297
  private
773
298
 
774
299
  def start_stdout_logger