failure is not an option - static.eventials.com · failure is not an option or: how i learned to...

52
Hiro Asari Senior Software Engineer Red Hat Failure is not an option or: How I learned to read the logs and love the stack trace RubyConf Brasil 2012 Friday, August 31, 12

Upload: ngobao

Post on 26-Dec-2018

223 views

Category:

Documents


0 download

TRANSCRIPT

Hiro AsariSenior Software EngineerRed Hat

Failure is not an optionor: How I learned to read the logs and love the stack trace

RubyConf Brasil 2012

Friday, August 31, 12

Failure is not an optionor: How I learned to read the logs and love the stack trace

Hiro AsariJRuby Support Engineer

RubyConf Brasil 2012

Friday, August 31, 12

Friday, August 31, 12

If debugging is the process of removing bugs, then programming must be the process of putting them in.

Edsger Dijkstra©2002 Hamilton Richards

Friday, August 31, 12

All code appearing in this talk are fictitious. Any resemblance

to real code fragments, in production or otherwise, is

purely coincidental.

Friday, August 31, 12

Discovery

Friday, August 31, 12

Know where your logs are

http://www.flickr.com/photos/41449558@N06/6690612703Friday, August 31, 12

/var/log/*$RAILS_ROOT/log

Friday, August 31, 12

Gather the logs

http://www.flickr.com/photos/30505480@N00/6820686281Friday, August 31, 12

Know your architecture

http://en.wikipedia.org/wiki/File:Ponte_estaiada_Octavio_Frias_-_Sao_Paulo.jpg

Friday, August 31, 12

http://goo.gl/maps/hBrzmFriday, August 31, 12

HAProxy

nginx

unicorn

nginx nginx nginx nginx

unicorn unicorn unicorn

request

Web Server

Friday, August 31, 12

HAProxy

nginx

unicorn

nginx nginx nginx nginx

unicorn unicorn unicorn

request

Friday, August 31, 12

http://www.flickr.com/photos/usnavy/6871499850/

What if there are no logs?

Friday, August 31, 12

Generating logs

• Debugger

• IRB

• pry

• p / pp / puts

Friday, August 31, 12

Debug!

Friday, August 31, 12

⋮gems/bundler-1.0.9/lib/bundler/ui.rb:56: uninitialized constant Gem::SilentUI (NameError)⋮

$ bundle install$

Friday, August 31, 12

know?

Does

Friday, August 31, 12

Answer:

Update to Bundler 1.0.10

or later

Friday, August 31, 12

Read th

e stac

k trac

e

http://www.flickr.com/photos/26699508@N04/2529389660

Friday, August 31, 12

NoMethodError: undefined method `[]' for nil:NilClass! !initialize at c:/jruby/lib/ruby/gems/1.8/gems/metric_fu-2.1.1/lib/generators/saikuro.rb:232! !get_elements at c:/jruby/lib/ruby/gems/1.8/gems/metric_fu-2.1.1/lib/generators/saikuro.rb:169! !initialize at c:/jruby/lib/ruby/gems/1.8/gems/metric_fu-2.1.1/lib/generators/saikuro.rb:130! !assemble_files at c:/jruby/lib/ruby/gems/1.8/gems/metric_fu-2.1.1/lib/generators/saikuro.rb:111

Example

Friday, August 31, 12

def initialize(line)!!@line = line!!@element_type = line.match(TYPE_REGEX)[1].strip!!@name = line.match(NAME_REGEX)[1].strip!!@complexity = line.match(COMPLEXITY_REGEX)[1].strip!!@lines = line.match(LINES_REGEX)[1].strip!!@defs = []end

Example

line 232

Friday, August 31, 12

rake assets:precompile failure

Example

JRuby 1.6.6Rails 3.1.1

can't convert Encoding into String

Friday, August 31, 12

rake aborted!can't convert Encoding into String (in /opt/jruby/lib/ruby/gems/shared/gems/haml_coffee_assets-0.6.0/vendor/assets/javascripts/hamlcoffee.js.coffee.erb)org/jruby/RubyIO.java:3722:in `popen'/opt/jruby/lib/ruby/gems/shared/gems/execjs-1.2.9/lib/execjs/external_runtime.rb:165:in `sh'/opt/jruby/lib/ruby/gems/shared/gems/execjs-1.2.9/lib/execjs/external_runtime.rb:125:in `exec_runtime'org/jruby/RubyBasicObject.java:1700:in `__send__'org/jruby/RubyKernel.java:2099:in `send'⋮

Example

Friday, August 31, 12

def sh(command) output, options = nil, {} options[:external_encoding] = @encoding if @encoding options[:internal_encoding] =

Encoding.default_internal || 'UTF-8' IO.popen(command, options) { |f| output = f.read } output end

line 165

jruby -e 'output = nil; IO.popen("ls",{:internal_encoding => Encoding::EucJP}) { |f| output = f.read }; p output'

Minimal Failure

Friday, August 31, 12

$ jruby -v --1.9 -e 'output = nil; IO.popen("ls",{:internal_encoding => Encoding::EucJP}) { |f| output = f.read }; p output'jruby 1.6.6 (ruby-1.9.2-p312) (2012-01-30 5673572) (Java HotSpot(TM) 64-Bit Server VM 1.7.0_04) [darwin-x86_64-java]TypeError: can't convert Encoding into String popen at org/jruby/RubyIO.java:3722 (root) at -e:1

Example

Friday, August 31, 12

rake aborted!can't convert Encoding into String (in /opt/jrubylib/ruby/gems/shared/gems/haml_coffee_assets-0.6.0/vendor/assets/javascripts/hamlcoffee.js.coffee.erb)org/jruby/RubyIO.java:3722:in `popen'/opt/jrubylib/ruby/gems/shared/gems/execjs-1.2.9/lib/execjs/external_runtime.rb:165:in `sh'/opt/jrubylib/ruby/gems/shared/gems/execjs-1.2.9/lib/execjs/external_runtime.rb:125:in `exec_runtime'org/jruby/RubyBasicObject.java:1700:in `__send__'org/jruby/RubyKernel.java:2099:in `send'⋮

Example

Friday, August 31, 12

Time to

run debugger!

Friday, August 31, 12

Friday, August 31, 12

Friday, August 31, 12

Friday, August 31, 12

Friday, August 31, 12

Rails footnotes plugin

Friday, August 31, 12

Safeguards

Friday, August 31, 12

Test your code before you ship

Friday, August 31, 12

Set up continuous integration

• Travis http://travis-ci.org

• Jenkins http://jenkins-ci.org

Friday, August 31, 12

Code Coverage

• Shows what you did not test

• Does not show your tests are complete

Friday, August 31, 12

def foo(arg) begin if arg.nil? raise ArgumentError else raise RegexpError end rescue Exception raise "Play it again, Sam" endend

Rescue exceptions judiciously

Friday, August 31, 12

def foo(arg) begin if arg.nil? raise ArgumentError else raise RegexpError end rescue Exception => e raise e endend

Rescue exceptions judiciously

Friday, August 31, 12

unless arg.is_a? Array arg = [arg] end # do stuff with arg arg.each do … endend

Let it faildef foo(arg)

Friday, August 31, 12

# do stuff with arg arg.each do … endend

Let it fail

unless arg.is_a? Array arg = [arg] end

def foo(arg)

Friday, August 31, 12

# do stuff with arg arg.each do … endend

Let it faildef foo(arg)

Friday, August 31, 12

def foo(*args) args.each do … endend

Let it fail

Friday, August 31, 12

Prefer hard-coded* error messages

Ugh!

$ ack -c 'Expected.*but got' .15

$ ruby -S awesome_appExpected 1, but got 2.

Friday, August 31, 12

irb(main):007:0> obj.foo.foo.foo.foo.fooNoMethodError: undefined method `foo' for nil:NilClass!!!! from (irb):7!!!! from /usr/local/bin/irb2.0:12:in `<main>'

Method chaining

Friday, August 31, 12

…if you're as clever as you can be when you write [a program], how will you ever debug it?

Brian KernighanFriday, August 31, 12

Test your code before you ship

Friday, August 31, 12

Optimize for humans

…who deal with your present failures

Friday, August 31, 12

Remember this guy?

It is you!

Friday, August 31, 12

One More Thing…

Friday, August 31, 12

http://yqg06172.img.jugem.jp/20110824_2225189.jpg

Friday, August 31, 12