I understand that from the console I can run heroku restart. What I'd like to do is to have a button in my app (admin console), where pushing that button runs a heroku restart. Does anyone know how to do that and if it's possible? So the code would look something like this:
<button id="heroku_restart">Restart</button>
$("#heroku_restart").click(function() {
$.post('/restart', {}).done(function(response) {
alert(response)
})
})
class AdminsController
# this is the action mapped to the route /restart
def restart
# code for heroku restart
end
end
So per #vpibano, as of this writing, doing it with the platform-api is a breeze. Here's the action POSTed to by a button on my website:
def restart
heroku = PlatformAPI.connect_oauth(ENV["heroku_oauth_token"])
heroku.dyno.restart_all("lastmingear")
render nothing: true
end
As per the description mentioned in the post, the one way of doing it is :
1) First locate the server.pid file
pid_file = Rails.root.join("tmp", "pids", "server.opid")
2) Now, truncate the contents of the file
File.open(pid_file, "w") {|f| f.truncate(0)}
3) Finally, run the server using Kernel module:
Kernel.exec("rails s")
Note: As rightly, mentioned by #vpibano you will need authentication to access your app.
This is not a working model but a way to achieve the requirement.
Hope it helps!!
Related
I’m developing with Ruby on Rails. When I start an application server with Puma, the following logs continue to show every a few seconds.
{"method":{},"path":{},"format":{},"params":{},"controller":"ApplicationCable::Connection","action":"connect","status":200,"duration":8.75,"backtrace":null,"host":null,"user_id":null,"user_type":null,"remote_ip":null,"user_agent":null,"os":null,"os_version":null,"browser":null,"browser_version":null,"#timestamp":"2021-07-28T10:24:34.068Z","#version":"1","message":"[200] (ApplicationCable::Connection#connect)"}
{"method":{},"path":{},"format":{},"params":{},"controller":"ApplicationCable::Connection","action":"disconnect","status":200,"duration":0.58,"backtrace":null,"host":null,"user_id":null,"user_type":null,"remote_ip":null,"user_agent":null,"os":null,"os_version":null,"browser":null,"browser_version":null,"#timestamp":"2021-07-28T10:24:34.069Z","#version":"1","message":"[200] (ApplicationCable::Connection#disconnect)"}
This interrupts binding.pry prompts as follow, so I can’t debug an application properly.
[1] pry(#<SomeController>)> {"method":{},"path":{},"format":{},"params":{},"controller":"ApplicationCable::Connection","action":"connect","status":200,"duration":8.75,"backtrace":null,"host":null,"user_id":null,"user_type":null,"remote_ip":null,"user_agent":null,"os":null,"os_version":null,"browser":null,"browser_version":null,"#timestamp":"2021-07-28T10:24:34.068Z","#version":"1","message":"[200] (ApplicationCable::Connection#connect)"}
{"method":{},"path":{},"format":{},"params":{},"controller":"ApplicationCable::Connection","action":"disconnect","status":200,"duration":0.58,"backtrace":null,"host":null,"user_id":null,"user_type":null,"remote_ip":null,"user_agent":null,"os":null,"os_version":null,"browser":null,"browser_version":null,"#timestamp":"2021-07-28T10:24:34.069Z","#version":"1","message":"[200] (ApplicationCable::Connection#disconnect)"}
I wasn’t able to find from which these logs show.
What I’ve tried is adding ActionCable.server.config.logger = Logger.new(nil) to config/application.rb. But I still have the problem.
https://dev.to/xlts/fixing-rails-action-cable-logger-la8#option-2-try-to-do-it-systematically
How can I fix this problem?
Thank you in advance.
I’m using Lograge, so I’ve resolved this problem by adding the following configuration to config/initializers/lograge.rb.
Rails.application.configure do
# ...
# ...
# ...
config.lograge.ignore_actions = [
"ApplicationCable::Connection#connect",
"ApplicationCable::Connection#disconnect"
]
end
In my Ruby on Rails app I have build a function to validate if a piece of javascript is added to a certain website. When I run this code I don't get any errors in my log, but my app says:
We're sorry, but something went wrong.
If you are the application owner check the logs for more information.
But when I check the logs I don't see any errors. The code I have used is the following:
def validate_installation
data = HTTParty.get(self.website)
url = "http://www.smartnotif.com/sn.js"
if data.body.include? url
return true
else
return false
end
end
When I run this code on my local development machine it runs fine, but when I try to runs this production machine on DigitalOcean I have this problem with the same code, no errors.
Try to include
require 'httparty'
Restart rails server
rails s
Also check the permission of log folder, why it is not writing error in log folder
Also try: Use self keyword as you are calling it as class method
def self.validate_installation
data = HTTParty.get(self.website)
url = "http://www.smartnotif.com/sn.js"
if data.body.include? url
return true
else
return false
end
end
I am using a background job in order to import user data from a csv file into my datase. First I did this "hard" in my User model by simply calling a method in my User model and by passing the file path which is transmitted via a form file_field:
User.import_csv(params[:file].path)
Worked well locally and on production (heroku).
Now when it comes to huge CSV files, I understood that I need a job to perform this import in the background. I am familiar with redis and sidekiq so the job was built quickly.
CsvImportJob.perform_async(URI.parse(params[:file].path))
and in my worker:
def perform(file_path)
User.import_csv(file_path)
end
Well, that also works perfect locally but as soon as I hit this on production, I see the following error in my log:
» 10 Aug 2015 13:56:26.596 2015-08-10 11:56:25.987726+00:00 app worker.1 - - 3 TID-oqvt6v1d4 ERROR: Actor crashed!
» 10 Aug 2015 13:56:26.596 2015-08-10 11:56:25.987728+00:00 app worker.1 - - Errno::ENOENT: No such file or directory # rb_sysopen - /tmp/RackMultipart20150810-6-14u804c.csv
» 10 Aug 2015 13:56:26.596 2015-08-10 11:56:25.987730+00:00 app worker.1 - - /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/csv.rb:1256:in `initialize'
This is meant to be the file_path variable.
Somehow heroku is not able to find the file when I pass it to a sidekiq job. When I do this without sidekiq, it works.
I don't really know how to tackle this issue so any help is appreciated.
I had the same experience, you can look at a similar project of mine at https://github.com/coderaven/datatable-exercise/tree/parallel_processing
(Basically just focus on object_record.rb model and the jobs: import_csv_job.rb and process_csv_job.rb)
The error: Errno::ENOENT: No such file or directory # rb_sysopen
If you said that this works on heroku then probably that means that the path you are getting this is valid (in your example you are using the /tmp/ path)
So here's 2 probable problems and their solution:
1.) You have saved an unknown to Heroku path (or inaccessible path) which cannot be access or opened by the application when it is running. Since, when handling the import csv without sidekiq - the file you uploaded are save temporarily in-memory until you finish processing the csv - However, in a job scheduler (or sidekiq) the path should not be in memory and should be an existing path that is accessible to the app.
Solution: Save the file to a storage somewhere (heroku has an ephemeral filesystem so you cannot save files via the running web-app) to work this around, you have to use an Amazon S3 like service (you can also use Google Drive like what I did) to save your files there and then give the path to your sidekiq worker - so it can access and process it later.
2.) If the paths are correct and the files are save or processed correctly then from my experience it could have been that you are using File.open instead of the open-uri's open method. File.open does not accept remote files, you need to require open-uri on your worker and then use the open method to work around remote files.
ex.
require 'open-uri'
class ProcessCsvJob < ActiveJob::Base
queue_as :default
def perform(csv_path)
csv_file = open(csv_path,'rb:UTF-8')
SmarterCSV.process(csv_file) do |array|
.... code here for processing ...
end
end
end
I'm fully aware this question is already past almost a year, so if you have solved this or this answer worked then it could also help serve as a documentation archive for those who will probably experience the same problem.
You can't pass a file object to the perform method.
The fix is to massage the data beforehand and pass in the parameters you need directly.
Something like...
def import_csv(file)
CSV.foreach(file.path, headers: true) do |row|
new_user = { email: row[0], password: row[1] }
CsvImportJob.perform_async(new_user)
end
end
Note: you'd call CsvImportJob.perform_later for Sidekiq with ActiveJob and Rails 5.
You got the error because on production/staging and sidekiq run on different servers.
Use my solution: upload csv to google cloud storage
class Services::Downloader
require 'fog'
StorageCredentials = YAML.load_file("#{::Rails.root}/config/g.yml")[Rails.env]
def self.download(file_name, local_path)
storage = Fog::Storage.new(
provider: "Google",
google_storage_access_key_id: StorageCredentials['key_id'],
google_storage_secret_access_key: StorageCredentials['access_key'])
storage.get_bucket(StorageCredentials['bucket'])
f = File.open(local_path)
storage.put_object(StorageCredentials['bucket'], file_name, f)
storage.get_object_https_url(StorageCredentials['bucket'], file_name, Time.now.to_f + 24.hours)
end
end
Class User
class User < ApplicationRecord
require 'csv'
require 'open-uri'
def self.import_data(file)
load_file = open(file)
data = CSV.read(load_file, { encoding: "UTF-8", headers: true, header_converters: :symbol, converters: :all})
...
Worker
class ImportWorker
include Sidekiq::Worker
sidekiq_options queue: 'workers', retry: 0
def perform(filename)
User.import_data(filename)
end
end
and code for start worker
--
path = Services::Downloader.download(zip.name, zip.path)
ImportWorker.perform_async(path)
For some reason, my Rails app is no longer logging my DelayedJob gem's activity, either to a separate log (delayed_job.log) or to the main Rails development log. I am also using the Workless gem, should this be relevant.
It used to say things like this:
2013-06-07T19:16:25-0400: [Worker(delayed_job.workless host:MyNames-MacBook-Pro.local pid:28504)] Starting job worker
2013-06-07T19:16:38-0400: [Worker(delayed_job.workless host:MyNames-MacBook-Pro.local pid:28504)] MyApp#scrape completed after 13.0290
2013-06-07T19:16:38-0400: [Worker(delayed_job.workless host:MyNames-MacBook-Pro.local pid:28504)] 1 jobs processed at 0.0761 j/s, 0 failed ...
2013-06-07T19:16:43-0400: [Worker(delayed_job.workless host:MyNames-MacBook-Pro.local pid:28504)] Exiting...
But nothing is appearing anymore in any of the logs.
How can I make sure that DelayedJob activity logs to the main development log? I don't mind if it also logs to a separate log, but the important thing is that I see its activity in my Mac's console.
I have searched for answers to this issue online (such as here and nothing is working.
Here is my delayed_job_config.rb: (in config/initializers)
Delayed::Worker.sleep_delay = 60
Delayed::Worker.max_attempts = 2
Delayed::Worker.max_run_time = 20.minutes
Delayed::Worker.logger = Rails.logger
Delayed::Worker.logger.auto_flushing = true
Please let me know if you'd like more code from my app - I'd be happy to provide it. Much thanks from a Rails newbie.
I finally got this to work. All thanks to Seamus Abshere's answer to the question here. I put what he posted below in an initializer file. This got delayed_job to log to my development.rb file (huzzah!).
However, delayed_job still isn't logging into my console (for reasons I still don't understand). I solved that by opening a new console tab and entering tail -f logs/development.log.
Different from what Seamus wrote, though, auto-flushing=true is deprecated in Rails 4 and my Heroku app crashed. I resolved this by removing it from my initializer file and placing it in my environments/development.rb file as config.autoflush_log = true. However, I found that neither of the two types of flushing were necessary to make this work.
Here is his code (without the auto-flushing):
file_handle = File.open("log/#{Rails.env}_delayed_jobs.log", (File::WRONLY | File::APPEND | File::CREAT))
# Be paranoid about syncing
file_handle.sync = true
# Hack the existing Rails.logger object to use our new file handle
Rails.logger.instance_variable_set :#log, file_handle
# Calls to Rails.logger go to the same object as Delayed::Worker.logger
Delayed::Worker.logger = Rails.logger
If the above code doesn't work, try replacing Rails.logger with RAILS_DEFAULT_LOGGER.
I have a condition where I need to check for the file in another server, if that file exists I need to delete from the current server. Can any body help me.
You can place a script on another server and ask it in restful way to perform that tasks for you:
http://another.server/exists/:file_name
http://another.server/delete/:file_name
but you will have to think about security aspects of this solution.
Also take a look on executing remote commands via ssh: http://bashcurescancer.com/run_remote_commands_with_ssh.html. Combined with using ssh "without password" it can be acceptable solution to run command line program that run what you need.
Just write a ruby script and do something along the line with:
require "open-uri"
file_name = "file.name"
begin
file = open("http://www.example.com/#{file_name}")
File.delete("path_to" + file_name)
p "File #{file_name} deleted"
rescue
p "File not found"
end