Class: Cabin::Channel
- Inherits:
-
Object
- Object
- Cabin::Channel
- Includes:
- Mixins::Logger, Mixins::Timer, Mixins::Timestamp
- Defined in:
- lib/cabin/channel.rb
Overview
A wonderful channel for logging.
You can log normal messages through here, but you should be really shipping structured data. A message is just part of your data. “An error occurred” - in what? when? why? how?
Logging channels support the usual ‘info’ ‘warn’ and other logger methods provided by Ruby’s stdlib Logger class
It additionally allows you to store arbitrary pieces of data in it like a hash, so your call stack can do be this:
@logger = Cabin::Channel.new
rubylog = Logger.new(STDOUT) # ruby's stlib logger
@logger.subscribe(rubylog)
def foo(val)
context = @logger.context()
context[:foo] = val
context[:example] = 100
()
# Clear any context we just wanted bar() to know about
context.clear()
@logger.info("Done in foo")
end
def
@logger.info("Fizzle")
end
The result:
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}
Constant Summary
Constants included from Mixins::Logger
Mixins::Logger::BACKTRACE_RE, Mixins::Logger::LEVELS
Instance Attribute Summary collapse
-
#metrics ⇒ Object
All channels come with a metrics provider.
Attributes included from Mixins::Logger
Class Method Summary collapse
-
.each(&block) ⇒ Object
def Cabin::Channel.set.
-
.filter(&block) ⇒ Object
Register a new filter.
-
.filters ⇒ Object
Get a list of filters included in this class.
-
.get(identifier = $0) ⇒ Object
Get a channel for a given identifier.
-
.set(identifier, channel) ⇒ Object
def Cabin::Channel.get.
Instance Method Summary collapse
-
#context ⇒ Object
def publish.
-
#initialize ⇒ Channel
constructor
Create a new logging channel.
-
#publish(data) ⇒ Object
Publish data to all outputs.
-
#remove(key) ⇒ Object
Remove a context value by name.
-
#subscribe(output) ⇒ Object
Subscribe a new input New events will be sent to the subscriber using the ‘<<’ method foo << event.
-
#unsubscribe(id) ⇒ Object
Unsubscribe.
Methods included from Mixins::Timer
Methods included from Mixins::Logger
Methods included from Mixins::Timestamp
Constructor Details
#initialize ⇒ Channel
Create a new logging channel. The default log level is ‘info’
100 101 102 103 104 105 106 107 |
# File 'lib/cabin/channel.rb', line 100 def initialize @subscribers = {} @data = {} @level = :info @metrics = Cabin::Metrics.new @metrics.channel = self @subscriber_lock = Mutex.new end |
Instance Attribute Details
#metrics ⇒ Object
All channels come with a metrics provider.
94 95 96 |
# File 'lib/cabin/channel.rb', line 94 def metrics @metrics end |
Class Method Details
.each(&block) ⇒ Object
def Cabin::Channel.set
68 69 70 71 72 73 74 |
# File 'lib/cabin/channel.rb', line 68 def each(&block) @channel_lock.synchronize do @channels.each do |identifier, channel| yield identifier, channel end end end |
.filter(&block) ⇒ Object
Register a new filter. The block is passed the event. It is expected to modify that event or otherwise do nothing.
83 84 85 86 |
# File 'lib/cabin/channel.rb', line 83 def filter(&block) @filters ||= [] @filters << block end |
.filters ⇒ Object
Get a list of filters included in this class.
77 78 79 |
# File 'lib/cabin/channel.rb', line 77 def filters @filters ||= [] end |
.get(identifier = $0) ⇒ Object
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.
60 61 62 |
# File 'lib/cabin/channel.rb', line 60 def get(identifier=$0) return @channel_lock.synchronize { @channels[identifier] } end |
.set(identifier, channel) ⇒ Object
def Cabin::Channel.get
64 65 66 |
# File 'lib/cabin/channel.rb', line 64 def set(identifier, channel) return @channel_lock.synchronize { @channels[identifier] = channel } end |
Instance Method Details
#context ⇒ Object
def publish
176 177 178 179 |
# File 'lib/cabin/channel.rb', line 176 def context ctx = Cabin::Context.new(self) return ctx end |
#publish(data) ⇒ Object
Publish data to all outputs. The data is expected to be a hash or a string.
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.
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/cabin/channel.rb', line 156 def publish(data) event = {} self.class.filters.each do |filter| filter.call(event) end if data.is_a?(String) event[:message] = data else event.merge!(data) end event.merge!(@data) # Merge any logger context @subscriber_lock.synchronize do @subscribers.each do |id, output| output << event end end end |
#remove(key) ⇒ Object
Remove a context value by name.
145 146 147 |
# File 'lib/cabin/channel.rb', line 145 def remove(key) @data.delete(key) end |
#subscribe(output) ⇒ Object
Subscribe a new input New events will be sent to the subscriber using the ‘<<’ method
foo << event
Returns a subscription id you can use later to unsubscribe
114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/cabin/channel.rb', line 114 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) output = Cabin::Outputs::IO.new(output) end @subscriber_lock.synchronize do @subscribers[output.object_id] = output end return output.object_id end |
#unsubscribe(id) ⇒ Object
Unsubscribe. Takes a ‘subscription id’ as returned by the subscribe method
128 129 130 131 132 |
# File 'lib/cabin/channel.rb', line 128 def unsubscribe(id) @subscriber_lock.synchronize do @subscribers.delete(id) end end |