Class: Cabin::Channel
- Inherits:
-
Object
- Object
- Cabin::Channel
- Includes:
- Mixins::Logger, Mixins::Pipe, Mixins::Terminal, 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, &block) ⇒ 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::Terminal
Methods included from Mixins::Timer
Methods included from Mixins::Pipe
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’
104 105 106 107 108 109 110 111 |
# File 'lib/cabin/channel.rb', line 104 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.
98 99 100 |
# File 'lib/cabin/channel.rb', line 98 def metrics @metrics end |
Class Method Details
.each(&block) ⇒ Object
def Cabin::Channel.set
70 71 72 73 74 75 76 |
# File 'lib/cabin/channel.rb', line 70 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.
85 86 87 88 |
# File 'lib/cabin/channel.rb', line 85 def filter(&block) @filters ||= [] @filters << block end |
.filters ⇒ Object
Get a list of filters included in this class.
79 80 81 |
# File 'lib/cabin/channel.rb', line 79 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.
62 63 64 |
# File 'lib/cabin/channel.rb', line 62 def get(identifier=$0) return @channel_lock.synchronize { @channels[identifier] } end |
.set(identifier, channel) ⇒ Object
def Cabin::Channel.get
66 67 68 |
# File 'lib/cabin/channel.rb', line 66 def set(identifier, channel) return @channel_lock.synchronize { @channels[identifier] = channel } end |
Instance Method Details
#context ⇒ Object
def publish
181 182 183 184 |
# File 'lib/cabin/channel.rb', line 181 def context ctx = Cabin::Context.new(self) return ctx end |
#publish(data, &block) ⇒ 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.
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/cabin/channel.rb', line 160 def publish(data, &block) 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| append = block_given? ? block.call(output, event) : true output << event if append end end end |
#remove(key) ⇒ Object
Remove a context value by name.
149 150 151 |
# File 'lib/cabin/channel.rb', line 149 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
118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/cabin/channel.rb', line 118 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
132 133 134 135 136 |
# File 'lib/cabin/channel.rb', line 132 def unsubscribe(id) @subscriber_lock.synchronize do @subscribers.delete(id) end end |