Отладка в метод из производства IRB

Когда я ищу проблему, например, с конкретным объектом ActiveRecord, я часто обнаруживаю, что выполняю в своей производственной системе следующее:

# RAILS_ENV=production bundle exec

irb(main)> article = Article.find(123)
=> #<Article id: 123, title: "Foobar">
irb(main)> article.do_something(3)
NoMethodError: undefined method `id' for nil:NilClass

Иногда я не могу воспроизвести, почему линия article.do_something(3) выдает ошибку, поэтому я хочу отладить ее прямо на моем сервере, в производственном режиме.

Проблема сейчас в следующем: как мне войти в метод #do_something с аргументом 3 на объекте / экземпляре article?

Конечно, в этом методе можно установить точку останова, перезагрузить производство и позволить всем своим клиентам подождать на этой точке останова, пока я не закончу отладку... Но это не лучшая идея.

Итак, есть ли способ отладки в методе конкретного экземпляра из запущенного сеанса irb / pry? (оба были бы в порядке)

6 ответов

Решение

После того, как я попробовал все больше и больше гуглить, я думаю, что нашел решение, которое работает для меня.

  1. Войдите в вашу консоль rails console / irb / pry session
  2. Настройте ваш случай (например, загрузите ваши модели, требуйте зависимостей...), чтобы вы могли выполнить код, который вы хотите отлаживать, в одну строку
  3. require 'byebug' (или же require 'debugger' для старых версий ruby)
  4. Теперь интересная часть: поместите оператор отладчика перед строкой, которую вы хотите отлаживать, вот так binding.pry; user.do_something или же debugger; user.do_something
  5. Теперь вы в своем отладчике. Может быть, вам нужно перейти к следующей строке с next (или просто n если у вас включены ярлыки), чтобы перейти к вашему методу.

Вот полный пример из нашей производственной системы:

[1] pry(main)> require 'byebug'
=> true
[2] pry(main)> user = User.find(2)
  User Load (0.3ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
=> #<User id: 2, name="XXX XXX">
[3] pry(main)> user.full_name
NameError: undefined local variable or method address for #<User:0x0055b168663590>

[4] pry(main)> binding.pry; user.full_name

[68, 73] in /usr/src/app/app/models/user.rb
   68:   end
   69: 
   70:   def full_name
=> 71:     "#{address.firstname} #{address.last_name}"
   72:   end
   73: end
(byebug) 

Конечно, pry, byebug и т. д. — это круто, НО вам не нужна жемчужина.

Ruby 3 (и более новые версии Ruby 2.x) имеет встроенную отладку irb.

      require 'irb'

def run
  a = "hello"
  binding.irb # debug starts here, eg puts a
  a = "something else"
  a
end

run

Отладка на вашем рабочем сервере - ужасная идея. Исходя из мира PHP, мы привыкли делать это все время, и все будет впечатляюще, и только если вам повезет, будет резервная копия базы данных.

Вместо этого вы можете настроить промежуточный сервер - это сервер, работающий на той же платформе с точно такими же настройками. Вы можете даже использовать cron вместе с pg_backups ежедневно зеркалировать производственную базу данных, чтобы вы могли опробовать новые функции и даже показать их сотрудникам. И если он взорвется, то это не конец света - и нет риска потери данных конечного пользователя.

Но вы можете подумать, что на самом деле вы должны писать тесты, а не использовать точки останова или журналы. Напишите тест, который повторяет проблему и определяет желаемое поведение. Затем вы можете поиграть с кодом и узнать из состояния теста, работает ли то, что вы делаете.

Вы можете использовать pry-debugger (через ruby ​​1.9.3) или pry-byebug (Ruby >= 2).

Оба из них позволяют вам устанавливать точки останова, позволяя в интерактивном режиме выполнять пошаговый просмотр кода, проверять значения переменных, возвращаемые значения методов и т. Д.

Как вы справитесь с производственными данными, я не совсем уверен, но это позволит вам отлаживать определенный метод.

Вы можете изменить код на вашем производстве, чтобы поставить значение, которое вы хотите проверить в #do_something метод и бег irb проверить это. Потому что мы не перезагружаем производственный сервер, поэтому не беспокойтесь о ваших изменениях.

Вы можете пойти простым путем, и попробуйте сделать отладку через puts, Вы можете добавить как можно больше puts внутри вашего метода, как вам нужно, перед каждой возможной строкой может возникнуть проблема

Другие вопросы по тегам