# Log4r configuration: "/dev/null" outputter question

**URL:** <https://www.ruby-forum.com/t/log4r-configuration-dev-null-outputter-question/109638>\
**Category:** Ruby\
**Created:** [July 17, 2007, 2:38pm UTC](https://www.ruby-forum.com/t/log4r-configuration-dev-null-outputter-question/109638 "2007-07-17T14:38:12Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ronaldfischer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/67e7ee/32.png) [@ronaldfischer](https://www.ruby-forum.com/u/ronaldfischer)\
**Post date:** [July 17, 2007, 2:38pm UTC](https://www.ruby-forum.com/t/log4r-configuration-dev-null-outputter-question/109638/1 "2007-07-17T14:38:12Z")

</div>

Well, my code does seem to work, but I have the feeling that I could  
have  
done it much simpler… So here is my problem:

I would like to control log4r via an environment variable, which can  
contain one of 4 types of values:

stdout : logging goes to stdout  
stderr : logging goes to stderr  
file:FILENAME : logging goes to FILENAME  
none : logging not needed

The problem is what outputter to use to implement ‘none’. My first idea  
to simply use FileOutputter(‘none’,:filename =\> ‘/dev/null’) does not  
work  
because my code is also supposed to run onder Windows where we don’t  
have  
/dev/null. So I came up with the solution to invent a “NullOutputter”:

class NullOutputter \<Outputter  
def initialize(name)  
super(name)  
end  
end

…

$log = Logger.new(‘TestLog’)  
outputterspec=ENV[‘TFW\_LOG’] || ‘stdout’  
$log.outputters = case outputterspec  
when ‘stdout’  
Outputter.stdout  
when ‘stderr’  
Outputter.stderr  
when /^file:(.+)$/  
FileOutputter.new ‘tfw’, :filename =\> $1, :trunc =\> true  
when ‘none’  
NullOutputter.new ‘tfwnull’  
end

Note that I did NOT use

when ‘none’  
Outputter.new ‘tfwnull’

because Outputter is documented as abstract class.

My solution works, but I wonder whether I could make it simpler  
(i.e. without creating the NullOutputter class).

Ronald

---

<div class="post-metadata">

**Author:** ![ronaldfischer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/67e7ee/32.png) [@ronaldfischer](https://www.ruby-forum.com/u/ronaldfischer)\
**Post date:** [July 17, 2007, 4:57pm UTC](https://www.ruby-forum.com/t/log4r-configuration-dev-null-outputter-question/109638/2 "2007-07-17T16:57:33Z")

</div>

On 7/17/07, Ronald F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> The problem is what outputter to use to implement ‘none’. My first idea  
> to simply use FileOutputter(‘none’,:filename =\> ‘/dev/null’) does not  
> work  
> because my code is also supposed to run onder Windows where we don’t  
> have  
> /dev/null.

There is a /dev/null equivalent on Windows, NUL: You can use it in  
this fashion …

fn = test(?e, ‘/dev/null’) ? ‘/dev/null’ : ‘NUL:’  
fd = File.open(fn, ‘w’)

You can now write to that file descriptor and everything will go to  
the bit bucket.

> My solution works, but I wonder whether I could make it simpler  
> (i.e. without creating the NullOutputter class).

Certainly. Just create an instance of Outputter and then define the  
methods you need.

out = Outputter.new ‘tfwnull’  
class \<\< out  
def canonical\_log(logevent) nil end  
end

The canonical\_log method is used by the outputters to format the log  
event and then write the formatted output to a file. By setting this  
to have a nil body, you will save a few cycles each time a log  
messages needs to be generated.

Another options is just to set the global log level to ‘off’. That is  
left as an exercise for the reader 😉

Blessings,  
TwP

---

<div class="post-metadata">

**Author:** ![ronaldfischer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/67e7ee/32.png) [@ronaldfischer](https://www.ruby-forum.com/u/ronaldfischer)\
**Post date:** [July 18, 2007, 10:03am UTC](https://www.ruby-forum.com/t/log4r-configuration-dev-null-outputter-question/109638/3 "2007-07-18T10:03:57Z")

</div>

> end  
> Now I wonder, since Outputter is documented as _abstract_ class, why  
> I can instantiate it at all? Or is “abstract class” in Ruby not dealt  
> with the same strength as in, say, Java or C++?

But anyway, I tried your approach, but I don’t see how I get the  
instance  
of the anonymous class into my outputters. When I do it like this:

#!/usr/bin/ruby  
require ‘log4r’  
include Log4r  
$log=Logger.new(‘testing’)  
out = Outputter.new ‘tfwnull’  
$log.outputters=class \<\< out  
def canonical\_log(logevent) nil end  
end

I get the error message

“Expected kind of Outputter, got NilClass (TypeError)”

Ronald
