Suppressing SQL logging in production

Hi everyone.

I would like to choose logger for production.
I see sql queries in logs and it’s not good.
I use lograge for rails application but, as I understand, it’s not usable for hanami.
Сan you give me advice for to config logger for prod correctly?

I checked logger

 app["db.config"].gateways[:default].logger
=> nil

it is nil

But I see messages like

Loaded :postgres in 4ms INSERT INTO

As I understand

Dry::Monitor::SQL::Logger.config

is responsible for this message

=> #<Dry::Configurable::Config values={:message_template=>" Loaded %s in %sms %s", :theme=>nil}>

is it possible to disable db_logging?

lib/hanami/providers/db_logging.rb

Hi @vladimirtcats, this is an interesting one. You’ve certainly unearthed some things:

  • DB logs in production mode are not JSON-formatted, like we default to for other kinds of logs
  • There’s no obvious way to disable DB logs in production

We’ll have to look at ways to resolve this.

In the meantime, I reckon we can come up with some monkey patches that will at least allow you to disable production DB logging in the meanwhile.

I think it’ll come down to overriding Dry::Monitor::SQL::Logger#log_query in the production environment, so that the method does nothing. If that’s enough of a lead for you, please feel free to have a go!

If not, then give me a day or so to try a few things and get back to you.

Thank for your reply!

I also thought about monkey patching

Dry::Monitor::SQL::Logger#log_query

but I thought that I was in the wrong way

Can you give me advice how to correctly apply monkey patch for hanami?

As I understand, I can put patch in lib folder and require this patch in app.rb file

Well, you’re not wrong :slight_smile: It’s not a clean long-term solution. But I think it should work! And at this stage I’m just looking for ways to unblock you, which will also allow us the time we need to figure out what that good long-term solution should look like.

Yep, pretty much this.

I tried to apply patch but without success

# lib/sql_monkey_patching.rb
# frozen_string_literal: true

module Dry
  module Monitor
    module SQL
      class Logger
        def log_query(time:, name:, query:); end
      end
    end
  end
end

config/app.rb

require_relative "../lib/sql_monkey_patching"

it seems to me that my patch is overriden in some stage of loading app

Your patch file will want to make sure that the relevant dry-monitor class is loaded first. This is how you ensure that your version of the method ends up “winning”.

I tried to add require 'dry-monitor' in patch but result was the same

You’re getting close! But because the dry-monitor classes are autoloaded via Zeitwerk, a single require "dry-monitor" isn’t quite enough. You’ll want one of these, I think:

require "dry/monitor"
require "dry/monitor/sql/logger"

module Dry
  module Monitor
    module SQL
      class Logger
        def log_query(time:, name:, query:); end
      end
    end
  end
end

or:

require "dry/monitor"

Dry::Monitor::SQL::Logger.class_eval do
  def log_query(time:, name:, query:); end
end

The second is probably the nicer approach for a patch. It will give you early feedback e.g. if for any reason the full Dry::Monitor::SQL::Logger class is no longer available, whereas the code in first approach would end up continuing to execute (but do nothing) in the case of the underlying dry-monitor classes changing.

Thank for your help!
the final code for this patch is:

require "dry-monitor"
require "dry/monitor/sql/logger"

Dry::Monitor::SQL::Logger.class_eval do
  def log_query(time:, name:, query:); end
end
2 Likes