Archive by Author

Logging in production with Rails

22 Nov

I use the Rails server logs primarily to dig through a user’s interaction with the site across requests to track down intricate bugs, like how did the user manage to get the system into this state which it shouldn’t be in.

But using the default Rails logs to do this piece of detective work is horrible.

I’m using the Hodel3000CompliantLogger, which prefixes each log line with the process id, which makes it possible to trace through each individual request.

But I haven’t found any tools that help me dig through those large log files yet.

I discovered Loggly today, and I briefly got my hopes up, but it does nothing like what I’m looking for. Or if it is, I haven’t noticed. All I can see that it does for me, is aggregate log files from various servers. I only have one server. There’s some searching, but it still just shows me the plain old log file.

What I want to see is a list of each request served by Rails, along with the IP address, the user agent, the parameters, info from the session such as logged in user ID, the response code, the redirected to URL if redirected, perhaps processing time, and memory consumption.

Then I want to be able to filter by IP address, so I can follow just one user’s path through the system, looking at each request, one by one.

Then I want to be able to dig into each request, one by one, seeing everything my app logged, which includes database statements and my own debugging statements and such.

I think having such a tool would help me tremendously.

Does any such tool exist already?

Possibly a customized Rails logger along with a web-based interface that lets me search and browse my logs.

I really thought Loggly was it, but I can’t see that it does the job for me :(

Your insight is greatly appreciated.

Thanks!
//Lars

How to set a default form builder in Rails 3.1 while letting it be autoloaded

8 Nov

Took me a couple hours to figure this out.

When you do config.action_view.default_form_builder = MyFormBuilder in your appliaction.rb, it doesn’t get autoloaded (ie. reloaded when you change something in development – which is really handy).

But, despite what this page says, changing it to say ActionView::Base.default_form_builder = MyFormBuilder in an initializer does squat to make my formbuilder get auto-reloaded.

It seems that the problem is that the class is never invoked by name, and so the autoloader doesn’t kick in. If instead you say :builder => MyFormBuilder on the form_for tag, it does get reloaded.

If you insert the code <% MyFormBuilder %> at the top of your erb page, the class actually does get reloaded, but the form builder still uses the old version. A Class is actually an Object, and ActionView::Base.default_form_builder still has a pointer to the old Class object, even though the constant MyFormBuilder now points to the new class. At least that’s what I think happens.

What ended up working for me was putting this code in config/initializers/set_default_form_builder.rb, which defines new form_for and fields_for  tags, which sets the :builder option to the builder I want, invoked by name. NOW my formbuilder gets reloaded with each change, AND I don’t have to specify it on each form.

Here’s the complete code I’m using:

Ahh, much easier to develop it now.

Enjoy!

Fast index creation in MySQL with InnoDB

1 Nov

I hunted around the web for hours and hours and hours trying to figure this out.

I have a table with 1.4M rows, and I need to add some indices to it, and to drop one that was created wrong. (It started with the primary key – bad idea!)

One my laptop, creating the index took a few seconds. On the server, it took over 20 minutes, then I killed it. Couldn’t afford to take zenbilling down for that long.

When doing a “show processlist”, it told me it was doing a “Copy to tmp table”, which took forever. I searched for “copy to tmp table innodb create index” and permutations of that, and came up with nothing but other people’s frustrations.

I looked at every single variable in “show variables” and compared them, tweaked them on the server, but nothing changed.

Only when I googled “fast index creation innodb” did I come up with this.

Turns out that the server was running MySQL 5.0 and I was running 5.5 locally.

If you install MySQL 5.1 (the latest available in debian) and install the InnoDB plugin, then you can create indices in a snap.

Don’t forget to configure MySQL to use the InnoDB plugin instead of the built-in version.

Github textmate bundle

1 Nov

I only discovered the github TextMate bundle a few days ago.

It’s great. I particularly like the “Show in Github” feature, which makes it quick and easy to see what was the original version of this file you’re editing.

And while we’re on the topic of git, git log -p <path> is really handy to show you what changed with which commits in a given file. Helps you understand why a certain change was made, or why a line is there.

Rails tip: Get AckMate to search .scss files

9 Oct

I love AckMate, but to my horror, it doesn’t search through .scss or .css.scss files, which is used in Rails 3.1.

The fix is easy: Add this to your ~/.ackrc:

–type-add=css=.scss

That does the trick.

Cheers.

Recording live calls

20 Sep

I usually do live calls using GoToWebinar (which I hate, but it’s the best product I’ve found, unfortunately – web 2.0, where are you, when will you catch up??) and then record them using WireTap Studio.

But as of OS X Lion, WireTap Studio can’t record the audio from applications anymore. Which sucks.

Recording my own voice is the easy part. The hard part is recording the voices of other people on the call when they’re asking questions and engaging in dialogue.

Thankfully, it turns out that Screenflow can. So you can record the audio using Screenflow (both audio from microphone + computer audio – the last one is the trick), and then you can export it to an AIFF file (Lossless – Audio only), which you can then convert to MP3.

It’s not pretty, but it works.

Why GoToWebinar doesn’t offer to record the audio server-side, and let me download a simple MP3 file of the recording is beyond me.

New payment service Stripe looks amazing

9 Sep

Just got access to Stripe, a simple Javascript API-based payment service.

You encrypt the credit card info and submit it to their servers via Javascript, and get back a token which you can use to charge against that card later.

Simple and beautifully executed.

Now can we get to use it in Denmark, please? And with a Dankort?

Linking two input fields

6 Sep

When you send emails from zenbilling, you get to choose a separate sender email and reply-to address. Usually they’re one and the same, but sometimes you want them to be different.

The way I did this is to have two input fields, one for each, but to have them linked, so when you make changes to sender email, reply-to is automatically updated with the same change. Unless reply-to has been changed to be different from sender email, in which case we leave reply-to alone.

Today I needed this pattern somewhere else, and so I wrote a handy little jQuery function for it, which you can find here.

Enjoy!

Using Glyphicons with Rails

5 Sep

I love Glyphicons – they’re pretty, versatile, stylish, clean, well executed, well priced, and there’s lots of them.

So I’ve created a Rails helper that makes it easier to work with them. It lets you do things like this:

link_to_glyphicon(:edit, edit_admin_product_coupon_path(@product, coupon))
 
glyphicon(:move, :class => 'drag_handle', :title => "Drag to reorder", :variant => :halfling)

If you’re interested, you can find the code here.

Patches are graciously accepted.

Rails tip of the day: Rails + OS X Lion + rvm + nokogiri

6 Aug

I followed this guide, but still had trouble getting nokogiri to install.

Nokogiri complained about libiconv, but the culprit wasn’t libiconv. It was libxml2 and libxlst.

Here’s the output from trying to install nokogiri:

✗ gem install nokogiri -v 1.4.4
Fetching: nokogiri-1.4.4.gem (100%)
Building native extensions.  This could take a while...
ERROR:  Error installing nokogiri:
	ERROR: Failed to build gem native extension.
 
        /Users/lars/.rvm/rubies/ree-1.8.7-2011.03/bin/ruby extconf.rb
checking for libxml/parser.h... yes
checking for libxslt/xslt.h... yes
checking for libexslt/exslt.h... yes
checking for iconv_open() in iconv.h... no
checking for iconv_open() in -liconv... no
-----
libiconv is missing.  please visit http://nokogiri.org/tutorials/installing_nokogiri.html for help with installing dependencies.
-----

In other instances, I did manage to get it installed somehow, but when I tried to run “rails c”, I’d get this error:

/Users/lars/.rvm/gems/ree-1.8.7-2011.03/gems/nokogiri-1.4.4/lib/nokogiri/nokogiri.bundle: [BUG] Segmentation fault

Ultimately, the answer was this gist, which I resisted for a long time, because I thought it wasn’t libxml2/libxslt that was missing, but libiconv. I was wrong.

I did have to change the last line to refer to version 2.7.8 of libxml2 rather than 2.7.7. Minor change.

I hope this blog post will save you the hour or two that I wasted wrestling with this stupid issue :)