Project

log_switch

0.01
No release in over 3 years
Low commit activity in last 3 years
There's a lot of open issues
Extends a class for singleton style logging that can easily be turned on and off.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

>= 0
>= 2.6.0
>= 1.1.2
>= 0.7.2
 Project Readme

log_switch¶ ↑

github.com/turboladen/log_switch

DESCRIPTION¶ ↑

While developing other gems that required a single class/singleton style logger, I got tired of repeating the code to create that logger and mix it in to my base class. I just wanted to be able to require something, then be able to do:

MyLib.log "some message"

I also wanted to be able to programmatically turn on/off logging by doing something like:

MyLib.log = false

This gem allows just that. Well, almost…

FEATURES/PROBLEMS¶ ↑

Features:

  • require and extend to mix in to your class/module to get a single point of logging

  • Switch on/off logging

  • Use whatever Logger you want

SYNOPSIS¶ ↑

Basic Use¶ ↑

Get your app logging with a single point of logging:

require 'log_switch'

class MyThing
  extend LogSwitch
end

MyThing.log "I like you, Ruby."  # => D, [2011-10-07T14:40:26.697084 #30080] DEBUG -- : I like you, Ruby.

…and then you can simply switch off logging by doing:

MyThing.log = false
MyThing.log "You're my favorite." # => No logging occurs!

By default, LogSwitch sets the log level to :debug. You can change the default log level as you go:

MyThing.log_level = :warn
MyThing.log "Crap!"           # => W, [2011-10-07T15:30:54.012502 #32892]  WARN -- : Crap!

You can pass in the log level for your Logger type too:

MyThing.log "Stuff!", :info      # => I, [2011-10-07T15:28:49.480741 #32892]  INFO -- : Stuff!
MyThing.log "Meow", :fatal       # => F, [2011-10-07T15:32:21.207867 #32892] FATAL -- : Meow

If you have another Logger object you want to write to, no problem:

some_other_logger = Logger.new 'log.txt'
MyThing.logger = some_other_logger
MyThing.log "hi!"
File.open('log.txt', 'r').read    # => Logfile created on 2011-10-07 15:50:19 -0700 by logger.rb/25413
                                  #    D, [2011-10-07T15:51:16.385798 #34026] DEBUG -- : hi!

Hooks¶ ↑

You can also make sure code gets executed before each call to .log. While this really only makes sense when you’re logging from multiple places and/or you’re not sure when the first call to your logger will occur (unlike this example), say you want to makes sure your log directory exists before trying to write the log file to it:

log_directory = File.expand_path('my_log_dir')

MyThing.before do
  FileUtils.mkdir_p(full_directory) unless Dir.exists? log_directory
end

log_file = log_directory + "/sweet_log_bro.txt"
MyThing.logger = Logger.new(log_file)
MyThing.log "Thanks brah!"            # This calls the #before hook, thus
                                      # creating the directory.
MyThing.log "I'm hungry..."           # This also calls the #before hook...

You might just want want a one-time before hook–in that case, .log will call a plain old block that you pass to it, right before writing to the log file. Here’s the above example, using the one-timer:

log_directory = File.expand_path('my_log_dir')

log_file = log_directory + "/sweet_log_bro.txt"
MyThing.logger = Logger.new(log_file)

MyThing.log("Thanks brah!") do
  FileUtils.mkdir_p(full_directory) unless Dir.exists? log_directory
end

# No block gets called here (assuming the +#before+ hook from above hasn't been defined)
MyThing.log "I'm hungry..."

Mixin for lazy people like me¶ ↑

All that stuff above describes how you can extend some class of yours to make it a singleton logger (well, not that you can’t have it do other stuff too…). If you’re using this in a sizeable project, however, it can get tiresome typing out MyThing.log "message" over and over again; for me, it’s usually more like MyThing::Logger.log "message". The {LogSwitch::Mixin} mixin lets you shorten things up.

If you’ve extended {LogSwitch} into a class…

class MyThing
  class Logger
    extend LogSwitch
  end
end

…then you can mix in {LogSwitch::Mixin} to your other classes that you want to use MyThing::Logger.log:

class MyThing
  class WidgetMaker
    include LogSwitch::Mixin

    def make_widget
      log "Making widget...", :info    # This will delegate to MyThing::Logger.log
    end
  end
end

This lets you still use a single logger throughout your classes, but shortens the amount of typing you have to do.

Prepend class name of #log caller to the message¶ ↑

When you’ve got a bunch of different classes doing logging, it’s easy to get lost in all the text. Adding the class name of the class that’s logging a message can make this easier to read. Now log_switch will do that for you, if you use its Mixin.

# lib/my_thing/logger.rb
class MyThing::Logger
  extend LogSwitch
end

MyThing::Logger.log_class_name = true

# lib/my_thing/barrel_roller.rb
class MyThing::BarrelRoller
  include LogSwitch::Mixin

  def do_one
    log "I did a barrel roll!"
  end
end

# somewhere else...
barrel_roller = MyThing::BarrelRoller.new
barrel_roller.do_one      # => D, [2012-11-12T21:11:32.133414 #16645] DEBUG -- : <MyThing::BarrelRoller> I did a barrel roll!

REQUIREMENTS¶ ↑

  • Rubies (tested):

    • MRI 1.9.3

    • MRI 1.9.2

    • MRI 1.8.7

    • ree 1.8.7-2011.03

    • JRuby 1.6.5

    • Rubinius 1.2.4

  • RubyGems:

    • None!

INSTALL¶ ↑

$ gem install log_switch

DEVELOPERS¶ ↑

After checking out the source, run:

$ bundle install

This task will install any missing dependencies for you.

THANKS¶ ↑

I need to thank the github.com/rubiii/savon project for most of the code here. Somehow I ran across how they do logging and started following suit. The code in log_switch is almost identical to Savon’s logging.