Class: Cabin::Channel

Inherits:
Object
  • Object
show all
Includes:
Mixins::Logger
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
  bar()

  # Clear any context we just wanted bar() to know about
  context.clear()

  @logger.info("Done in foo")
end

def bar
  @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::LEVELS

Instance Attribute Summary collapse

Attributes included from Mixins::Logger

#level

Instance Method Summary collapse

Constructor Details

#initializeChannel

Returns a new instance of Channel.



53
54
55
56
57
58
# File 'lib/cabin/channel.rb', line 53

def initialize
  @outputs = []
  @data = {}
  @level = :info
  @metrics = Cabin::Metrics.new
end

Instance Attribute Details

#metricsObject

Returns the value of attribute metrics.



48
49
50
# File 'lib/cabin/channel.rb', line 48

def metrics
  @metrics
end

Instance Method Details

#[](key) ⇒ Object



82
83
84
# File 'lib/cabin/channel.rb', line 82

def [](key)
  @data[key]
end

#[]=(key, value) ⇒ Object



76
77
78
# File 'lib/cabin/channel.rb', line 76

def []=(key, value)
  @data[key] = value
end

#contextObject



143
144
145
146
# File 'lib/cabin/channel.rb', line 143

def context
  ctx = Cabin::Context.new(self)
  return ctx
end

#publish(data) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/cabin/channel.rb', line 100

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.
  if data.is_a?(String)
    event[:message] = data
  else
    event.merge!(data)
  end

  @outputs.each do |out|
    out << event
  end
end

#remove(key) ⇒ Object



88
89
90
# File 'lib/cabin/channel.rb', line 88

def remove(key)
  @data.delete(key)
end

#subscribe(output) ⇒ Object



64
65
66
67
68
69
70
71
72
# File 'lib/cabin/channel.rb', line 64

def subscribe(output)
  # Wrap ruby stdlib Logger if given.
  if output.is_a?(::Logger)
    output = Cabin::Outputs::StdlibLogger.new(output)
  end
  @outputs << output
  # TODO(sissel): Return a method or object that allows you to easily
  # unsubscribe?
end

#time(data, &block) ⇒ Object



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/cabin/channel.rb', line 122

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