Tuesday, November 30, 2010

Gabba: A Ruby Gem For Doing Server Side Google Analytics Tracking


Yo, Gabba! Gabba, hey? Gabba is a Ruby gem to do easy server-side Google Analytics tracking of page view and custom events. Gather around and I'll show you how it works.

Google Analytics is the gold standard of website traffic reporting. In addition to tracking page views, one of the interesting capabilities it has is to track custom events. These could be shopping cart checkouts or video plays from clicking on a button in a Flash player.

The way that Google Analytics is implemented is using the typical tracking image technique. An image is fetched from the server, and based on the infomation pased with this request, the information about the visit is tracked. One twist on this is that Google Analytics generates the tag for the "traxel" using a piece of asynchronous JavaScript. This means that clients without javascript are not able to use Google Analytics to track visitor metrics... or does it?

There is another lesser-known way to integrate that can generate the needed info entirely on the server. This is normally used to handle older mobile browsers that do not have JavaScript implementations. Since all you are doing is fetching a 1x1 pixel GIF image, all you really need is the magic URL.

This is in fact exactly what you would need to do if you want to track custom events, the only real difference being the specific parameters passed to Google Analytics.

There are a number of cases where you might want to track custom events for non-browser devices or other unique situations. Tracking when a purchase is completed, or when a video is played by Flash player or a phone call is initiated, are just a few things you might want to track entirely on the server, with no browser interaction at all.

I did a bit of searching, but did not find any Ruby library that did what I needed. You know what that means! Fire up the editor, I'm going in! And that is how the gabba gem was born.

It is very easy to use:

# track page views
Gabba::Gabba.new("UT-1234", "mydomain.com").page_view("something", "track/me")

# or track custom events
Gabba::Gabba.new("UT-1234", "mydomain.com").event("Videos", "Play", "ID", "123")


That is all there is to using it. Simple way to get server side Google Analytics tracking of page view and custom events. Fork gabba on github, or just "gem install gabba" and start tracking all your fun stuff.

Wednesday, November 17, 2010

10 Cool Things From RubyConf X

This last week was the fantastic RubyConf X. It has been ten years of RubyConf and in celebration of this notable occasion, the organizers located it in New Orleans and opened up the registration to a lot more people then most years past. This had the clearly foreseeable consequence of turning the conference into a really fun time!

So here, in no particular order, are 10 cool things I saw or heard at the conference.

1. Rite


During Matz's keynote he introduced "Rite" which is a embedded version of Ruby designed to run on devices such as digital TVs, and other neat small gadgets. It will have a different implementation that the CRuby implementation, optimized for the smaller lower powered profile of the next generation gadgets. The project is sponsored by the Japanese government and is already being used in development by a major game company that could not be named but is will known. My palms started sweating the minute I heard about it, and I am already getting excited about the prospect of flying_robot 2.0 based on Rite.

2. Evergreen w/CoffeeScript


CJ Kihlbom and Jonas Nicklas gave an excellent overview of client-side UI testing. They also demoed their own highly useful Evergreen testing framework which works together with Ruby and Jasmine looks like a very succinct and useful approach toward browser testing. Writing specs in CoffeeScript looks very tasty.

3. Gentlemanly Git Tricks


Scott Chacon's talks on git always leave me feeling knowing both more than I did, and less then I thought I did, at the same time. This session also had a hilarious and yet useful section on 'how to be a gentleman' including tips on whiskey, how to dress, how to tip, and how to treat a lady. Keeping it classy, Scott!

4. "F-Bombs, Zeds, _whys and a Missing Brain Area"


The keynote speeches from Dave Thomas, David Heinemeier Hansson and Matz could not have been more different on the surface, and yet had a similar theme: defy the limitations of the status quo, and seek out new ideas that are actually better. Dave's admonishment of the community to get over our gender bias, David's F-bombs, weed photos, and cry of "Freedom!", and Matz's love of diversity from _why to Zed, and adopting of David's amusing yet appropriate term "freedom-patching" in lieu of the less pleasant-sounding "monkeypatching" were all different ways of showing our desire as a community to seek out these truths. As long as we keep talking to each other, and also listening with an open mind.

5. Ruby 1.9.2 is Ready


Several people have been saying it, I am been using it from some testing, and Jim Wierich said it in the 'hallway track': Ruby 1.9.2 is ready for prime-time. If you are not transitioning your apps to 1.9.2 you should be. Performance, and cool tools like minitest are just two reasons to do it today.

6. Beyond The Code


Paul Campbell, Joe O'Brian, Keavy McMinn, Jon Dahl, Tom Preston-Werner and several other interesting developers spoke about more than just programming. Hacking business, art, music, and code, are all just aspects of hacking. RubyConf is a great place to find out not just about Ruby code, but the motivations and inspiration behind people we respect, and look to to improve ourselves.

7. Lightning Talks


The number of people that are eager to signup for a lightning talk was huge at RubyConf, as always greatly exceeding the available time. Even trimming down each to 4 minutes, there was only time to get thru relatively few, and I was lucky to get to speak about the Ticketmaster gem.

8. Kid Programmer Mini-Conf


Sarah Allen, Sarah Mei, Jim Meyer (who sadly could not make the conference at the last minute), Liah Hansen put together a parallel kids programming track, for the first time ever at RubyConf. The idea was brilliant, and I hope to bring my own son next year to participate.

UPDATE: Sarah Mei informs me that Maxwell Salzberg is also an organizer of the kids track. My bad!

9. Hallway Track


As always, the conversations at RubyConf are amazing. The people who attend are doing amazing things, and the change to hang out for a few days talking is a fantastic chance to learn and find out incredibly useful and interesting things. You have to actually attend RubyConf to experience this, you just cannot get it by watching the videos.

10. Music


From the live music in New Orleans, to the DJs, it is really great to have been in a city where music is something living, vibrant, and cherished. Getting to do my music/brain hacking talk on "How To Jam In Code" was just the icing on the cake for me in the city of Jazz. Getting to create a bio-computer made of living people is a special privilege, thank you very much to everyone who participated.

But most of all, thank you very much to Kelly Fowler, Chad Fowler, Rich Kilmer, and David Black for doing so very much for all of us. It is a lot of hard work, and we all appreciate it!

RubyConf X was a tremendous affirmation of the strength and depth of sharing within the Ruby community. I look forward to seeing what the next ten years have in store for us.

Wednesday, March 24, 2010

Happy Ada Lovelace Day 2010

Once again, it is Lady Ada Lovelace day, and time for me to celebrate some women software developers that I know personally. This year I want to call out four women that I have especially noticed their knowledge and dedication. In no particular order...

First, a big shout out to Sarah Mei (@sarahmei). Sarah is a founder of RailsBridge, a non-profit organization dedicated to helping people learn about and make use of Ruby on Rails. She is also a conference speaker who has been going around hyping up the community about one of the subjects most near and dear to my heart: teaching kids programming.

Next, a special thanks to Sonia Ramirez, my colleague at our Los Angeles based software development consultancy The Hybrid Group. Sonia is a tireless and detail oriented software developer. She is always eager to learn, and brings a great sense of humor to all of her work with us.

Third, a special thanks to Andrea O.K. Wright. Andrea has been a very active member of the Ruby community, and has given a number of presentations, must recently an incredibly ambitious overview of NoSQL databases at RubyConf 2009.

And rounding out this small sampling of the XX chromosome-based programming talent, is a new acquaintance Sarah Allen (@ultrasaurus). Sarah is also involved with the RailsBridge project, and is a mobile software developer who has published several projects based on the Rhodes framework. She is also a conference speaker, and published the RubyConf mobile application that we all made use of at LARubyConf earlier this year.

These persons of the female gender are merely a small sampling of the awesomeness that exists within the Ruby community. They just happen to be ladies that I have either worked with, or benefited from their contributions directly.

Thank you all, and have a great Ada Lovelace Day. And get back to some coding!

Thursday, March 04, 2010

Configuring Hybrid Ruby on Rails Applications On EY-Cloud

This last weekend, we completed migration of a slightly more complex Ruby on Rails application than the usual to Engine Yard's EY-Cloud. It took a few tries, and a tiny bit of research, before we completely understood what to do to get it up and running with all of the needed capabilities. Naturally this was due to gaps in my own knowledge, and I wanted to post about what I had learned, and how awesome EY-Cloud really is!

If you do not know about it, EY-Cloud is Engine Yard's cloud platform that is based on Amazon's EC2. Readers of this blog know I am not afraid to get hardcore when it comes to EC2 server configurations, and with EY-Cloud I feel like I can now get the best of everything. But I am getting ahead of myself.

Let me briefly describe the architecture of the application I was migrating. The main application is written in Ruby on Rails and uses MySQL as its data store. The app provides UI and an API for interactions with the application, mostly called by a custom iPhone app written using PhoneGap. The main app is secured using an SSL certificate. In addition, a separate API for a specific high-performance capability is written using Sinatra and DataMapper. This "special API" is also secured via SSL.

OK, you got that? Perhaps not, so here is a diagram to illustrate what I am talking about:



We call this kind of application a "hybrid" application, meaning that it is built using Ruby on Rails + "something else". For this app, the "something else" is Sinatra + DataMapper.

The previous installation used the same basic setup, but was created manually using hand-configured EC2 instances. This required a lot more management to keep the application going, and especially to add or remove instances to the cluster. Backing up the entire configuration by creating custom AMI's was also very labor intensive.

This was the scenario that led us to wish to migrate the app from raw EC2 to EY-Cloud. So if you are planning to set something like this up yourself, here are my notes to share my experience migrating a hybrid Ruby on Rails application to EY-Cloud.

Prerequisites
You need to have an account setup with Engine Yard for EY-Cloud. In addition, you should have installed the Elasticfox plugin for Firefox to easily administer the security groups. You can also do this via the command line, but it is a lot more effort.

Configure Main Environment & Application
Configuring your main application for EY-Cloud is a pretty simple process. It basically requires setting up private key access to the git repository and the application settings using the web based interface that Engine Yard provides. There is a complete article that describes this in detail here. The main steps are:

  • Create main environment

  • Create main application and configure access to its git repo

  • Config ssh key you will use to connect to instances

  • Add ssl certificate, and config main app to use it

  • Config any needed gems and unix packages to be used by main app

  • Launch app server and separate database server in main environment


Configure Secondary Environment & Application
Now you are ready to configure the environment and application for the other public accessible SSL protected service that is part of the application. This needs to be a secondary application because EY-Cloud currently only allows a single SSL cert per environment, and only allows you to associate it with one application. Hence needing a second environment configured. The main steps are:

  • Create specialapi environment

  • Create specialapi application and configure access to its git repo

  • Config ssh key you will use to connect to specialapi instances

  • Add ssl certificate, and config specialapi app to use it

  • Config any needed gems and unix packages to be used by specialapi app

  • Launch specialapi app in specialapi environment. No database is necessary.

  • Copy contents of database.yml from /data/mainapp/shared/config/database.yml on "main app" server to /data/specialapi/shared/config/database.yml on "specialapi" server. Yes, you will need to use SSH to login to both servers.
  • Use keep file on the database.yml location on the specialapi environment to point to the master database in the main app environment. This page explains about keep files.


EC2 Security Configuration
In order to allow the secondary environment to get access to the database located in the main environment, you need to make a small but critical change to the configuration in the EC2 Security Groups. Otherwise the internal firewall at Amazon will not allow the application to access the database. It is very easy to configure this using Elasticfox. Here is how:

  • Setup your EC2 security credentials for your EY-cloud account. You can download them as part of the ey-cloud.yml file

  • Once you are connected to that account using elasticfox, click on the "Security Groups" tab. You should see 3 security groups "default", one for the main app named something similar to "ey-myapp_production-12341234" that refers to the main environment, and another one named something like "ey-secondaryapp_production-56785678" that refers to the secondary environment

  • Click on the "ey-myapp_production-12341234" group in the left pane labeled "Your Groups" then click on the green checkmark icon at the top of the "Group Permissions" pane. This will bring up the "Add New Permission For Security Group" dialog. Click on the "Group" tab, then choose the "ey-secondaryapp_production-56785678" group from the Groups dropdown, and click on the "Add" button. Your secondary environment should now be able to access the main environment's database


Conclusion
It is pretty great to be able to take advantage of both the cool management interface and scalable clustered database and application stack, as well as being able to get down and dirty via SSH, something you really do need in order to configure more complex hybrid Ruby on Rails applications. EY-Cloud provides this kind of capability, and is certainly a lot easier than managing it all yourself. Hopefully, these notes will make it easier for you to migrate your own complex application. Please let me know how it works for you.

Monday, February 22, 2010

I Was A Guest Blogger At LARubyConf 2010

Longtime readers of this blog know that I can really get into writing about Ruby conferences, and I had a great time this last weekend at LARubyConf 2010. This time, I got to try some thing new: I was guest blogging the conference for TheBitSource, which has been providing some great coverage of other tech events like PyCon and SCALE.

Please check out my complete recap from the 2nd annual Los Angeles Ruby Conference LARubyConf 2010 here. And thanks!

Monday, January 18, 2010

Crossing The PhoneGap For Multiplatform Mobile Applications

I had first heard of the PhoneGap open source framework for multiplatform mobile development last year at the FutureRuby conference in Toronto. Honestly, I did not really concentrate on all they were saying at the time, and in the flurry of info including back-to-back mobile sessions with Rhomobile, I did not fully retain a clear picture of what they had to offer. My bad.

It was not until late last year, while working on plans for a very cool mobile application, that I was reminded about PhoneGap by one of my colleagues. After a brief evaluation of their benefits vs. the other multiplatform options, we decided to use PhoneGap on this particular project. We have made some amazing progress with using PhoneGap for mobile development since then, and I thought I would share a few of the lessons learned.

First of all, a quick explanation of how PhoneGap works. Jesse MacFadyen, one of the programmers at Nitobi, the primary developers of PhoneGap, has a good blog post where he breaks down how the PhoneGap framework works on iPhone. Here is my much condensed take on what he is saying.

All of the mobile platforms supported by PhoneGap have some kind of web browser control. A PhoneGap application is a packaged up application which is a webpage or mini-website, that executes inside whatever web browser control is available on that platform. Add in a standard JavaScript API to a wrapper that accesses the device-specific functionality like GPS or the accelerometer, and you can hook up the JavaScript on your "page" to the hardware.

But don't make the mistake of thinking you should just slap together some web pages formatted for mobile. Rather, you can and must think of it as an application that is written in the form of a single web page with a bunch of JavaScript. To access server data, you will need to write some AJAX code to access the remote resources, then update your UI accordingly. The good news is you can use familiar JavaScript libraries such as jQuery to do so. We chose jqTouch to get a very iPhone-like UI.

The PhoneGap framework is under very active development. New code is being committed to their github repo frequently. As such, you really do need to have git installed, and some working knowledge of how to use it, to get things setup.

In fact, the device specific functionality for each platform is contained within the main PhoneGap git repository as a series of git submodules such as phonegap-iphone, phonegap-android, etc. This makes it all but impossible to install the latest and greatest without git. Being a git user myself, this does not pose any problem, and if you are not gitmotized yet, this is an ideal time to become so.

Here are the series of steps I followed to create my own PhoneGap project...

Prerequisites

  • Install iPhone SDK (yes, you must join the iPhone developer program)

  • Install Android SDK (http://www.talkandroid.com/android-sdk-install-guide/ has some good instructions. I am not using Eclipse, so I skipped all that)

  • Install Apache Ant (sudo port install apache-ant)


Install PhoneGap

  • Get latest PhoneGap (git clone git://github.com/phonegap/phonegap.git)

  • Get submodules for iPhone & Android (cd phonegap && git submodule update)

  • Build iPhone Lib and install

  • Build Android libs


Setting Up A New Multiplatform PhoneGap Project

  • Create a new iPhone project using the phonegap-iphone template. The www directory in the new project will be becoming the shared part of your project, with all your UI and application logic

  • Create the Android project using the phonegap-android build script. Use the www directory from the iphone project as the www-dir param. You will be replacing this with a reference to the git submodule

  • Create a new git repo in the www directory in the iPhone project, and commit all the files in the www directory

  • Change directories to the parent of where you want to put the directory for the shared git repo, then clone the repo located at /path/to/iphoneproj/www to /path/to/sharedrepo. You may also want to create a remote branch at this point for the new shared repo

  • Remove the www directory from the iPhone project

  • Create a new git repo in the iphone project directory, then commit all files. You may also want to create a remote branch at this point

  • Put the shared code into the iPhone project by using "git submodule add" to put a reference to the shared repo into /path/to/iphoneproj/www

  • Create a new git repo in the Android project directory, then commit all files. You may also want to create a remote branch at this point, as you probably did for the iPhone project files

  • Remove the /path/to/androidproj/assets/www directory from the Android project, and use "git submodule add" to put a reference to the shared repo at /path/to/androidproj/assets/www


You now should have 3 git repos, with the shared code, the iPhone specific project code, and the Android specific project code, each in their respective places. Much easier and nicer to work on.

Anyhow, I hope this info is useful to any PhoneGap developers that want to get things setup cleanly for multi-platform mobile programming. Please let me know any feedback or improvements that people out there come up with, for this neat open source framework for doing JavaScript-based mobile development.

Tuesday, January 12, 2010

Sparkline Some Interest With Ruby on Rails

Recently, I added some sparkline graphs to a Ruby on Rails application. A sparkline is a very small graphic that displays a large amount of information, typically shown over time, and usually embedded in some other text. Invented by the father of modern infographics Edward Tufte, the sparkline has become a fixture of many online applications that want to visually display some stats in a simple, integrated way.

When it come to adding sparklines into a Ruby on Rails application, there are a couple of different options. You can chart the data on the server, output being an image file. You can also chart the data on the client, with a couple of different JavaScript libraries as available options.

I started my plan, intending to implement my charts on the client-side. The project that appears to have the most flexibility, speed, and options, is an amazing jQuery plugin called jQuery Sparkline. Unfortunately, the project to which I needed to add the sparklines is a bit older, and does not use jQuery. As a result, I was not able to use jQuery Sparkline for this current project.

Another interesting JavaScript sparkline library is lethain's Sparkline.js, but it has not been updated in some time, and is not compatible with current Internet Explorer versions. There is also an interesting looking newer lib topfunky-sparkline-js but I have not tried it out yet.

So that brings us to server-side sparkline generation. If you are using ImageMagick/RMagick then @topfunky once again provides, with the Ruby sparklines gem. This gem provides lots of options for doing all sorts of fancy sparklines.

In my case, I am not using ImageMagick for anything else, so I did not want to install it just for this. What I really wanted was something much lighter-weight, and I was willing to accept a lot fewer options to get it.

It turns out that madrobby has written a library for generating very simple sparklines in pure Ruby code, called spark_pr. The project uses _why's pure Ruby implementation of a PNG generator to do the low-level work.

spark_pr has also spawned an interesting application of it from @technoweenie called Sparkplug, which is a Rack module that generates spaklines from CSV data on the fly, using Rack handlers and Rack caching.

Once I had seen Sparkplug's minimal elegance, it seemed spark_pr was the option for me. I decided to incorporate spark_pr into my application. Given that the app was written with a dedicated approach to keeping a clean RESTful interface, and that the database already contained the time-series data, it was quite easy to incorporate. Here is what I had to do:

Step 1: Put spark_pr.rb file into lib directory. I just grabbed the code from the repo, and dropped it into my project. You may decide to have a more sophisticated way to do it, such as using git submodules.

Step 2:
require "spark_pr"
in your controller

Step 3:
include Spark
in your controller

Step 4: Add PNG format to controller action that was already returning my time-series data, and return the sparkline PNG data:

Note that this controller action is already returning XML or JSON. PNG is just another format to be added, if you have a well-designed RESTful controller action.

Step 5: Put image_tag that requests the sparkline PNG image file into the view where you want it to appear, like this one:


Voila! Refresh that view and you should now be looking at your ultra-hipster-chic sparkline graph. It is surprising how much more information comprehension a person has, when they are seeing a visual representation of their data. Plus it looks cool.