为日志格式化Rails模型的最佳技术是什么?

时间:2014-12-12 16:32:51

标签: ruby-on-rails ruby logging model formatting

因此我们需要记录Rails应用程序中发生的事情:

logger.info("Created zone #{zone} for user #{user}.")

zoneuser是标准模型,即ActiveRecord::Base派生类的对象。默认输出不是很有用:

Created zone #<Zone:0x007f93b3709498> for user #<User:0x007f93b3509418>.

出于调试目的,至少输出模型id是有意义的。看到一些关键属性(其中一组因模型而异)也很高兴,例如user.namezone.area

inspect会有些过分,因为我们的一些模型(包含User)有许多非关键属性,这些属性不会立即生效,只会使日志混乱。

覆盖to_s感觉不对,因为模型应关注其状态,而不是表示。此外,这种“短期检查”只是在日志中需要的,而不是我们想要输出模型的每个时间。

为日志格式化Rails模型的最佳方法是什么?

1 个答案:

答案 0 :(得分:2)

我的直接想法是:

  1. 你为什么要记录这些?
  2. 如果这个日志很重要,您对此日志的要求是什么?
  3. 这些将引导您朝着您需要的方向前进。如果你想使用这样的字符串插值,to_s就是所谓的。

    要将信息保留在模型之外,您可以使用concerns将其混合在一起:

    # app/models/concerns/user/log_format.rb
    module Concerns::User::LogFormat
      extend ActiveSupport::Concern
      def to_log_format
        "Hey I'm a User and I have some #{attributes}!"
      end
    end
    

    将其混合到User

    class User < ActiveRecord::Base
      include Concerns::User::LogFormat
    end
    

    然后你可以打开Logger并添加一个聪明的方法:

    class ActiveSupport::Logger
      def log_models(level, message, *args)
        args = args.map { |arg| arg.try(:to_log_format) || arg }
        self.send(level, sprintf(message, *args))
      end
    end
    

    然后你可以打电话给它:

    user = ...
    zone = ...
    logger.log_models(:info, "Created zone %s for user %s.", zone, user)
    

    似乎还有很长的路要走,记录一堆信息,目的是什么?如果您有特定目的,可能一般的应用程序日志不适合这样做。

相关问题