Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ActiveJob[+SolidQueue?] job's code log stream broken (with hacky workaround) #237

Open
qd3v opened this issue Sep 2, 2024 · 3 comments
Open

Comments

@qd3v
Copy link

qd3v commented Sep 2, 2024

Environment

Provide at least:

  • Ruby Version: 3.3.4
  • rails (7.2.1)
  • semantic_logger (4.16.0)
  • rails_semantic_logger (4.17.0)
  • solid_queue (0.6.1)

Rails configuration:

    config.active_job.queue_adapter = :solid_queue

    config.log_level                    = ENV![:APP_LOG_LEVEL]
    config.rails_semantic_logger.format = :default

    if ENV![:APP_LOG_TO_STDOUT]
      $stdout.sync = true

      config.rails_semantic_logger.format            = :color
      config.rails_semantic_logger.add_file_appender = false
      config.semantic_logger.add_appender(io: $stdout, formatter: config.rails_semantic_logger.format)
    end

    config.rails_semantic_logger.semantic     = true
    config.rails_semantic_logger.started      = true
    config.rails_semantic_logger.processing   = false
    config.rails_semantic_logger.rendered     = false
    config.rails_semantic_logger.quiet_assets = true

Expected Behavior

Log to $stdout

Actual Behavior

I've been using SM for many years, and that's the first time I have issues, and I think they come from SolidQueue thread model or something.
Ok, the problem is SM prints only part of logs: from SolidQueue (supervisor?) but not from the job processing code.

My job class:

module Jobs
  # Base is an ActiveJob::Base subclass, nothing fancy
  class GenerateIdeas < Base
    queue_as :default

    def perform(category_id)
      puts logger.class.name # SemanticLogger::Logger <- ok here

      # Returns  <SemanticLogger::Appender::IO:0x000000012d18d2a0
      # I believe that is the configured one
      puts SemanticLogger.appenders.inspect
      puts SemanticLogger.appenders.count # 1
      logger.fatal("STARTING JOB") # nothing
    end
  end
end

Log dump:

2024-09-02 13:37:28.365143 D [7188:18540] (0.084ms) ActiveRecord -- TRANSACTION -- { :sql => "BEGIN", :allocations => 6, :cached => nil }
2024-09-02 13:37:28.369738 D [7188:18540] (6.058ms) ActiveRecord -- SolidQueue::Process Create -- { :sql => "INSERT INTO \"solid_queue_processes\" (\"kind\", \"last_heartbeat_at\", \"supervisor_id\", \"pid\", \"hostname\", \"metadata\", \"created_at\", \"name\") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING \"id\"", :binds => { :kind => "Supervisor(fork)", :last_heartbeat_at => "2024-09-02 09:37:28.296550", :supervisor_id => nil, :pid => 7188, :hostname => "ws.q", :metadata => nil, :created_at => "2024-09-02 09:37:28.360878", :name => "supervisor(fork)-71a95d781f6914449836" }, :allocations => 415, :cached => nil }
2024-09-02 13:37:28.372734 D [7188:18540] (1.182ms) ActiveRecord -- TRANSACTION -- { :sql => "COMMIT", :allocations => 400, :cached => nil }
2024-09-02 13:37:28.374567 I [7188:18540] JOBS -- SolidQueue-0.6.1 Register Supervisor(fork) (76.3ms)  pid: 7188, hostname: "ws.q", process_id: 67, name: "supervisor(fork)-71a95d781f6914449836"
2024-09-02 13:37:28.396726 D [7188:18540] (0.628ms) ActiveRecord -- SolidQueue::ClaimedExecution Load -- { :sql => "SELECT \"solid_queue_claimed_executions\".* FROM \"solid_queue_claimed_executions\" LEFT OUTER JOIN \"solid_queue_processes\" ON \"solid_queue_processes\".\"id\" = \"solid_queue_claimed_executions\".\"process_id\" WHERE \"solid_queue_processes\".\"id\" IS NULL", :allocations => 7, :cached => nil }
2024-09-02 13:37:28.399934 W [7188:18540] JOBS -- SolidQueue-0.6.1 Fail claimed jobs (4.3ms)  job_ids: [], process_ids: []
2024-09-02 13:37:28.402211 I [7188:18540] JOBS -- SolidQueue-0.6.1 Started Supervisor(fork) (127.7ms)  pid: 7188, hostname: "ws.q", process_id: 67, name: "supervisor(fork)-71a95d781f6914449836"
2024-09-02 13:37:28.438936 D [7188:io-worker-1] (1.098ms) ActiveRecord -- SolidQueue::Process Load -- { :sql => "SELECT \"solid_queue_processes\".* FROM \"solid_queue_processes\" WHERE \"solid_queue_processes\".\"last_heartbeat_at\" <= $1 ORDER BY \"solid_queue_processes\".\"id\" ASC LIMIT $2 FOR UPDATE SKIP LOCKED", :binds => { :last_heartbeat_at => "2024-09-02 09:32:28.425749", :limit => 50 }, :allocations => 10, :cached => nil }
2024-09-02 13:37:28.439706 D [7188:io-worker-1] JOBS -- SolidQueue-0.6.1 Prune dead processes (14.0ms)  size: 0
2024-09-02 13:38:28.381268 D [7188:io-worker-1] (0.109ms) ActiveRecord -- TRANSACTION -- { :sql => "BEGIN", :allocations => 5, :cached => nil }
2024-09-02 13:38:28.381692 D [7188:io-worker-1] (0.569ms) ActiveRecord -- SolidQueue::Process Update -- { :sql => "UPDATE \"solid_queue_processes\" SET \"last_heartbeat_at\" = $1 WHERE \"solid_queue_processes\".\"id\" = $2", :binds => { :last_heartbeat_at => "2024-09-02 09:38:28.380277", :id => 67 }, :allocations => 178, :cached => nil }
2024-09-02 13:38:28.385207 D [7188:io-worker-1] (3.314ms) ActiveRecord -- TRANSACTION -- { :sql => "COMMIT", :allocations => 220, :cached => nil }

This code works, but that is not what we all want :)

def perform(category_id)
  logger = Logger.new($stdout)
  logger.fatal("STARTING JOB") # ok
end

After some time of double-checking everything I found workaround: an attempt to re-add $stdout appender resets something, and fix logging:

module Jobs
  class Base < ActiveJob::Base

    before_perform :fix_logging_v4_17

    def fix_logging_v4_17
      # This logs error (attempt to add another console logger) but forces SM to work
      SemanticLogger.add_appender(io: $stdout, formatter: :color)
    end
  end
end

The log message about this dirty hack appears, but at least this works :)

There's even worse hack: call SemanticLogger#sync!.

Thank you for your work!

@kristoph
Copy link

Any addition insights to resolve this issue at all?

@reidmorrison
Copy link
Owner

Does someone in the community that uses Active Job have a solution they want to submit as a PR?
Or, even just submit a PR with a failing test for the above scenario?

@bytnar
Copy link

bytnar commented Oct 16, 2024

2 small cents from me.
I'm not sure it is fully on SemanticLogger side.
After I switched for test purposes to Sidekiq from SolidQueue, I'm able to see log entries. So maybe it is SolidQueue that passes logger object down to job (thread) in a way that is incompatible with SemanticLogger.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants