Production Code Analysis

You can't improve if you can't measure, or improve what you don't know

How Dead Code Sticks Around

Finding Dead Code

Using 3rd Party tool (NewRelic)

Easiest way, look transactions over last 7 days: (note won't help with specific formats or never hit endpoints)

Using 3rd Party tool (NewRelic)

LS made a gem to help, newrelic_route_check compare NR reports to Rails routes.
download the `controller_summary.csv`

run `bundle exec rake newrelic:compare_with_routes`

found 335 uniq new relic controller action hits
found 562 uniq Rails routes controller action pairs
exists in new relic, but not in routes: 0
never accessed in new relic stats: ***
Pipeline::DealsController#show
Pipeline::EmailTemplatesController#show
SubscribeButtonController#dropdown_for_deal
SubscribeButtonController#subscribe_to_deal
...
AuthorizationRulesController#graph
AuthorizationRulesController#change
      

Stats Instrumentation

Stats Instrumentation: Background Events Executed

# Example for Resque background jobs
STATSD = Statsd.new(host, port).tap{|sd| sd.namespace = 'app_name'}

def before_perform(*args)
  STATSD.increment "resque.processed.#{get_event_name}"
end

def after_perform(*args)
  STATSD.increment "resque.completed.#{get_event_name}"
end

Stats Instrumentation: Emails Sent

# Example for ActionMailer
STATSD = Statsd.new(host, port).tap{|sd| sd.namespace = 'app_name'}

class BaseMailer < ActionMailer::Base
  def initialize(method_name=nil, *parameters)
    STATSD.increment "mailers.base_mailer.#{method_name}" if method_name
    #...
    super(method_name, *parameters)
  end
end

Stats Instrumentation: Views Rendered

ActiveSupport::Notifications.subscribe /render_partial.action_view|render_template.action_view/ do |name, start, finish, id, payload| 
  RenderTracker.track_template(name, start, finish, id, payload) unless name.include?('!') 
end

class RenderTracker
  def self.track_template(name, start, finish, id, payload)
    if file = payload[:identifier]
      Statsd.increment "views.#{file}"
    end
    if layout = payload[:layout]
      Rails.logger.info "[RenderTracker] layout: #{layout}"
    end
  end
end

Stats Instrumentation: Views Rendered

We made a gem for that and some helpers: Flatfoot

FLATFOOT = Flatfoot::Tracker.new(Redis.new)

ActiveSupport::Notifications.subscribe /render_partial.action_view|render_template.action_view/ do |name, start, finish, id, payload|
  FLATFOOT.track_views(name, start, finish, id, payload) unless name.include?('!') 
end

FLATFOOT.used_views
=> ["app/views/home/index.html.erb",...

FLATFOOT.unused_views
=> ["app/views/something/_old_partial.html.erb",...

Stats Instrumentation: One Off Trackers

# Example Tracking a code path
class HomeController < ApplicationController
  def show
    if request.xhr?
       #some weird logic
       STATSD.increment "deprecated.home_controller.show.xhr"
     end
    respond_to do |format|
        format.html { STATSD.increment "deprecated.home.show.html" }
        format.json { STATSD.increment "deprecated.home.show.json" }
        format.mobile { STATSD.increment "deprecated.home.show.mobile" }
    end
  end
end

Stats Instrumentation: Production Performance Comparisons

shout out to @ubermajestix (Tyler Montgomery) for showing me the timing trick

STATSD = Statsd.new(host, port).tap{|sd| sd.namespace = 'app_name'}

def example_html_stripping_method
  strip_method = rand(2)&1 == 0 ? 'nokogiri' : 'strip_tags'
  desc = STATSD.time("application_helper.example_html_stripping_method.#{strip_method}") do
    if strip_method == 'strip_tags'
      strip_tags(desc_raw).gsub(/^\s+/,'').gsub(/\s+$/,'')
    else
      Nokogiri::HTML.parse(desc_raw).text.strip
    end
  end
  #...
end

Stats Instrumentation: Translations Usage

We made a gem for that @Chrismo (Chris Morris) built: Humperdink

class KeyTracker
  def initialize(redis, key)
    redis_set = Humperdink::RedisDirtySet.new(:redis => redis, :key => key, :max_dirty_items => 9)
    @tracker = Humperdink::Tracker.new(redis_set, :enabled => true)
  end

  def on_translate(locale, key, options = {})
    begin
      if @tracker.tracker_enabled
        requested_key = normalize_requested_key(key, options)
        @tracker.track(requested_key)
      end
    rescue => e
      @tracker.shutdown(e)
    end
  end
...

Production Code Coverage: Coverband

Production Code Coverage: Coverband

baseline = Coverband.parse_baseline
Coverband.configure do |config|
  config.root              = Dir.pwd
  config.redis   = Redis.new(:host => 'redis.host.com')
  config.coverage_baseline = baseline
  config.root_paths        = ['/app/']
  config.ignore            = ['vendor']
  config.startup_delay = Rails.env.production? ? 15 : 1
  config.percentage    = Rails.env.production? ? 20.0 : 90.0
  config.stats         = Statsd.new('stat.my.com', 25)
  config.verbose       = Rails.env.production? ? false: true
end

Production Code Coverage: Coverband

#configure rake
require 'coverband'
Coverband.configure
require 'coverband/tasks'

#setup middleware in `config.ru`
require File.dirname(__FILE__) + '/config/environment'
require 'coverband'
Coverband.configure

use Coverband::Middleware
run ActionController::Dispatcher.new

Logs

Logs: Better with Imprint

Another LS gem Imprint

Thanks

/