【问题标题】:Debug into method from production irb从生产 irb 调试到方法
【发布时间】:2016-04-20 14:29:16
【问题描述】:

当我查找问题时,例如使用特定的 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)这行会报错,所以我想直接在我的服务器上调试,在生产模式下。

现在的问题是:如何在对象/实例article 上使用参数3 进入方法#do_something

当然,可以在该方法中设置断点,重新加载生产,然后让所有客户在该断点上等待,直到我完成调试...但这不是最好的主意。

那么,有没有办法从正在运行的 irb / pry 会话中调试到特定实例的方法? (两者都可以)

【问题讨论】:

    标签: ruby-on-rails ruby debugging irb byebug


    【解决方案1】:

    在尝试和更多谷歌搜索之后,我想我找到了一个适合我的解决方案。

    1. 登录到您的 Rails 控制台/irb/pry 会话
    2. 设置您的案例(例如加载您的模型、需要依赖项...),以便您可以在一行中执行要调试的代码
    3. require 'byebug'(或 require 'debugger' 用于旧 ruby​​ 版本)
    4. 现在有趣的部分:在你想调试的行前面放一个调试器语句,像 binding.pry; user.do_somethingdebugger; 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) 
    

    【讨论】:

    • 对不起,如果我听起来像一个漏洞,但这里最可能的解释是您忘记在生产中运行迁移。如果您发现自己很难记住运行迁移(我们都这样做),您可以使用运行 rake db:status 的 post commit hook 作为提醒。
    • 该错误仅用于演示目的,并非真正的错误。问题是如何从 irb / pry / rails 控制台上下文中使用调试器进入该方法
    • 非常聪明,喜欢它!
    【解决方案2】:

    在您的生产服务器中进行调试是一个可怕的想法。来自 PHP 世界,我们过去一直这样做,而且事情会爆炸性地发生,而且只有当你幸运地有数据库备份时。

    相反,您可以设置一个临时服务器 - 这将是一个在完全相同的平台上运行且具有完全相同的设置的服务器。您甚至可以使用 cron 和 pg_backups 每天镜像生产数据库,以便您可以尝试新功能,甚至向合作者展示它们。如果它爆炸了,那也不是世界末日 - 也不会有丢失最终用户数据的风险。

    但您可能会认为您实际上应该编写测试而不是使用断点或日志。编写一个复制问题并指定所需行为的测试。然后,您可以玩弄代码,并从测试状态中知道您正在做的事情是否有效。

    【讨论】:

    • 正如我所写的,有时您无法在测试或机器上重现错误,有时您必须在生产系统上进行调试。我知道这是一个坏主意,但没有选择,我不得不这样做。我们有测试,一个开发和一个临时环境,但是当错误被抛出到生产环境时,如果你不能在它们上重现它,这个环境就不是很有帮助。因此,生产调试是最后的选择
    【解决方案3】:

    您可以使用 pry-debugger(通过 ruby​​ 1.9.3)或 pry-byebug (Ruby >= 2)。

    这两者都允许您设置断点,从而允许您在代码运行时以交互方式单步执行代码、检查变量值、方法返回值等。

    您将如何使用生产数据进行管理我不太确定,但这将允许您调试特定方法。

    【讨论】:

      猜你喜欢
      • 2019-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-29
      • 2011-04-24
      • 1970-01-01
      • 1970-01-01
      • 2019-05-09
      相关资源
      最近更新 更多