appsignal 2.8.4.beta.1 → 2.9.18.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +31 -0
  3. data/.github/ISSUE_TEMPLATE/chore.md +14 -0
  4. data/.gitignore +2 -3
  5. data/.rubocop.yml +3 -0
  6. data/.rubocop_todo.yml +7 -16
  7. data/.travis.yml +28 -27
  8. data/CHANGELOG.md +657 -533
  9. data/README.md +31 -3
  10. data/Rakefile +128 -129
  11. data/SUPPORT.md +16 -0
  12. data/appsignal.gemspec +17 -4
  13. data/build_matrix.yml +21 -9
  14. data/ext/Rakefile +23 -17
  15. data/ext/agent.yml +40 -37
  16. data/ext/base.rb +116 -31
  17. data/ext/extconf.rb +34 -28
  18. data/gemfiles/capistrano2.gemfile +5 -0
  19. data/gemfiles/capistrano3.gemfile +5 -0
  20. data/gemfiles/grape.gemfile +5 -0
  21. data/gemfiles/no_dependencies.gemfile +5 -0
  22. data/gemfiles/padrino.gemfile +5 -0
  23. data/gemfiles/que.gemfile +5 -0
  24. data/gemfiles/que_beta.gemfile +10 -0
  25. data/gemfiles/rails-3.2.gemfile +5 -0
  26. data/gemfiles/rails-4.0.gemfile +5 -0
  27. data/gemfiles/rails-4.1.gemfile +5 -0
  28. data/gemfiles/rails-4.2.gemfile +5 -0
  29. data/gemfiles/rails-6.0.gemfile +5 -0
  30. data/gemfiles/resque.gemfile +5 -0
  31. data/lib/appsignal.rb +14 -492
  32. data/lib/appsignal/cli/demo.rb +5 -2
  33. data/lib/appsignal/cli/diagnose.rb +84 -4
  34. data/lib/appsignal/cli/diagnose/paths.rb +0 -5
  35. data/lib/appsignal/cli/diagnose/utils.rb +19 -0
  36. data/lib/appsignal/cli/helpers.rb +6 -0
  37. data/lib/appsignal/cli/install.rb +45 -15
  38. data/lib/appsignal/cli/notify_of_deploy.rb +10 -0
  39. data/lib/appsignal/config.rb +1 -2
  40. data/lib/appsignal/event_formatter.rb +4 -5
  41. data/lib/appsignal/event_formatter/action_view/render_formatter.rb +10 -8
  42. data/lib/appsignal/event_formatter/moped/query_formatter.rb +60 -59
  43. data/lib/appsignal/extension.rb +2 -2
  44. data/lib/appsignal/helpers/instrumentation.rb +494 -0
  45. data/lib/appsignal/helpers/metrics.rb +54 -0
  46. data/lib/appsignal/hooks.rb +11 -8
  47. data/lib/appsignal/hooks/active_support_notifications.rb +2 -5
  48. data/lib/appsignal/hooks/puma.rb +74 -11
  49. data/lib/appsignal/hooks/sequel.rb +1 -1
  50. data/lib/appsignal/hooks/sidekiq.rb +115 -0
  51. data/lib/appsignal/integrations/mongo_ruby_driver.rb +7 -0
  52. data/lib/appsignal/integrations/que.rb +9 -8
  53. data/lib/appsignal/integrations/railtie.rb +2 -1
  54. data/lib/appsignal/marker.rb +2 -3
  55. data/lib/appsignal/minutely.rb +188 -19
  56. data/lib/appsignal/rack/sinatra_instrumentation.rb +1 -1
  57. data/lib/appsignal/system.rb +16 -18
  58. data/lib/appsignal/transaction.rb +8 -0
  59. data/lib/appsignal/utils/rails_helper.rb +20 -0
  60. data/lib/appsignal/version.rb +1 -1
  61. data/lib/puma/plugin/appsignal.rb +26 -0
  62. data/spec/lib/appsignal/cli/diagnose/utils_spec.rb +40 -0
  63. data/spec/lib/appsignal/cli/diagnose_spec.rb +129 -22
  64. data/spec/lib/appsignal/cli/install_spec.rb +57 -8
  65. data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +10 -0
  66. data/spec/lib/appsignal/config_spec.rb +13 -11
  67. data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +38 -28
  68. data/spec/lib/appsignal/event_formatter/moped/query_formatter_spec.rb +6 -0
  69. data/spec/lib/appsignal/event_formatter_spec.rb +168 -69
  70. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +104 -25
  71. data/spec/lib/appsignal/hooks/puma_spec.rb +251 -34
  72. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +209 -0
  73. data/spec/lib/appsignal/hooks_spec.rb +4 -0
  74. data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +24 -1
  75. data/spec/lib/appsignal/minutely_spec.rb +318 -26
  76. data/spec/lib/appsignal/system_spec.rb +0 -35
  77. data/spec/lib/appsignal/transaction_spec.rb +68 -10
  78. data/spec/lib/appsignal/utils/hash_sanitizer_spec.rb +39 -31
  79. data/spec/lib/appsignal/utils/json_spec.rb +7 -3
  80. data/spec/lib/appsignal_spec.rb +98 -22
  81. data/spec/lib/puma/appsignal_spec.rb +91 -0
  82. data/spec/spec_helper.rb +13 -0
  83. data/spec/support/{project_fixture → fixtures/projects/valid}/config/application.rb +0 -0
  84. data/spec/support/{project_fixture → fixtures/projects/valid}/config/appsignal.yml +1 -0
  85. data/spec/support/{project_fixture → fixtures/projects/valid}/config/environments/development.rb +0 -0
  86. data/spec/support/{project_fixture → fixtures/projects/valid}/config/environments/production.rb +0 -0
  87. data/spec/support/{project_fixture → fixtures/projects/valid}/config/environments/test.rb +0 -0
  88. data/spec/support/{project_fixture → fixtures/projects/valid}/log/.gitkeep +0 -0
  89. data/spec/support/helpers/config_helpers.rb +1 -1
  90. data/spec/support/helpers/log_helpers.rb +6 -0
  91. data/spec/support/helpers/wait_for_helper.rb +28 -0
  92. data/spec/support/mocks/mock_probe.rb +11 -0
  93. data/spec/support/stubs/sidekiq/api.rb +4 -0
  94. metadata +43 -31
  95. data/spec/support/fixtures/containers/cgroups/docker +0 -14
  96. data/spec/support/fixtures/containers/cgroups/docker_systemd +0 -8
  97. data/spec/support/fixtures/containers/cgroups/lxc +0 -10
  98. data/spec/support/fixtures/containers/cgroups/no_permission +0 -0
  99. data/spec/support/fixtures/containers/cgroups/none +0 -1
@@ -54,8 +54,11 @@ module Appsignal
54
54
  puts "Demonstration sample data sent!"
55
55
  puts "It may take about a minute for the data to appear on https://appsignal.com/accounts"
56
56
  else
57
- puts "Error: Unable to start the AppSignal agent and send data to AppSignal.com"
58
- puts "Please use `appsignal diagnose` to debug your configuration."
57
+ puts "\nError: Unable to start the AppSignal agent and send data to AppSignal.com."
58
+ puts "Please use the diagnose command (https://docs.appsignal.com/ruby/command-line/diagnose.html) to debug your configuration:"
59
+ puts
60
+ puts " bundle exec appsignal diagnose --environment=production"
61
+ puts
59
62
  exit 1
60
63
  end
61
64
  end
@@ -82,6 +82,8 @@ module Appsignal
82
82
  print_empty_line
83
83
 
84
84
  library_information
85
+ data[:installation] = fetch_installation_report
86
+ print_installation_report
85
87
  print_empty_line
86
88
 
87
89
  host_information
@@ -180,7 +182,8 @@ module Appsignal
180
182
  if rails_app?
181
183
  data[:app][:rails] = true
182
184
  current_path = Rails.root
183
- initial_config[:name] = Rails.application.class.parent_name
185
+ initial_config[:name] =
186
+ Appsignal::Utils::RailsHelper.detected_rails_app_name
184
187
  initial_config[:log_path] = current_path.join("log")
185
188
  end
186
189
 
@@ -325,12 +328,89 @@ module Appsignal
325
328
  save :language, "ruby"
326
329
  puts_and_save :package_version, "Gem version", Appsignal::VERSION
327
330
  puts_and_save :agent_version, "Agent version", Appsignal::Extension.agent_version
328
- puts_and_save :agent_architecture, "Agent architecture",
329
- Appsignal::System.installed_agent_architecture
330
331
  puts_and_save :extension_loaded, "Extension loaded", Appsignal.extension_loaded
331
332
  end
332
333
  end
333
334
 
335
+ def fetch_installation_report
336
+ path = File.expand_path("../../../../ext/install.report", __FILE__)
337
+ raw_report = File.read(path)
338
+ Utils.parse_yaml(raw_report)
339
+ rescue => e
340
+ {
341
+ "parsing_error" => {
342
+ "error" => "#{e.class}: #{e}",
343
+ "backtrace" => e.backtrace
344
+ }.tap do |r|
345
+ r["raw"] = raw_report if raw_report
346
+ end
347
+ }
348
+ end
349
+
350
+ def print_installation_report
351
+ puts "\nExtension installation report"
352
+ install_report = data[:installation]
353
+ if install_report.key? "parsing_error"
354
+ print_installation_report_parsing_error(install_report)
355
+ return
356
+ end
357
+
358
+ print_installation_result_report(install_report)
359
+ print_installation_language_report(install_report)
360
+ print_installation_download_report(install_report)
361
+ print_installation_build_report(install_report)
362
+ print_installation_host_report(install_report)
363
+ end
364
+
365
+ def print_installation_report_parsing_error(report)
366
+ report = report["parsing_error"]
367
+ puts " Error found while parsing the report."
368
+ puts " Error: #{report["error"]}"
369
+ puts " Raw report:\n#{report["raw"]}" if report["raw"]
370
+ end
371
+
372
+ def print_installation_result_report(report)
373
+ report = report.fetch("download", {})
374
+ puts " Installation result"
375
+ puts " Status: #{report["status"]}"
376
+ puts " Message: #{report["message"]}" if report["message"]
377
+ puts " Error: #{report["error"]}" if report["error"]
378
+ end
379
+
380
+ def print_installation_language_report(report)
381
+ report = report.fetch("language", {})
382
+ puts " Language details"
383
+ puts " Implementation: #{report["implementation"]}"
384
+ puts " Ruby version: #{report["version"]}"
385
+ end
386
+
387
+ def print_installation_download_report(report)
388
+ report = report.fetch("download", {})
389
+ puts " Download details"
390
+ puts " Download URL: #{report["download_url"]}"
391
+ puts " Checksum: #{report["checksum"]}"
392
+ end
393
+
394
+ def print_installation_build_report(report)
395
+ report = report.fetch("build", {})
396
+ puts " Build details"
397
+ puts " Install time: #{report["time"]}"
398
+ puts " Architecture: #{report["architecture"]}"
399
+ puts " Target: #{report["target"]}"
400
+ puts " Musl override: #{report["musl_override"]}"
401
+ puts " Library type: #{report["library_type"]}"
402
+ puts " Source: #{report["source"]}" if report["source"] != "remote"
403
+ puts " Dependencies: #{report["dependencies"]}"
404
+ puts " Flags: #{report["flags"]}"
405
+ end
406
+
407
+ def print_installation_host_report(report)
408
+ report = report.fetch("host", {})
409
+ puts " Host details"
410
+ puts " Root user: #{report["root_user"]}"
411
+ puts " Dependencies: #{report["dependencies"]}"
412
+ end
413
+
334
414
  def host_information
335
415
  rbconfig = RbConfig::CONFIG
336
416
  puts "Host information"
@@ -349,7 +429,7 @@ module Appsignal
349
429
  save :heroku, Appsignal::System.heroku?
350
430
 
351
431
  save :root, Process.uid.zero?
352
- puts_value "root user",
432
+ puts_value "Root user",
353
433
  Process.uid.zero? ? "true (not recommended)" : "false"
354
434
  puts_and_save :running_in_container, "Running in container",
355
435
  Appsignal::Extension.running_in_container?
@@ -17,7 +17,6 @@ module Appsignal
17
17
  begin
18
18
  config = Appsignal.config
19
19
  log_file_path = config.log_file_path
20
- install_log_path = File.join("ext", "install.log")
21
20
  makefile_log_path = File.join("ext", "mkmf.log")
22
21
  {
23
22
  :package_install_path => {
@@ -36,10 +35,6 @@ module Appsignal
36
35
  :label => "Log directory",
37
36
  :path => log_file_path ? File.dirname(log_file_path) : ""
38
37
  },
39
- install_log_path => {
40
- :label => "Extension install log",
41
- :path => File.join(gem_path, install_log_path)
42
- },
43
38
  makefile_log_path => {
44
39
  :label => "Makefile install log",
45
40
  :path => File.join(gem_path, makefile_log_path)
@@ -6,12 +6,14 @@ module Appsignal
6
6
  passwd_struct = Etc.getpwuid(uid)
7
7
  return unless passwd_struct
8
8
  passwd_struct.name
9
+ rescue ArgumentError # rubocop:disable Lint/HandleExceptions
9
10
  end
10
11
 
11
12
  def self.group_for_gid(gid)
12
13
  passwd_struct = Etc.getgrgid(gid)
13
14
  return unless passwd_struct
14
15
  passwd_struct.name
16
+ rescue ArgumentError # rubocop:disable Lint/HandleExceptions
15
17
  end
16
18
 
17
19
  def self.read_file_content(path, bytes_to_read)
@@ -30,6 +32,23 @@ module Appsignal
30
32
 
31
33
  IO.binread(path, length, offset)
32
34
  end
35
+
36
+ def self.parse_yaml(contents)
37
+ arguments = [contents]
38
+ if YAML.respond_to? :safe_load
39
+ method = :safe_load
40
+ arguments << \
41
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.6.0")
42
+ # Use keyword params for Ruby 2.6 and up
43
+ { :permitted_classes => [Time] }
44
+ else
45
+ [Time]
46
+ end
47
+ else
48
+ method = :load
49
+ end
50
+ YAML.send(method, *arguments)
51
+ end
33
52
  end
34
53
  end
35
54
  end
@@ -1,10 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "appsignal/utils/rails_helper"
4
+
3
5
  module Appsignal
4
6
  class CLI
5
7
  module Helpers
6
8
  private
7
9
 
10
+ def ruby_2_6_or_up?
11
+ Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.6.0")
12
+ end
13
+
8
14
  def colorize(text, color)
9
15
  return text if Gem.win_platform?
10
16
 
@@ -75,19 +75,39 @@ module Appsignal
75
75
  def install_for_rails(config)
76
76
  puts "Installing for Ruby on Rails"
77
77
 
78
- require File.expand_path(File.join(Dir.pwd, "config/application.rb"))
78
+ name_overwritten = configure_rails_app_name(config)
79
+ configure(config, rails_environments, name_overwritten)
80
+ done_notice
81
+ end
79
82
 
80
- config[:name] = Rails.application.class.parent_name
83
+ def configure_rails_app_name(config)
84
+ loaded =
85
+ begin
86
+ load Appsignal::Utils::RailsHelper.application_config_path
87
+ true
88
+ rescue LoadError, StandardError
89
+ false
90
+ end
81
91
 
82
- name_overwritten = yes_or_no(" Your app's name is: '#{config[:name]}' \n Do you want to change how this is displayed in AppSignal? (y/n): ")
83
- puts
84
- if name_overwritten
85
- config[:name] = required_input(" Choose app's display name: ")
92
+ name_overwritten = false
93
+ if loaded
94
+ config[:name] = Appsignal::Utils::RailsHelper.detected_rails_app_name
95
+ puts
96
+ name_overwritten = yes_or_no(
97
+ " Your app's name is: '#{config[:name]}' \n " \
98
+ "Do you want to change how this is displayed in AppSignal? " \
99
+ "(y/n): "
100
+ )
101
+ if name_overwritten
102
+ config[:name] = required_input(" Choose app's display name: ")
103
+ puts
104
+ end
105
+ else
106
+ puts " Unable to automatically detect your Rails app's name."
107
+ config[:name] = required_input(" Choose your app's display name for AppSignal.com: ")
86
108
  puts
87
109
  end
88
-
89
- configure(config, rails_environments, name_overwritten)
90
- done_notice
110
+ name_overwritten
91
111
  end
92
112
 
93
113
  def install_for_sinatra(config)
@@ -228,7 +248,10 @@ module Appsignal
228
248
 
229
249
  def installed_frameworks
230
250
  [].tap do |out|
231
- out << :rails if framework_available? "rails"
251
+ if framework_available?("rails") &&
252
+ File.exist?(Appsignal::Utils::RailsHelper.application_config_path)
253
+ out << :rails
254
+ end
232
255
  out << :sinatra if framework_available? "sinatra"
233
256
  out << :padrino if framework_available? "padrino"
234
257
  out << :grape if framework_available? "grape"
@@ -249,12 +272,19 @@ module Appsignal
249
272
  end
250
273
 
251
274
  def write_config_file(data)
252
- template = ERB.new(
253
- File.read(File.join(File.dirname(__FILE__), "../../../resources/appsignal.yml.erb")),
254
- nil,
255
- "-"
275
+ filename = File.join(
276
+ File.dirname(__FILE__),
277
+ "../../../resources/appsignal.yml.erb"
256
278
  )
257
-
279
+ file_contents = File.read(filename)
280
+ arguments = [file_contents]
281
+ if ruby_2_6_or_up?
282
+ arguments << { :trim_mode => "-" }
283
+ else
284
+ arguments << nil
285
+ arguments << "-"
286
+ end
287
+ template = ERB.new(*arguments)
258
288
  config = template.result(OpenStruct.new(data).instance_eval { binding })
259
289
 
260
290
  FileUtils.mkdir_p(File.join(Dir.pwd, "config"))
@@ -60,6 +60,8 @@ module Appsignal
60
60
  # Terminology: Deploy marker
61
61
  class NotifyOfDeploy
62
62
  class << self
63
+ include Appsignal::Utils::DeprecationMessage
64
+
63
65
  # @param options [Hash]
64
66
  # @option options :environment [String] environment to load
65
67
  # configuration for.
@@ -85,6 +87,14 @@ module Appsignal
85
87
  },
86
88
  config
87
89
  ).transmit
90
+
91
+ puts
92
+ message = "This command (appsignal notify_of_deploy) has been " \
93
+ "deprecated in favor of the `revision` config option. Please " \
94
+ "see our documentation for more information on the recommended " \
95
+ "method: " \
96
+ "https://docs.appsignal.com/application/markers/deploy-markers.html"
97
+ deprecation_message message, Appsignal.logger
88
98
  end
89
99
 
90
100
  private
@@ -36,7 +36,7 @@ module Appsignal
36
36
  :enable_allocation_tracking => true,
37
37
  :enable_gc_instrumentation => false,
38
38
  :enable_host_metrics => true,
39
- :enable_minutely_probes => false,
39
+ :enable_minutely_probes => true,
40
40
  :ca_file_path => File.expand_path(File.join("../../../resources/cacert.pem"), __FILE__),
41
41
  :dns_servers => [],
42
42
  :files_world_accessible => true
@@ -214,7 +214,6 @@ module Appsignal
214
214
  ENV["_APPSIGNAL_WORKING_DIR_PATH"] = config_hash[:working_dir_path] if config_hash[:working_dir_path]
215
215
  ENV["_APPSIGNAL_WORKING_DIRECTORY_PATH"] = config_hash[:working_directory_path] if config_hash[:working_directory_path]
216
216
  ENV["_APPSIGNAL_ENABLE_HOST_METRICS"] = config_hash[:enable_host_metrics].to_s
217
- ENV["_APPSIGNAL_ENABLE_MINUTELY_PROBES"] = config_hash[:enable_minutely_probes].to_s
218
217
  ENV["_APPSIGNAL_HOSTNAME"] = config_hash[:hostname].to_s
219
218
  ENV["_APPSIGNAL_PROCESS_NAME"] = $PROGRAM_NAME
220
219
  ENV["_APPSIGNAL_CA_FILE_PATH"] = config_hash[:ca_file_path].to_s
@@ -75,16 +75,15 @@ module Appsignal
75
75
 
76
76
  def initialize_formatter(name, formatter)
77
77
  format_method = formatter.instance_method(:format)
78
- if format_method && format_method.arity == 1
79
- formatter_classes[name] = formatter
80
- formatters[name] = formatter.new
81
- else
78
+ if !format_method || format_method.arity != 1
82
79
  raise "#{formatter} does not have a format(payload) method"
83
80
  end
81
+ formatter_classes[name] = formatter
82
+ formatters[name] = formatter.new
84
83
  rescue => ex
85
84
  formatter_classes.delete(name)
86
85
  formatters.delete(name)
87
- logger.warn("'#{ex.message}' when initializing #{name} event formatter")
86
+ logger.error("'#{ex.message}' when initializing #{name} event formatter")
88
87
  end
89
88
 
90
89
  def register_deprecated_formatter(name)
@@ -22,11 +22,13 @@ module Appsignal
22
22
  end
23
23
  end
24
24
 
25
- Appsignal::EventFormatter.register(
26
- "render_partial.action_view",
27
- Appsignal::EventFormatter::ActionView::RenderFormatter
28
- )
29
- Appsignal::EventFormatter.register(
30
- "render_template.action_view",
31
- Appsignal::EventFormatter::ActionView::RenderFormatter
32
- )
25
+ if defined?(Rails)
26
+ Appsignal::EventFormatter.register(
27
+ "render_partial.action_view",
28
+ Appsignal::EventFormatter::ActionView::RenderFormatter
29
+ )
30
+ Appsignal::EventFormatter.register(
31
+ "render_template.action_view",
32
+ Appsignal::EventFormatter::ActionView::RenderFormatter
33
+ )
34
+ end
@@ -6,65 +6,66 @@ module Appsignal
6
6
  module Moped
7
7
  class QueryFormatter
8
8
  def format(payload)
9
- if payload[:ops] && !payload[:ops].empty?
10
- op = payload[:ops].first
11
- case op.class.to_s
12
- when "Moped::Protocol::Command"
13
- [
14
- "Command", {
15
- :database => op.full_collection_name,
16
- :selector => sanitize(op.selector, true, :mongodb)
17
- }.inspect
18
- ]
19
- when "Moped::Protocol::Query"
20
- [
21
- "Query", {
22
- :database => op.full_collection_name,
23
- :selector => sanitize(op.selector, false, :mongodb),
24
- :flags => op.flags,
25
- :limit => op.limit,
26
- :skip => op.skip,
27
- :fields => op.fields
28
- }.inspect
29
- ]
30
- when "Moped::Protocol::Delete"
31
- [
32
- "Delete", {
33
- :database => op.full_collection_name,
34
- :selector => sanitize(op.selector, false, :mongodb),
35
- :flags => op.flags
36
- }.inspect
37
- ]
38
- when "Moped::Protocol::Insert"
39
- [
40
- "Insert", {
41
- :database => op.full_collection_name,
42
- :documents => sanitize(op.documents, true, :mongodb),
43
- :count => op.documents.count,
44
- :flags => op.flags
45
- }.inspect
46
- ]
47
- when "Moped::Protocol::Update"
48
- [
49
- "Update",
50
- {
51
- :database => op.full_collection_name,
52
- :selector => sanitize(op.selector, false, :mongodb),
53
- :update => sanitize(op.update, true, :mongodb),
54
- :flags => op.flags
55
- }.inspect
56
- ]
57
- when "Moped::Protocol::KillCursors"
58
- [
59
- "KillCursors",
60
- { :number_of_cursor_ids => op.number_of_cursor_ids }.inspect
61
- ]
62
- else
63
- [
64
- op.class.to_s.sub("Moped::Protocol::", ""),
65
- { :database => op.full_collection_name }.inspect
66
- ]
67
- end
9
+ return unless payload[:ops]
10
+ return if payload[:ops].empty?
11
+
12
+ op = payload[:ops].first
13
+ case op.class.to_s
14
+ when "Moped::Protocol::Command"
15
+ [
16
+ "Command", {
17
+ :database => op.full_collection_name,
18
+ :selector => sanitize(op.selector, true, :mongodb)
19
+ }.inspect
20
+ ]
21
+ when "Moped::Protocol::Query"
22
+ [
23
+ "Query", {
24
+ :database => op.full_collection_name,
25
+ :selector => sanitize(op.selector, false, :mongodb),
26
+ :flags => op.flags,
27
+ :limit => op.limit,
28
+ :skip => op.skip,
29
+ :fields => op.fields
30
+ }.inspect
31
+ ]
32
+ when "Moped::Protocol::Delete"
33
+ [
34
+ "Delete", {
35
+ :database => op.full_collection_name,
36
+ :selector => sanitize(op.selector, false, :mongodb),
37
+ :flags => op.flags
38
+ }.inspect
39
+ ]
40
+ when "Moped::Protocol::Insert"
41
+ [
42
+ "Insert", {
43
+ :database => op.full_collection_name,
44
+ :documents => sanitize(op.documents, true, :mongodb),
45
+ :count => op.documents.count,
46
+ :flags => op.flags
47
+ }.inspect
48
+ ]
49
+ when "Moped::Protocol::Update"
50
+ [
51
+ "Update",
52
+ {
53
+ :database => op.full_collection_name,
54
+ :selector => sanitize(op.selector, false, :mongodb),
55
+ :update => sanitize(op.update, true, :mongodb),
56
+ :flags => op.flags
57
+ }.inspect
58
+ ]
59
+ when "Moped::Protocol::KillCursors"
60
+ [
61
+ "KillCursors",
62
+ { :number_of_cursor_ids => op.number_of_cursor_ids }.inspect
63
+ ]
64
+ else
65
+ [
66
+ op.class.to_s.sub("Moped::Protocol::", ""),
67
+ { :database => op.full_collection_name }.inspect
68
+ ]
68
69
  end
69
70
  end
70
71