我正在将Apartment gem用于多租户Rails 5.2应用程序。我不确定这对我的问题是否重要,只是给出一些背景信息即可。
是否有一种方法可以覆盖Rails记录器并将每个单个日志条目重定向到基于正在使用的租户(数据库)的文件?
思考...我有什么方法可以在Logger中进行猴子补丁修改,以动态更改写入的文件?
示例:我希望当天将所有错误消息定向到一个文件。因此,在一周结束时,将有7个动态生成的文件,用于记录在每个特定日期发生的错误。
另一个示例:在编写任何服务器日志消息之前,请检查是否在下午1点之前。如果在下午1点之前将其写入/log/before_1.log ...如果在下午1点之后将其写入/log/after_1.log
愚蠢的例子...但是我想在写任何日志行之前进行这种动态控制。
谢谢!
答案 0 :(得分:1)
通常情况下,记录器通常是按服务器(或实际上是每个环境)配置的,而公寓则根据请求设置租户-这意味着在实践中,记录器实际上不能很好地工作。
您可以随时通过将Rails.logger
分配给记录器实例来设置记录器。
Rails.logger = Logger.new(Rails.root.join('log/foo.log'), File::APPEND)
# or for multiple loggers
Rails.logger.extend(Logger.new(Rails.root.join('log/foo.log'), File::APPEND))
但是它不是那么简单-您不能将其扔到ApplicationController
中并认为所有内容都是笨拙的-它将被称为延迟方式,并且大多数条目都带有重要内容,例如请求或在控制器之前弹出的所有错误将最终显示在默认日志中。
您可以做的是编写here的自定义片段,以切换日志:
# app/middleware/tenant_logger.rb
class TenantLogger
def initialize app
@app = app
end
def call(env)
file_name = "#{Appartment::Tenant.current}.log"
Rails.logger = Logger.new(Rails.root.join('log', file_name), File::APPEND)
@app.call(env)
end
end
并将其安装在中间件堆栈中的“电梯”之后:
Rails.application.config.middleware.insert_after Apartment::Elevators::Subdomain, TenantLogger
尽管这在中间件堆栈中还算很低,您仍然会错过很多由中间件记录的重要信息,例如Rails::Rack::Logger
。
使用Rails指南建议的带标签的记录器使用单个文件是更好的解决方案。