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

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.

Related

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.

How to Save A Tiny Bit Of Data In Rails On Heroku

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')

how to deal with the situation while DB Down?

how to deal with the situation while DB Down!
Description:
Server:Passenger
Imagine:
While you app'running,one of the dbs down,so this rails goes wrong,when new request to the website,there will be new rails to answer the request(but DB still down),so it's keeping going wrong till all rails go wrong!
so whats the solution under this situation?
just update your /public/500.html
There are 404.html, 422.html, 500.html page in your public folder, whenever any error occurs depending on the error code one of there html is shown to the user.
You need to give same look and feel as your application with related message so that user should get acknowledge something bad is happens and at the same time should connected to the your application.

php system design for rollback on exceptions

I have a system which upon request does things such as
extracts zip, creates directories, inserts database information
It could fail for whatever reason at any stage, maybe permissions, bad file format, database error.
I don't want the system to have partial executions due to any exceptions.
How exactly would I implement a rollback system ?
What I'm thinking is for every action push into a stack or database a string function execution of the opposite action and for any failure pop it and do an eval on it.
Any other built in way or any tips before I start this?
I run this some situation, best I could to figure is to make verfications during the process(extract zip code, test database connection, verfier the user name avaialble, and so on), in the end of process I apply all the nessery functions(submit data, register user ...).

Resources