【问题标题】:Include params/request information in Rails logger?在 Rails 记录器中包含参数/请求信息?
【发布时间】:2011-02-09 16:35:41
【问题描述】:

我正在尝试在我的 Rails 日志中获取更多信息,特别是请求的 URI 或当前参数(如果可用)(我很感激它们不会总是如此)。但是我似乎无法做到。这是我到目前为止所做的:

#config/environments/production.rb
config.logger = Logger.new(config.log_path)
config.log_level = :error
config.logger.level = Logger::ERROR

#config/environment.rb
class Logger
  def format_message(level, time, progname, msg)
    "**********************************************************************\n#{level} #{time.to_s(:db)} -- #{msg}\n"
  end  
end

所以我可以很好地自定义消息,但我似乎无法在此处访问参数/请求变量。有谁知道这是否可行,如果可以,怎么办?或者是否有更好的方法来获取这些信息? (甚至可能是基于 Redis 的东西?)

谢谢你,

【问题讨论】:

    标签: ruby-on-rails ruby params logging


    【解决方案1】:

    你应该查看请求类

    like puts request.uri。

    点击这里了解更多详情http://api.rubyonrails.org/classes/ActionController/AbstractRequest.html

    【讨论】:

    • 感谢副总裁,但它似乎不起作用。我相信,因为 Logger 是在大多数 Rails 加载之前配置的,所以它无法访问 @env 变量,或者实际上是 params/request 变量。 @env 在 format_message 范围内为零,请求也是如此,因此 request_uri 也会出错。
    【解决方案2】:

    这应该可以! :) 干杯。

    logger.info({:user_agent => request.user_agent, :remote_ip => request.remote_ip}.inspect)

    logger.info(params.inspect)

    by by.. 这应该放在您的控制器操作中。例如:如果您将它放在 create 操作中,它还应该记录 user_agent 即浏览器、remote_ip 即用户的远程 ip 和所有参数。

    【讨论】:

    • 嗨,帕迪,谢谢。虽然这可行,但有没有办法自动让记录器本身可以使用请求/参数? IE。如果不是我从控制器调用 logger.info/warn/error,而是从代码中任何地方引发的异常调用它。例如。我可能在代码中随意调用 current_user.profesion.blank?这会出错,因为专业应该是专业(nil 等未定义的函数)。在日志中包含 url/current 参数以及堆栈跟踪会很棒。
    • 我试过了。但是正如您所说,在加载 Rails 之前配置了 Logger。我发现了这篇我真的不知道它有多大帮助的文章:ubuntusolutions.org/2009/08/custom-logger-in-rails.html
    • 是的。反过来,它可能是以某种方式扩展首先调用 Raise/logger 的类/代码,以便在 msg 中添加一些额外的数据?甚至只是某个地方的 ActionController?
    • 这可能有助于解决参数问题。但是还是太啰嗦了。 ActionController::Base.logger = Logger.new(STDOUT)
    【解决方案3】:

    (在被问到这个问题后很久才回复,但也许它会帮助下一个人。)

    我刚刚做了类似的事情。

    1) 您需要独立于记录请求级别的详细信息来覆盖您的记录器。看起来你已经想出定制你的记录器了。答案在这里: Rails logger format string configuration

    2) 我将所有请求的请求和响应记录到我的服务中。请注意,Rails 将大量内容放入标头中,因此直接转储请求或标头可能是个坏主意。另外值得注意的是,我的应用程序主要是通过 API 访问的。如果你的主要是一个网络应用程序,我猜大多数人都是,你可能不想检查 response.body ,因为它会包含你的 html。

    class ApplicationController < ActionController::Base 
      around_filter :global_request_logging
    ...
      def global_request_logging 
        http_request_header_keys = request.headers.keys.select{|header_name| header_name.match("^HTTP.*")}
        http_request_headers = request.headers.select{|header_name, header_value| http_request_header_keys.index(header_name)}
        logger.info "Received #{request.method.inspect} to #{request.url.inspect} from #{request.remote_ip.inspect}.  Processing with headers #{http_request_headers.inspect} and params #{params.inspect}"
        begin 
          yield 
        ensure 
          logger.info "Responding with #{response.status.inspect} => #{response.body.inspect}"
        end 
      end 
    end
    

    【讨论】:

    • 这正是我想要的。工作得很好。谢谢。
    • 这个反应太棒了!谢谢
    • 实际上它只在从request.headers 更改为request.headers.env 时才对我有用。 (我正在使用 Rails 4)。提出了修改建议。
    • 我认为您想将 ("^HTTP.*") 更改为 (/^HTTP.*/) 但我也很好奇为什么您只匹配以 HTTP 开头的标头,而不是说 rails 增加了很多的标题。 rails 不添加的所有 headers 是否都以 HTTP 开头?
    • String#match 对任一语法 ruby-doc.org/core-2.4.0/String.html#method-i-match 均有效。而且,是的,rails 在里面放了很多实际上并没有通过电线的东西。当时,不,我不知道来自客户端的任何标头都没有以 HTTP 为前缀。 YMMV
    猜你喜欢
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 2015-04-11
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-28
    相关资源
    最近更新 更多