<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Gray Soft / The Standard Library / The Books are Wrong About Logger</title>
  <id>tag:graysoftinc.com,2014-03-20:/posts/17</id>
  <updated>2014-04-03T19:31:38Z</updated>
  <link rel="self" href="http://graysoftinc.com/the-standard-library/the-books-are-wrong-about-logger/feed.xml"/>
  <link rel="alternate" href="http://graysoftinc.com/the-standard-library/the-books-are-wrong-about-logger"/>
  <author>
    <name>James Edward Gray II</name>
  </author>
  <entry>
    <title>The 7th Comment on "The Books are Wrong About Logger"</title>
    <link rel="alternate" href="http://graysoftinc.com/the-standard-library/the-books-are-wrong-about-logger#comment_352"/>
    <id>tag:graysoftinc.com,2010-03-18:/comments/352</id>
    <updated>2014-04-03T19:31:38Z</updated>
    <summary>That works too, but I prefer to stick to the public interface the library defines for adjusting the format.  My hope that it will stay supported even if the `call()` method is no longer used internally.</summary>
    <content type="html">&lt;p&gt;That works too, but I prefer to stick to the public interface the library defines for adjusting the format.  My hope that it will stay supported even if the &lt;code&gt;call()&lt;/code&gt; method is no longer used internally.&lt;/p&gt;</content>
    <author>
      <name>James Edward Gray II</name>
    </author>
  </entry>
  <entry>
    <title>The 6th Comment on "The Books are Wrong About Logger"</title>
    <link rel="alternate" href="http://graysoftinc.com/the-standard-library/the-books-are-wrong-about-logger#comment_351"/>
    <id>tag:graysoftinc.com,2010-03-18:/comments/351</id>
    <updated>2014-04-03T19:31:56Z</updated>
    <summary>You can even simplify this a bit more by redefining `Logger::Formatter`&amp;#39;s `call` method via `module_eval`:

```ruby
Logger::Formatter.module_eval(
  %q{ def call(severity, time, progname, msg)} +
  %q{ &amp;quot;#{severity} -- #{format_datetime(time)}...</summary>
    <content type="html">&lt;p&gt;You can even simplify this a bit more by redefining &lt;code&gt;Logger::Formatter&lt;/code&gt;'s &lt;code&gt;call&lt;/code&gt; method via &lt;code&gt;module_eval&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="no"&gt;Logger&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Formatter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;module_eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="sx"&gt;%q{ def call(severity, time, progname, msg)}&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
  &lt;span class="sx"&gt;%q{ "#{severity} -- #{format_datetime(time)}  #{progname}:: #{msg2str(msg)}" end}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Adding this to your script will overwrite the &lt;code&gt;call&lt;/code&gt; method in &lt;code&gt;Formatter&lt;/code&gt;.  I much prefer to manually editing the core Ruby library files, and is more efficient than creating a new subclass.&lt;/p&gt;</content>
    <author>
      <name>Joe Martin</name>
    </author>
  </entry>
  <entry>
    <title>The 5th Comment on "The Books are Wrong About Logger"</title>
    <link rel="alternate" href="http://graysoftinc.com/the-standard-library/the-books-are-wrong-about-logger#comment_90"/>
    <id>tag:graysoftinc.com,2006-12-13:/comments/90</id>
    <updated>2014-04-03T19:28:48Z</updated>
    <summary>Thanks for showing that Neville.  I was unaware of that feature.</summary>
    <content type="html">&lt;p&gt;Thanks for showing that Neville.  I was unaware of that feature.&lt;/p&gt;</content>
    <author>
      <name>James Edward Gray II</name>
    </author>
  </entry>
  <entry>
    <title>The 4th Comment on "The Books are Wrong About Logger"</title>
    <link rel="alternate" href="http://graysoftinc.com/the-standard-library/the-books-are-wrong-about-logger#comment_89"/>
    <id>tag:graysoftinc.com,2006-12-13:/comments/89</id>
    <updated>2014-04-03T19:28:48Z</updated>
    <summary>AFAIK, the following example can be simplified using `Logger`&amp;#39;s block parameter, whereby the block is not &amp;quot;`yield`ed&amp;quot; to unless the level is active… ie:

```ruby
if log.error?
  log.error(expensive_error_report)
end
```

becomes:

```rub...</summary>
    <content type="html">&lt;p&gt;AFAIK, the following example can be simplified using &lt;code&gt;Logger&lt;/code&gt;'s block parameter, whereby the block is not "&lt;code&gt;yield&lt;/code&gt;ed" to unless the level is active… ie:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error?&lt;/span&gt;
  &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expensive_error_report&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;becomes:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;expensive_error_report&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;(Note the curly braces)&lt;/p&gt;</content>
    <author>
      <name>Neville</name>
    </author>
  </entry>
  <entry>
    <title>The 3rd Comment on "The Books are Wrong About Logger"</title>
    <link rel="alternate" href="http://graysoftinc.com/the-standard-library/the-books-are-wrong-about-logger#comment_52"/>
    <id>tag:graysoftinc.com,2006-07-11:/comments/52</id>
    <updated>2014-03-27T01:38:24Z</updated>
    <summary>James, thanks for that! Too bad they didn&amp;#39;t allow for custom logging levels. I just &amp;lt;a href=&amp;quot;http://www.justinlanghorst.com/2006/06/23/adding-to-the-ruby-logger/&amp;quot;&amp;gt;hacked it&amp;lt;/a&amp;gt;, but my solution is just that, a quick hack.</summary>
    <content type="html">&lt;p&gt;James, thanks for that! Too bad they didn't allow for custom logging levels. I just &lt;a href="http://www.justinlanghorst.com/2006/06/23/adding-to-the-ruby-logger/"&gt;hacked it&lt;/a&gt;, but my solution is just that, a quick hack.&lt;/p&gt;</content>
    <author>
      <name>Justin</name>
    </author>
  </entry>
  <entry>
    <title>The 2nd Comment on "The Books are Wrong About Logger"</title>
    <link rel="alternate" href="http://graysoftinc.com/the-standard-library/the-books-are-wrong-about-logger#comment_51"/>
    <id>tag:graysoftinc.com,2006-07-10:/comments/51</id>
    <updated>2014-04-03T19:26:06Z</updated>
    <summary>I just checked the Ruby Cookbook and it mentions `call()`, though your technique of using a subclass is better than my technique of just overriding `call()`.</summary>
    <content type="html">&lt;p&gt;I just checked the Ruby Cookbook and it mentions &lt;code&gt;call()&lt;/code&gt;, though your technique of using a subclass is better than my technique of just overriding &lt;code&gt;call()&lt;/code&gt;.&lt;/p&gt;</content>
    <author>
      <name>Leonard Richardson</name>
    </author>
  </entry>
  <entry>
    <title>The 1st Comment on "The Books are Wrong About Logger"</title>
    <link rel="alternate" href="http://graysoftinc.com/the-standard-library/the-books-are-wrong-about-logger#comment_50"/>
    <id>tag:graysoftinc.com,2006-07-08:/comments/50</id>
    <updated>2014-04-03T19:25:47Z</updated>
    <summary>Thanks for this post.  I&amp;#39;ve just started learning about the Ruby `Logger`, so this was good timing for me.</summary>
    <content type="html">&lt;p&gt;Thanks for this post.  I've just started learning about the Ruby &lt;code&gt;Logger&lt;/code&gt;, so this was good timing for me.&lt;/p&gt;</content>
    <author>
      <name>Jeff</name>
    </author>
  </entry>
  <entry>
    <title>The Books are Wrong About Logger</title>
    <link rel="alternate" href="http://graysoftinc.com/the-standard-library/the-books-are-wrong-about-logger"/>
    <id>tag:graysoftinc.com,2006-07-08:/posts/17</id>
    <updated>2014-04-03T19:31:56Z</updated>
    <summary>They said it couldn't be done, but they were wrong.  Let me show you how to customize Logger's output.</summary>
    <content type="html">&lt;p&gt;I've read several books that introduced the standard &lt;code&gt;Logger&lt;/code&gt; library and they all agree on one thing:  you can't customize the output.  That's so last version in thinking!  Behold…&lt;/p&gt;

&lt;p&gt;Here's a trivial &lt;code&gt;Logger&lt;/code&gt; script, showing basic functionality:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby -w&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"logger"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;expensive_error_report&lt;/span&gt;
  &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;  &lt;span class="c1"&gt;# Heavy Computation Simulation (patent pending)&lt;/span&gt;
  &lt;span class="s2"&gt;"YOU BROKE IT!"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;log&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;STDOUT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Logger&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;INFO&lt;/span&gt;  &lt;span class="c1"&gt;# set out output level above the DEBUG default&lt;/span&gt;

&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"We're not in the verbose debug mode."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"We do see informative logs though."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error?&lt;/span&gt;  &lt;span class="c1"&gt;# check that this will be printed, before waste time&lt;/span&gt;
  &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expensive_error_report&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you run that you will see:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;I, [2006-07-08T11:17:19.531943 #340]  INFO -- : We do see informative logs though.
E, [2006-07-08T11:17:22.532424 #340] ERROR -- : YOU BROKE IT!
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now everyone has always known you can format the date and time display using a &lt;code&gt;strftime()&lt;/code&gt; compatible pattern:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby -w&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"logger"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;expensive_error_report&lt;/span&gt;
  &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
  &lt;span class="s2"&gt;"YOU BROKE IT!"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;log&lt;/span&gt;                 &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;STDOUT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Logger&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;INFO&lt;/span&gt;
&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime_format&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"%Y-%m-%d %H:%M "&lt;/span&gt;  &lt;span class="c1"&gt;# simplify time output&lt;/span&gt;

&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"We're not in the verbose debug mode."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"We do see informative logs though."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error?&lt;/span&gt;
  &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expensive_error_report&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Which gives us the slightly easier to read:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;I, [2006-07-08 11:23 #384]  INFO -- : We do see informative logs though.
E, [2006-07-08 11:23 #384] ERROR -- : YOU BROKE IT!
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;All books I've read to date though tell you that's the end of the customization line.  But, if you are using Ruby 1.8.4 or higher, it's no longer true:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby -w&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"logger"&lt;/span&gt;

&lt;span class="c1"&gt;# Build a Logger::Formatter subclass.&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PrettyErrors&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Logger&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Formatter&lt;/span&gt;
  &lt;span class="c1"&gt;# Provide a call() method that returns the formatted message.&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;severity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;program_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;severity&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"ERROR"&lt;/span&gt;
      &lt;span class="n"&gt;datetime&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"%Y-%m-%d %H:%M"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;print_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"!!! &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;) !!!"&lt;/span&gt;
      &lt;span class="n"&gt;border&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"!"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;print_message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;
      &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;border&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;print_message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;border&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="k"&gt;super&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;expensive_error_report&lt;/span&gt;
  &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
  &lt;span class="s2"&gt;"YOU BROKE IT!"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;log&lt;/span&gt;           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;STDOUT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Logger&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;INFO&lt;/span&gt;
&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;formatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;PrettyErrors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;  &lt;span class="c1"&gt;# Install custom formatter!&lt;/span&gt;

&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"We're not in the verbose debug mode."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"We do see informative logs though."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error?&lt;/span&gt;
  &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expensive_error_report&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here's what that code produces:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;I, [2006-07-08T12:20:31.325112 #521]  INFO -- : We do see informative logs though.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!! YOU BROKE IT! (2006-07-08 12:20) !!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Don't believe everything you read.&lt;/p&gt;</content>
    <author>
      <name>James Edward Gray II</name>
    </author>
  </entry>
</feed>
