X-Request-Id tracking and TaggedLogging in Rails3.2

Posted by arunagw on October 21, 2011

Rails 3.2 will come with X-Request-Id tracking and TaggedLogging support!! Recently DHH added this feature here!

This makes it easy to trace requests from end-to-end in the stack and to identify individual requests in mixed logs.

If you have application on SAS model. Where you have logs filled with mixed request for all your customers. May be you need to filter out requests start with some specific subdomain. TaggedLogging will help you in that.

Where as the X-Request-Id feature will help you to track log with the same request. So in mixed logs you can easily find out the unique id logs for a request.

It will tag the log with the unique id for that request in the log. So later you can easily trace them down.

May be later on you can add more tags for your logs. If those methods are supported by the request object!

I am showing here some logs here with X-Request-Id

[2011-10-21 19:57:55] INFO  WEBrick 1.3.1
[2011-10-21 19:57:55] INFO  ruby 2.0.0 (2011-10-19) [x86_64-darwin11.2.0]
[2011-10-21 19:57:55] INFO  WEBrick::HTTPServer#start: pid=1585 port=3000
[9fda80066583f52e695a089d8622439c] 

Started GET "/blogs" for 127.0.0.1 at 2011-10-21 19:57:59 +0530
[9fda80066583f52e695a089d8622439c]  Processing by BlogsController#index as HTML
[9fda80066583f52e695a089d8622439c]    Blog Load (0.2ms)  SELECT "blogs".* FROM "blogs"
[9fda80066583f52e695a089d8622439c]    Rendered blogs/index.html.erb within layouts/application (8.8ms)
[9fda80066583f52e695a089d8622439c]  Completed 200 OK in 32ms (Views: 30.4ms | ActiveRecord: 0.3ms)
[2011-10-21 19:57:59] WARN  Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true
[0962521e4215d645367b58fa41da9f0d] 

Started GET "/assets/application.css?body=1" for 127.0.0.1 at 2011-10-21 19:57:59 +0530
[0962521e4215d645367b58fa41da9f0d] Served asset /application.css - 304 Not Modified (0ms)
[2011-10-21 19:57:59] WARN  Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true
[a7204cec4d2b2e930ac05b41fa1a5c65] 

Started GET "/assets/jquery_ujs.js?body=1" for 127.0.0.1 at 2011-10-21 19:57:59 +0530
[a7204cec4d2b2e930ac05b41fa1a5c65] Served asset /jquery_ujs.js - 304 Not Modified (1ms)
[2011-10-21 19:57:59] WARN  Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true
[202eadd97820dfbf429f87f4725324c3] 

Started GET "/assets/blogs.css?body=1" for 127.0.0.1 at 2011-10-21 19:57:59 +0530
[202eadd97820dfbf429f87f4725324c3] Served asset /blogs.css - 304 Not Modified (2ms)
[2011-10-21 19:57:59] WARN  Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true
[769a2752906bb0c2c5d1eae0a76ac328]

Here I showed some logs in strong. They are the same request for the index page tagged with the same unique id.
The same concept for the subdomain. The subdomain will also come as a tag.

You can also log some of the custom events in log file with the tags!

Logger.tagged("BCX") { Logger.info "Stuff" }                            # Logs "[BCX] Stuff"
Logger.tagged("BCX", "Jason") { Logger.info "Stuff" }                   # Logs "[BCX] [Jason] Stuff"
Logger.tagged("BCX") { Logger.tagged("Jason") { Logger.info "Stuff" } } # Logs "[BCX] [Jason] Stuff"

How to configure it ??

Open up your production.rb or your custom environment file, uncomment the line for log_tags

config.log_tags = [ :subdomain, :uuid ]

And you will get tagged logs with useful information.

Useful links :

Commit URL : https://github.com/rails/rails/commit/afde6fdd5ef3e6b0693a7e330777e85ef4cffddb
Feature Branch : 3.2

Cheers,
@arunagw

Use selenium as a script

Posted by arunagw on March 22, 2011

Hey All,

I came with a situation where i need to test things from browser. It nothing to do with the different browsers. It just to check some validations, some messages with some existing data with me.

I can’t touch the code base. It’s something like QA work.

I am not very much aware about using of selenium IDE which is available in browsers.

I look into the selenium world with ruby and found some interesting stuff that i can script my test and run for a browser.

To run into the browser i need to setup selenium-rc server running.

I have done it in my way. Just small code and using selenium-client gem which allows me to start and stop the selenium-rc server.

Here is my code for selenium-rc server. It also includes the selenium-jar file.
https://github.com/arunagw/selenium-server

For running selenium-rc server. Just clone it. bundle install and then rake selenium:rc:start

All set. Now you are ready to run selenium script from your local machine.

To test things i am using hitting up google.com and validating stuff. A google example is also given on the selenium-client gems readme.

#!/usr/bin/env ruby
#
# Sample Ruby script using the Selenium client API
#
require "rubygems"
gem "selenium-client", ">=1.2.16"
require "selenium/client"

begin
  @browser = Selenium::Client::Driver.new \
      :host => "localhost", 
      :port => 4444, 
      :browser => "*firefox", 
      :url => "http://www.google.com", 
      :timeout_in_second => 60

  @browser.start_new_browser_session
    @browser.open "/"
    @browser.type "q", "Selenium seleniumhq.org"
    @browser.click "btnG", :wait_for => :page
    puts @browser.text?("seleniumhq.org")
ensure
  @browser.close_current_browser_session    
end

You can just run above script after start the selenium-rc server and see the result yourself in the browser.

Some useful links for get up and running selenium with ruby.

Selenium-client for ruby :- https://github.com/ph7/selenium-client
All about selenium with ruby :- http://seleniumhq.org/projects/ruby/

Gem 1.5 with Rails 2.3 5

Posted by arunagw on March 19, 2011

You may fall down into the situation where you don’t have RVM and your system gem is upgraded for using latest things.

And your old application is still running on older version of rails.

This is just a workaround of using Gem > 1.3.7 in Rails 2.3 Applications.

I have tested this solution with Rails 2.3.5 and different version of gems.

After upgrading gems to 1.6.2 i have got an error

/activesupport-2.3.5/lib/active_support/dependencies.rb:55: 
uninitialized constant ActiveSupport::Dependencies::Mutex (NameError)

To fix this error need to update boot.rb file. Place this at the top of boot.rb

require 'thread'

After adding this you should be getting this error

 
/gem_dependency.rb:119:in
 `requirement': undefined local variable or method `version_requirements'

To fix this error you need update your environment.rb file.
Add this code above your Rails::Initializer.run block.

if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.3.7')
 module Rails
   class GemDependency
     def requirement
       r = super
       (r == Gem::Requirement.default) ? nil : r
     end
   end
 end
end

Now your application should start running properly. Have fun ;)

Now you can downgrade or upgrade your system gem version. Your application will still run.

Above workaround works for me very well. Any other ideas?

Redis key-value store 2

Posted by arunagw on March 18, 2011

Redis is really cool and lightweight key-value store. If you are looking for something in which you can store some string, hashes, lists, sets. The Redis is the best.

If you are a Ruby developer then you must try out this with a redis-rb gem. Very easy to configure, very easy to store things.

Following is the way of using redis in Ruby way.

To install

gem install redis

To load

require 'redis'

Before performing any operation with redis server you need to install Redis and start the redis server.

After that you can do like

redis = Redis.new # Automatically connect with the default port.

# if you have changed the port then you can specify the port in initialize.

>> redis.set "foo", "bar"
=> "OK"

>> redis.get "foo"
=> "bar"

Storing objects

>> redis.set "foo", [1, 2, 3].to_json
=> OK

>> JSON.parse(redis.get("foo"))
=> [1, 2, 3]

There are lot’s more things you can do with the Redis.

Links help you in redis

Redis official documentation (http://redis.io)
Github redis repository (https://github.com/antirez/redis)
Github redis rubygem repository (https://github.com/ezmobius/redis-rb)

Bundler Usage — Installing Gems 1

Posted by arunagw on March 18, 2011

Every time you change your Gemfile then you might adding/removing any dependancies in your application.

Just bundle install will install gems for you.

The output may look like

$ bundle install 
Fetching git://github.com/rails/rails.git
Fetching source index for http://rubygems.org/ 
Using rake (0.8.7) 
Installing abstract (1.0.0)
Your bundle is complete! Use `bundle show [gemname]` to see where a
bundled gem is installed.

You can specify groups for special environments

 
$ bundle install --without development test
$ bundle install --without test

You can specify installation directory for your gems.
This will install all the gems into tmp/bundle folder

$ bundle install --path tmp/bundle

You can check your applications bundler config.

 
$ bundle config 

Settings are listed in order of priority. The top value will be used.

disable_shared_gems
  Set for your local app (/Users/arunagw/errorapp/.bundle/config): "1"

path
  Set for your local app (/Users/arunagw/errorapp/.bundle/config): "tmp/bundle"

For more details about bundler you can checkout http://gembundler.com/
And also http://railscasts.com/episodes/201-bundler

Query cache in Rails

Posted by arunagw on February 27, 2011

By default Rails do Query cache. Whenever it execute find it enables the query cache.
You can enable manually by wrapping up in cache block.

Post.cache do
  puts Post.first
  puts Post.first
  puts Post.first
end

Your development.log looks like:

Post Load (1.0ms) SELECT * FROM posts LIMIT 1
CACHE (0.0ms) SELECT * FROM posts LIMIT 1
CACHE (0.0ms) SELECT * FROM posts LIMIT 1

Refactoring Environment

Posted by arunagw on February 24, 2011

Just writing about refactoring environment which can be best when you are doing refactoring in your code base.

Refactoring can be done at any time of your code. When you are refactoring code you can see follow things is a benefit for you.

  1. Have some good tests for which code you are going to refactor.
  2. Let’s pair when you start refactoring. Having a pair while doing refactoring is a great idea.
  3. Code must be under version control. GIT/SVN

 

BasicObject introduced in Ruby 1.9

Posted by arunagw on February 24, 2011

RUBY_VERSION < 1.9

class Parent
end
class Child < Parent
end

puts Child.superclass   #=> Parent
puts Parent.superclass  #=> Object
puts Parent.superclass.superclass  #=> nil

RUBY_VERSION = 1.9

class Parent
end
class Child < Parent
end 

puts Child.superclass   #=> Parent
puts Parent.superclass  #=> Object
puts Parent.superclass.superclass  #=> BasicObject
puts Parent.superclass.superclass.superclass  #=> nil

So now given any class in Ruby, super class will be BasicObject for newer versions.

Rake Migration: Track Rake Tasks with versions

Posted by vatrai on November 08, 2010

I have started working on a plugin which helps rails projects to maintain the list of rake tasks.

We are working on a project there are four to six teams at different geo-locations Bangalore, Kolkata, Edmonton etc.For the same project we have different environments like Developemnt, Testing, Staging, QA, QA2, Beta etc.All teams are working with new features, as well as bug fixes.

Many times we found a situation that a specific rake task should be run on a specific environment to fix the data. A lot of time team members forgot to shoot a mail and tell every team about a rake task which will fix a bug on specific environment. As other people update code base and start using the application they got stuck and it take a lot of time to resolve the issue that a specific task was not run because team did not get any information as such.

To resolve this issue we got a idea form rake tasks to migrate database (db:migrate). So if we can manage rake tasks with versions and if we can keep track of tasks those have been run, and yet to run on system. One can generate a ruby file write there any ruby code or invoke any rake task, and upload to repository other people only take update from repo and run a simple commend and the system will update.

Here we don’t have to worry to inform everybody about new task to fix bug or update system.

Here is the URL for plugin

http://github.com/vatrai/rake_migration

By using generators one can generate blank ruby files prefix with time-stamped version.  Version helps to keep track of tasks that are Runyet to Run on the system. One can specify Rails environment in ruby files, specify what data fix should be run on a specified environment using simple if condition.

To generate simple ruby file use:

ruby script/generate rake_migration <file_name>

This command creates a blank ruby file in {RAILS_ROOT}/rake/migrate directory.  Write ruby code or invoke rake task in the generated ruby file.

To run generated files run rake command:

{RAILS_ROOT} rake rake_migration:migrate

This command runs remaining(yet to run) ruby files in {RAILS_ROOT}/rake/migrate and saves version in rake_migrations table in database.


Follow

Get every new post delivered to your Inbox

Join other followers