How to Save A Tiny Bit Of Data In Rails On Heroku - ruby-on-rails

I have a super simple Ruby on Rails app that doesn't have any ActiveRecord code. The app saves literally one line of text via a "record" URL. I want to be able to then hit a URL that feeds back whatever line of text was recorded. Like this:
Person 1: POST to www.myUrl.heroku.com/recorder, DATA = "A really interesting string"
Person 2: GET to www.myUrl.heroku.com/recorder, I want my response to contain "A really interesting string"
This sounds SUPER SIMPLE which is why I am mega-frustrated that I can't do it. Heroku has an ephemeral file system - I read all about that. And Heroku logs can't be accessed from within the app (as far as I can tell) - I can use command line tools but that doesn't help. But I only need the data there for 10 minutes!
Here are the things we tried so far:
Save to a local file in /tmp - this works sometimes but fails when Heroku flushes the directory in between HTTP requests, which is expected behavior
Save to log file in /log via direct file write - same as above, works sometimes but also gets flushed often
Use a Ruby logger to write to a new log file - ditto
Use puts to write to the Heroku log - nice idea, but Heroku doesn't let you write to the production log this way, it writes somewhere else that you can access through command line but (as far as I can tell) not within the app
I really don't want to sign up for AWS since this is a service for someone else, and it seems ridiculous to sign up for 1 tb of data transfer for literally 1 line of text (it overwrites anytime someone "records"). I also would prefer not to create a whole ActiveRecord deal given, again, literally 1 line of text.
Any ideas here? Is there some micro cache or whatever I can use? I only need the data to persist for about 10 minutes.
Thanks!
Damien
PS Using Ruby 2.0, rails 3.something.

You can take advantage of Rails application caching - rails.cache.write('key','value') and rails.cache.read('key')

Related

Whats the best practice for creating and sending an email attachment using Rails API

I need to know if I'm implementing the correct procedure when sending an email with an attached .xls document.
The attached .xls document would simple have the information provided in an object. ...ie: person.first_name person.last_name. The xls file will render the full names of the list.
I have a front-end React.js with a back-end Rails API.
I actually have it working in it’s most simple way but I’m not sure if this would be the best way.
Please let me know if there is amore efficient way of doing this.
Currently I have this setup: In my React Action Creator I have a fetch calling to a custom “list” method on my controller backend. In this controller I’m creating and writing the file like this:
File.open(“new_file”, 'w+') do | f |
c = #list.names do | name, data |
f.puts ( "#{name.first_name} #{name.last_name}")
f.close
end
end
The above code will create a file in the root of my application which I’m not sure if it’s best practice.
After this code runs the mailer sends out the email with the proper xls file attached .
My question is: What do I do with this newly created file on the root of my rails application. Is this normal to have and every time this runs the file is overwritten which is okay in my opinion. What if two different people on different devices run the code at the same time. Will there be a chance of the list being mixed up and one user getting the wrong list? I just feel like this is not right to create a file to my back-end Rails api whenever my user needs a list emailed to them. Even if I delete it right after it’s sent in the mailer.
Thank you for your help.
How about creating temporally files with the ruby API
Or if there is not a need to reuse the file use send_data
If you have thousand of files that need caching is worth thinking something like the official Rails cache api(you can cache any kind of file no just HTML )

Rails save log data to database

Is it possible to access to the information being saved into a rails log file without reading the log file. To be clear I do not want to send the log file as a batch process but rather every event that is written into the log file I want to also send as a background job to a separate database.
I have multiple apps running in docker containers and wish to save the log entries of each into a shared telemetry database running on the server. Currently the logs are formatted with lograge but I have not figured out how to access this information directly and send it to a background job to be processed.(as stated before I would like direct access to the data being written to the log and send that via a background job)
I am aware of the command Rails.logger.instance_variable_get(:#logger) however what I am looking for is the actual data being saved to the logs so I can ship it to a database.
The reasoning behind this is that there are multiple rails api's running in docker containers. I have an after action set up to run a background job that I hoped would send just the individual log entry but this is where I am stuck. Sizing isn't an issue as the data stored in this database to be purged every 2 weeks. This is moreso a tool for the in-house devs to track telemetry through a dashboard. I appreciate you taking the time to respond
You would probably have to go through your app code and manually save the output from the logger into a table/field in your database inline. Theoretically, any data that ends up in your log should be accessible from within your app.
Depending on what how much data you're planning on saving this may not be the best idea as it has the potential to grow your database extremely quickly (it's not uncommon for apps to create GBs worth of logs in a single day).
You could write a background job that opens the log files, searches for data, and saves it to your database, but the configuration required for that will depend largely on your hosting setup.
So I got a solution working and in fairness it wasn't as difficult as I had thought. As I was using the lograge gem for formatting the logs I created a custom formatter through the guide in this Link.
As I wanted the Son format I just copied this format but was able to put in the call for a background job at this point and also cleanse some data I did not want.
module Lograge
module Formatters
class SomeService < Lograge::Formatters::Json
def call(data)
data = data.delete_if do |k|
[:format, :view, :db].include? k
end
::JSON.dump(data)
# faktory job to ship data
LogSenderJob.perform_async(data)
super
end
end
end
end
This was just one solution to the problem that was made easier as I was able to get the data formatted via lograge but another solution was to create a custom logger and in there I could tell it to write to a database if necessary.

Preventing Rails from connecting to database during initialization

I am quite new at Ruby/Rails. I am building a service that make an API available to users and ends up with some files created in the local filesystem, without any need to connect to any database. Then, once every few hours, I want to run a piece of ruby code that takes these local files, uploads them to Amazon S3 and registers their location into a Postgres database.
Right now both codes live together in the same project. I am observing that every time a user does something the system connects to the database. I have seen this answer which recommends to eliminate all traces of ActiveRecord in my code, but given that I want to have my background bookkeeping process connect to the database I am stuck on what to do.
Is it possible to define two different profiles (one with database and one without) and specify which profile a certain function call should run on? would this work?
I'm a bit confused by this, the db does not magically connect to the database for kicks on every request, it does so because of a specific request requires it. Generally through ActiveRecord but not exclusively
If your system is connecting every time you make a request, then that implies you have some sort of user metric or authorisation based code in there. Just killing off the database will cause this to fail, and likely you'll have to find it anyways, to then get your system to work. I'd advise locating it.
Things to look for are before_filters in controllers, or database session management, for example, or look for what is in the logs - the query should appear - and that will tell you what is being loaded, modified or whatnot.
It might even work to stop your database, just before doing a user activity, and see where the error leads you. Rinse and repeat until the user activity works, without the database.

Store Temporary Sensitive Data In Rails 4

I'm working on a Rails app but i'm having trouble implementing a solution for storing temporary data and automatically clearing it when the user sees it. I thought about using flash but that only works when the user visits via the next request. Im looking for something that will let the user browse the site and view other things but once they get to the page such as /example/, they see the temporary sensitive data, then next time they reload that page or go somewhere else and come back its permanently gone. Any suggestions?
Redis will be fastest and simplest solution (but not such simple as flash notices). Redis have built in lpop method to get something from list and remove it after that. I think you will not find good solution which will not require some setup (e.g. Redis installation)

Saving 500/404 errors in Ruby on Rails to a database?

Is there a way to save the 500/404 etc errors to your database so you can check them to see if there are any bugs on the site?
I thought you could send an JS AJAX request from the 500.html page. e.g.
/errors/create/?message=error_message&ip=123&browser=ie9
But I'm not sure how to get that information when running in production mode?
Any help greatly appreciated,
Alex
This is what I have in my application controller:
def rescue_action_in_public(exception)
#This is called every time a non-local error is thrown.
#Copy the error to the db for later analysis.
Error.create :exception_name => exception.exception.to_s, :backtrace_info => exception.backtrace.to_s
#Then handle the error as usual:
super
end
As you can see I have an Error model I created and this saves a new one to the DB whenever it happens. One thing to remember is that backtraces are much to big for string columns so you will need something bigger like a text type. This works in my Rails 3.0.5 app.
Logging errors to the db is inadvisable since these errors can often be caused by database issues. It's safer to append your errors to a file (on a separate disk) if your site is high traffic, if the file system is unresponsive, then your db won't work anyway. Even safer would be to use an asynchronous message queue hosted on another server. In both cases, you can create reports by periodically parsing your log output.

Resources