lib/cabin/channel.rb in cabin-0.4.2 vs lib/cabin/channel.rb in cabin-0.4.3
- old
+ new
@@ -1,8 +1,9 @@
require "cabin/mixins/logger"
+require "cabin/mixins/timestamp"
+require "cabin/mixins/timer"
require "cabin/namespace"
-require "cabin/timer"
require "cabin/context"
require "cabin/outputs/stdlib-logger"
require "cabin/outputs/io"
require "cabin/metrics"
require "logger"
@@ -43,30 +44,46 @@
#
# I, [2011-10-11T01:00:57.993200 #1209] INFO -- : {:timestamp=>"2011-10-11T01:00:57.992353-0700", :foo=>"Hello", :example=>100, :message=>"Fizzle", :level=>:info}
# I, [2011-10-11T01:00:57.993575 #1209] INFO -- : {:timestamp=>"2011-10-11T01:00:57.993517-0700", :message=>"Done in foo", :level=>:info}
#
class Cabin::Channel
+ class << self
+ # Get a channel for a given identifier. If this identifier has never been
+ # used, a new channel is created for it.
+ # The default identifier is the application executable name.
+ #
+ # This is useful for using the same Cabin::Channel across your
+ # entire application.
+ def get(identifier=$0)
+ @channels ||= Hash.new { |h,k| h[k] = Cabin::Channel.new }
+ return @channels[identifier]
+ end # def Cabin::Channel.get
+
+ # Get a list of filters included in this class.
+ def filters
+ @filters ||= []
+ end # def Cabin::Channel.filters
+
+ # Register a new filter. The block is passed the event. It is expected to
+ # modify that event or otherwise do nothing.
+ def filter(&block)
+ @filters ||= []
+ @filters << block
+ end
+ end # class << self
+
include Cabin::Mixins::Logger
+ include Cabin::Mixins::Timestamp
+ include Cabin::Mixins::Timer
# All channels come with a metrics provider.
attr_accessor :metrics
+
+ private
- # Get a channel for a given identifier. If this identifier has never been
- # used, a new channel is created for it.
- # The default identifier is the application executable name.
- #
- # This is useful for using the same Cabin::Channel across your
- # entire application.
- public
- def self.get(identifier=$0)
- @channels ||= Hash.new { |h,k| h[k] = Cabin::Channel.new }
- return @channels[identifier]
- end # def Cabin::Channel.get
-
# Create a new logging channel.
# The default log level is 'info'
- public
def initialize
@outputs = []
@data = {}
@level = :info
@metrics = Cabin::Metrics.new
@@ -74,11 +91,10 @@
end # def initialize
# Subscribe a new input
# New events will be sent to the subscriber using the '<<' method
# foo << event
- public
def subscribe(output)
# Wrap ruby stdlib Logger if given.
if output.is_a?(::Logger)
output = Cabin::Outputs::StdlibLogger.new(output)
elsif output.is_a?(::IO)
@@ -88,23 +104,20 @@
# TODO(sissel): Return a method or object that allows you to easily
# unsubscribe?
end # def subscribe
# Set some contextual map value
- public
def []=(key, value)
@data[key] = value
end # def []=
# Get a context value by name.
- public
def [](key)
@data[key]
end # def []
# Remove a context value by name.
- public
def remove(key)
@data.delete(key)
end # def remove
# Publish data to all outputs. The data is expected to be a hash or a string.
@@ -112,54 +125,38 @@
# A new hash is generated based on the data given. If data is a string, then
# it will be added to the new event hash with key :message.
#
# A special key :timestamp is set at the time of this method call. The value
# is a string ISO8601 timestamp with microsecond precision.
- public
def publish(data)
- event = {
- :timestamp => Time.now.strftime("%Y-%m-%dT%H:%M:%S.%6N%z")
- }
- event.merge!(@data)
- # TODO(sissel): need to refactor string->hash shoving.
+ event = {}
+ event.merge!(@data) # Merge any logger context
+
if data.is_a?(String)
event[:message] = data
else
event.merge!(data)
end
+ self.class.filters.each do |filter|
+ filter.call(event)
+ end
+
@outputs.each do |out|
out << event
end
end # def publish
- # Start timing something.
- # Returns an instance of Cabin::Timer bound to this Cabin::Channel.
- # To stop the timer and immediately emit the result to this channel, invoke
- # the Cabin::Timer#stop method.
- public
- def time(data, &block)
- # TODO(sissel): need to refactor string->hash shoving.
- if data.is_a?(String)
- data = { :message => data }
- end
-
- timer = Cabin::Timer.new do |duration|
- # TODO(sissel): Document this field
- data[:duration] = duration
- publish(data)
- end
-
- if block_given?
- block.call
- return timer.stop
- else
- return timer
- end
- end # def time
-
- public
def context
ctx = Cabin::Context.new(self)
return ctx
end # def context
+
+ def dataify(data)
+ if data.is_a?(String)
+ data = { :message => data }
+ end
+ return data
+ end # def dataify
+
+ public(:initialize, :context, :subscribe, :[]=, :[], :remove, :publish, :time, :context)
end # class Cabin::Channel