Crashlytics has a feature that tells you how many users are using your app right now. This is super addictive! Sometimes a find myself wasting hours just looking at that number while it goes up and down (while praying for it go up, of course).
But what if you don't have Crashlytics? Or you don't want to leave your terminal? I was faced with both these questions, so I went ahead and wrote a little ruby script to help with this problem. You can find it here.
It reads logs from the standard input. Finds IP addresses and puts them on a
hash with a timestamp. Every 5 seconds it goes and removes every IP address that didn't make any request for 60 seconds. So, this gives you an estimate of how many users are using your web application right now (or at least in the last minute), as long as they all have different IP addresses.
The objective was to make something that was really easy to use (and fast to build) without leaving the terminal. So, now I can just tail my logs and pipe the output to this script and it tells me how many users I have.
heroku logs -t | ruby active_users.rb
It also works outside of Heroku as long as you have centralised way to access your logs, it could be as simple as
tail -f logs/production.log | ruby active_users.rb
depending on your configuration.
The most tricky part here is how to expire IP addresses. First it needs to run in its own thread so it executes every so often (I have set it to 5 seconds) without affecting the rest of the process. This means that the access to the
hash with the IP addresses needs to be synchronised. I used a simple Mutex for this. The second problem is how to know which IP's to expire. Currently I'm just iterating through all of them. But this can get very slow if your app is extremely successful as it scales linearly. Ideally you would index the IP's in something like a B-TREE for better scalability. I'll revisit this code when this becomes a problem.