# \[ANN\] tagged\_logger 0.2.1

**URL:** <https://www.ruby-forum.com/t/ann-tagged-logger-0-2-1/180571>\
**Category:** Ruby\
**Created:** [December 22, 2009, 12:42am UTC](https://www.ruby-forum.com/t/ann-tagged-logger-0-2-1/180571 "2009-12-22T00:42:52Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![fkocherga](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/f04885/32.png) [@fkocherga](https://www.ruby-forum.com/u/fkocherga)\
**Post date:** [December 22, 2009, 12:42am UTC](https://www.ruby-forum.com/t/ann-tagged-logger-0-2-1/180571/1 "2009-12-22T00:42:52Z")

</div>

Hello all,

I’d like to announce one more logging facility ‘tagged\_logger’:  
[http://github.com/fkocherga/tagged\_logger](http://github.com/fkocherga/tagged_logger)

=== WHY? ===

Several reasons:

1. It makes #logger() method becomes accessible everywhere, so you do  
not have to write code like:  
def initialize; @log = …; end  
or like:  
def initialize(logger); @log = logger; end

2. Should your classes really know what sort of Logger has to be used?  
What if you’ve started using standard Logger, but later decided to  
switch to different logging library? The ‘tagged\_logger’ redirects  
logging to whatever logging library you choose, it allows switching  
without touching logging code. The ‘tagger\_logger’ is sort of binding  
between where and how logging happens.

3. Unlike log4j approach you do not have to build any sort of loggers  
hierarchy, but still you have a lot of control over how logging happens  
including different outputs for different subsystems. Actually chances  
are you already have some taxonomies â€“ class hierarchy, modules, source  
code organized in certain way, why should you think about _one more_  
hierarchy of loggers? The basic idea behind ‘tagged\_logger’ gem is to  
use existing taxonomies implicitly to organize your logging. For  
example, when method of class A logs something:

class A  
def foo; logger.info(“foo”); end  
end

the #logger could be smart enough to figure out that it gets called from  
class A and later you may use this information to set logging rules.  
Here is how:

=== EXAMPLES ===

#1: Simplest one

require ‘tagged\_logger’  
require ‘logger’

TaggedLogger.rules do  
output\_everything\_to Logger.new(STDOUT)  
end  
logger.info(“logger is everywhere!”)

from now on #logger() becomes available in every class.

#2: Defining your own custom logging

require ‘rubygems’  
require ‘tagged\_logger’

TaggedLogger.rules do  
output /.\*/ do | level, tag, msg |  
puts “#{level}-#{tag}: #{msg}”  
end  
end

The regexp passed to ‘output’ rule matches every class name and three  
block arguments are:  
level - one of :debug, :info, :warn, :error, :fatal  
msg - the message being printed  
tag - class name whose method calls #logger()

In block you may do whatever you like. Also you may have several rules  
per one class (or set of classes). Providing block is sort of heavy way  
customization. Very frequently it could be done much simpler:

# 3: Defining separate output for three classes Ftp, Http and Sockets:

TaggedLogger.rules do  
output [Ftp, Http, Sockets] =\> Logger.new(open(“network.log”, “w”))  
end

# 4: Putting log entries for three classes Ftp, Http and Sockets under

one common name Network and setting rule for tag Network :

TaggedLogger.rules do  
rename [Ftp, Http, Sockets] =\> :Network  
output :Network =\> Logger.new(STDOUT)  
end

You may find more examples at:  
[http://github.com/fkocherga/tagged\_logger/tree/master/examples/](http://github.com/fkocherga/tagged_logger/tree/master/examples/)

=== LICENSE ===  
TaggedLogger is released under the MIT license.

–  
Fedor Kocherga  
[http://sidenotes.kocherga.info/](http://sidenotes.kocherga.info/)
