【问题标题】:Full URLs in Rails logsRails 日志中的完整 URL
【发布时间】:2011-08-27 11:14:15
【问题描述】:

是否可以在 Rails 应用程序的日志中获取完整的 URL?目前我得到的是这样的:

在 2011-08-27 13:13:10 +0200 开始为 127.0.0.1 获取“/”

但我需要得到:

在 2011-08-27 13:13:10 +0200 开始 GET "http://localhost:3000/" for 127.0.0.1

因为这是一个域名很重要的应用。

【问题讨论】:

    标签: ruby-on-rails ruby logging dns hostname


    【解决方案1】:

    该行来自中间件Rails::Rack::Logger,它位于railties 中。最简单的情况是,您可以覆盖执行日志记录的方法,例如,在初始化程序中:

    class Rails::Rack::Logger < ActiveSupport::LogSubscriber
      protected
    
      def before_dispatch(env)
        request = ActionDispatch::Request.new(env)
        info "\n\nStarted #{request.request_method} \"#{request.url}\" for #{request.ip} at #{Time.now.to_default_s}"
      end
    end
    

    如果您不想覆盖记录器,您可以随时添加您自己的记录器(您已经创建),然后通过以下方式从堆栈中删除 Rails::Rack::Logger

    config.middleware.insert_before(Rails::Rack::Logger, YourLogger)
    config.middleware.delete(Rails::Rack::Logger)
    

    如果你走这条路,你可能会检查机架记录器以了解其对ActionDispatch::Request 的使用情况,并确保通过ActiveSupport::LogSubscriber.flush_all! 完成调度后刷新日志订阅者缓存的另一项工作

    【讨论】:

    • 我将这个 sn-p 应用到我的 rails 项目中,它在我的开发环境中运行良好,但在生产环境中却不行。还是不知道为什么
    • 只是猜测,但您的生产日志级别是否高于info?值得注意的是,这个答案不再是最新的。从那以后,机架记录器发生了变化。
    • 如果你用 call_app 替换 before_dispatch 它将在 Rails 3.2.x 中工作
    【解决方案2】:

    我认为如果不更改 Rails 本身就无法做到这一点,这并不好,但你可以添加自己的日志调用:

    class ApplicationController < ActionController::Base
    
      before_filter :log_request
    
      protected
    
      def log_request
        logger.info("Started #{request.method} #{request.url}")
      end    
    
    end
    

    【讨论】:

    • 我看到这个解决方案的唯一缺点是自定义日志行不在主日志行旁边,它不会记录图像、javascript等。我不确定后者是否以后在项目中会成为一个更复杂的问题。
    【解决方案3】:

    从 Rails 3.2.12 开始,不再对 before_dispatch 或 call_app 进行猴子修补,现在有一个方法可以接收请求并返回 Started GET "/session/new" for 127.0.0.1 at 2012-09-26 14:51:42 -0700 位。

    因此,您可以在自己的记录器或猴子补丁中仅覆盖该方法。

    # or "class Rails::Rack::Logger < ActiveSupport::LogSubscriber" for monkey patch
    class URLLogger < Rails::Rack::Logger 
    
      def started_request_message(request)
        'Started %s "%s%s%s" for %s at %s' % [
          request.request_method,
          request.protocol,
          request.host_with_port,
          request.filtered_path,
          request.ip,
          Time.now.to_default_s ]
      end
    end
    

    如果你子类别忘了修改config/application.rb中的中间件链(并确保URLLogger在配置块之前加载):

    config.middleware.insert_before(Rails::Rack::Logger, URLLogger)
    config.middleware.delete(Rails::Rack::Logger)
    

    【讨论】:

      【解决方案4】:

      我现在使用的解决方法是创建此类:

      class HostnameLogger
        def initialize(app)
          @app = app
        end
      
        def call(env)
          uri = env["REQUEST_URI"]
          if uri.blank? # While testing a Rails app, there's no env["REQUEST_UIR"] defined.
            uri = "http://#{env["HTTP_HOST"]}#{env["PATH_INFO"]}"
          end
          Rails.logger.info "Started #{env["REQUEST_METHOD"]} \"#{uri}\" for #{env["REMOTE_ADDR"]} at #{Time.now}"
          @app.call(env)
        end
      end
      

      然后将其添加为 Rack 中间件(在 application.rb 中):

      config.middleware.use "HostnameLogger"
      

      所以我明白了:

      在 2011-08-27 15:33:40 +0200 开始 GET "/users/login" for 127.0.0.1

      在 2011-08-27 15:33:40 +0200 开始 GET "http://localhost:3000/users/login" for 127.0.0.1

      【讨论】:

        【解决方案5】:
        Rails::Rack::Logger.class_eval do
          protected
          def started_request_message(request)
            "Started #{request.request_method} \"#{request.url}\" for #{request.ip} at #{Time.now.to_default_s}"
          end
        end
        

        【讨论】:

          猜你喜欢
          • 2014-02-03
          • 2014-04-09
          • 2011-03-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-23
          相关资源
          最近更新 更多