How to write into rails log from a job? - ruby-on-rails

I am facing an issue concerning logs. I built a rails app using ActiveJob with Sidekiq.
I want to write an entry into rails logs from a background job.
Usually, when I want to write an entry, I do something like this (in a controller for instance):
Rails.logger.fatal "BIG ISSUE!!!"
So I wanted to do the same but this time, in a background job:
class MyJob < ApplicationJob
queue_as :default
def perform(*args)
Rails.logger.fatal"FATAL TEST"
end
end
However nothing is written in the rails logs. Can you explain me why? And how to make this work?

Sidekiq logs will go to the /var/log/syslog to redirect check out this article https://github.com/mperham/sidekiq/wiki/Logging

Related

Reproduce ActiveJob::DeserializationError on rails console

I need for testing purpose to reproduce an ActiveJob::DeserializationError on rails console, I need to test the behaviour manually on testing environment.
class WrapperJob < ApplicationJob
discard_on ActiveJob::DeserializationError
def perform(event)
# doing something
end
end
The WrapperJob aims to perform something on the event, but during the enqueue time it might happen to remove event from database. I need a way please to reproduce ActiveJob::DeserializationError. right now I tried to pass a missing event, or a missing GlobalID but actually fail on the # doing something part instead of raising DeserializationError.
Thanks.

How can I run an ActiveJob in Rails console for debugging?

I currently have an ActiveJob that I've created and use Sidekiq to queue it. I'm wanting to debug the job, but for me to see any messages I program into it I have to check my log files. I feel like it would be more convenient to be able to see my puts messages in my job in the Rails Console. When I run the perform_later method though in rails console it just queues the job up and I never see the messages in console. Is there a way to make it where I will see them in the console?
You can run a job with perform_now.
For example...
class Foo < ActiveJob::Base
def perform(arg1)
puts "Hello #{arg1}"
end
end
Foo.perform_now('world')
You can temporarily set your queue adapter to inline.
Right now your code in application.rb will look something like this:
Rails.application.config.active_job.queue_adapter = :sidekiq
Just comment out the line
# Rails.application.config.active_job.queue_adapter = :sidekiq
This will run your job inline, and you should see the results in the console.
You can run with new, Eg.Foo.new.perform(ar_1, ar_2)
There is a configuration line you can add in development.rb
require 'sidekiq/testing/inline'
This should enable inline testing for development.

How to run cyclic background process in Ruby-on-Rails?

I have some methods that works with API of third party app. To do it on button click is no problem, but it should be permanent process.
How to run them background? And how to pause the cycle for make some other works with same API and resume the cycle after the job is done.
Now I read about ActiveJob, but its has time dependences only...
UPDATE
I've tried to make it with whenever and sidekiq, task runs, but it do nothing. Where to look for logs I can't understand.
**schedule.rb**
every 1.minute do
runner "UpdateWorker.perform_async"
end
**update_worker.rb**
class UpdateWorker
include Sidekiq::Worker
include CommonMods
def perform
logger.info "Things are happening."
logger.debug "Here's some info: #{hash.inspect}"
myMethod
end
def myMethod
....
....
....
end
end
It's not exactly what I need, but better then nothing. Can somebody explain me with examples?
UPDATE 2 After manipulating with code it's absolutely necessary to restart sidekiq . With this problem is solved, but I'm not sure that this is the best way.
You can define a job which enqueues itself:
class MyJob < ActiveJob::Base
def perform(*args)
# Do something unless some flag is raised
ensure
self.class.set(wait: 1.hour).perform_later(*args)
end
end
There are several libraries to schedule jobs on a regular basis. For example you could use to sidekiq-cron to run a job every minute.
If you want to pause it for some time, you could set a flag somewhere (Redis/database/file) and skip execution as long it is detected.
On a somewhat related note: don't use sidetiq. It was really great but it's not maintained anymore and has incompatibilities to current Sidekiq versions.
Just enqueue next execution in ensure section after job completes after checking some flag that indicates that it should.
Also i recommend adding some delay there so that you don't end up with dead loop on some error inside job
I dont know ActiveJobs, but I can recommend the whenever gem to create cron (periodic background) jobs. Basically you end up writing a rake tasks. Like this:
desc 'send digest email'
task send_digest_email: :environment do
# ... set options if any
UserMailer.digest_email_update(options).deliver!
end
I never added a rake task to itself but for repeated processing you could do somehow like this (from answers to this specific question)
Rake::Task["send_digest_email"].execute

Using Whenever gem with Rails Active Job to schedule a batch email job

I'm trying to understand how to use whenever properly, or if I'm even using it for the right thing. I've created a job:
class ScheduleSendNotificationsJob < ActiveJob::Base
queue_as :notification_emails
def perform(*args)
user_ids = User.
joins(:receipts).
where(receipts: {is_read: false}).
select('DISTINCT users.id').
map(&:id)
user_ids.each do |user_id|
SendNotificationsJob.create(id: user_id)
Rails.logger.info "Scheduled a job to send notifications to user #{user_id}"
end
end
end
I'd like to perform this job ever day at a set time. The job polls to see if there are any outstanding notifications, batches them, and then sends them to users so that a user can get one email with a bunch of notifications instead of a bunch of emails with one notification per email. I tried doing this with Delayed Job, but it seems it's not designed to schedule something on a recurring basis. So now I'm trying to do it with the whenever gem, but I can't seem to figure out how to set it up properly.
This is what I have in my config/schedule.rb file:
every 1.minute do
runner ScheduleSendNotifications.create
end
When I run whenever -i in the console I get the following:
Lorenzs-MacBook-Pro:Heartbeat-pods lorenzsell$ whenever -i
config/schedule.rb:13:in `block in initialize': uninitialized constant Whenever::JobList::ScheduleSendNotifications (NameError)
What am I doing wrong here? Should I be using something else? I'm just learning ruby and rails so any help is very much appreciated. Thank you.
The whenever gem takes a string as the argument to the runner function. Whenever doesn't actually load the Rails environment so it doesn't know about your ScheduleSendNotifications class.
The code below should get the crontab set up correctly to run your job.
every 1.minute do
runner "ScheduleSendNotifications.create"
end
From your project directory run whenever -w to set up the crontab file. Run crontab -l to view the written crontab file. Every minute the system will execute your Rails runner. From there you may need to debug your ScheduleSendNotifications.create code if something isn't working.

Anybody use resque gem with plugin resque-history and ActiveJob?

I use resque-history plugin for monitoring done tasks.
Firstly I include this string require 'resque-history/server' into routes file, and then I see new history tab in dashboard.
This is some code in /app/jobs/welcome_email_job.rb
require 'resque-history'
class WelcomeEmailJob < ActiveJob::Base
extend Resque::Plugins::History
#max_history = 200
#queue = :email
def perform(user)
UserMailer.welcome_email(user).deliver_now
puts "I delivered mail to #{user.login} now, sincerly yours Resque <3"
end
end
When job was done, I see in stats tab how many jobs was processed, but history tab empty, just only table head. Can I resolve this trouble?
Try restarting your workers (they aren't restarted automatically).

Resources