-
-
Save kristopolous/3020544 to your computer and use it in GitHub Desktop.
class OmniLog | |
attr_reader :available | |
def initialize(path) | |
@real = Logger.new(path) | |
@fake = Logger.new("/dev/null") | |
@available = Set.new | |
end | |
def add!(which) | |
unless respond_to? which | |
self.class.instance_eval do | |
define_method(which.to_sym) { @real } | |
end | |
@available << which | |
end | |
end | |
def remove!(which) | |
which = which.to_sym | |
self.class.instance_eval do | |
undef_method which if respond_to? which | |
end | |
end | |
def method_missing(meth, *args, &block) | |
@real.method(meth).call(*args) if @real.respond_to? meth | |
@available << meth unless @available.include? meth | |
@fake | |
end | |
end |
Could you provide some kind of benchmark. This vs Logger
vs Syslog
?
Hi paneq. It's certainly slower than Logger since it's a wrapper. It pivots on method_missing, which would probably be the biggest performance hit. I don't know the profiling of Logger vs. Syslog.
I understand what you are getting at though ... a free tracing/logging that you can simply disable and everything goes as if you didn't have the code there. Right ... that's a wonderful goal, but that's not this one.
This was more to address what can be the ridiculous verbosity of logs in a complex application. My programming style in ruby doesn't really involve a debugger, it involves just immense printing of information.
Having a single dimension of severity doesn't really help me isolate a problem. I could simply add and remove debug messages, but in the real world, things are stateful unfortunately so you often get problems from large scale cascaded parts interacting with each other (my big application for this right now is a peer-to-peer networking system). So simply being tidy about adding and then removing debug messages will add overhead once your application gets big.
No. It would be nice if I could tell large swaths to shutup or print as necessary. That's really the primary goal of this abstraction. Performance really wasn't a goal, and if it is yours, then I suggest you totally discard this solution and think from the ground up ... since I never had it as a conscious goal, your end result will probably look dramatically different from mine, whether you start with mine or not.
Best of luck!
It's similar to Logger (http://www.ruby-doc.org/stdlib-1.9.3/libdoc/logger/rdoc/…) but it has one extra big one:
namespaces.
The problem is that my application gets big and I want to be able to look at say, just the debug messages for a certain section, there was no good way of having a huge heap to catch them all, without it going by showing a bunch of stuff I don't want.
So I created OmniLog. Instead of doing something like
myLog = Logger.new("log.txt")
you do
myLog = OmniLog.new("log.txt")
myLog.[debug, warn, fatal, error, info] still work as before, but now you can do
myLog.connectionManager.debug "blah"
and then turn on "connectionManager" messages anywhere by doing
myLog.add! "connectionManager"
or removing them by doing
myLog.remove! "connectionManager"
You can also get all the available namespaces by doing
(Set) myLog.available
My usage scenario is near the top of my application I have something like
So then I can freely add and remove sections with a single line change, regardless of the severity of the thing being logged