class Sawmill::Record

A log record.

Log records are sequences of related log entries with a common record ID, beginning with a begin_record and ending with an end_record. Log records therefore can be analyzed as a group, for example to measure the time taken by an aggregate action such as a website request.

Log records must follow a particular protocol:

The only exception to these rules are incomplete log records, in which the final end_record is not present.

Public Class Methods

new(entries_=nil) click to toggle source

Create a log record.

You may optionally pass in an array of log entries to populate the record either partially or completely. If you do, note that Errors::IllegalRecordError may be raised if the log entries do not follow the log record protocol– e.g. if the first entry is not a begin_record, etc.

# File lib/sawmill/record.rb, line 69
def initialize(entries_=nil)
  @started = false
  @complete = false
  @message_count = 0
  @entries = []
  @attributes = {}
  @computations = {}
  if entries_ && entries_.size > 0
    entries_.each do |entry_|
      add_entry(entry_)
    end
  end
end

Public Instance Methods

add_entry(entry_) click to toggle source

Append a log entry to this record.

Entries must be added in order. Raises Errors::IllegalRecordError if the log record protocol is violated

# File lib/sawmill/record.rb, line 108
def add_entry(entry_)
  empty_ = @entries.size == 0
  if entry_.type == :unknown_data
    raise Errors::IllegalRecordError, "You cannot add an unknown_data entry to a record"
  end
  if empty_ && entry_.type != :begin_record
    raise Errors::IllegalRecordError, "First entry in a record must be a begin_record"
  elsif !empty_ && entry_.type == :begin_record
    raise Errors::IllegalRecordError, "Extra begin_record found"
  end
  if @complete
    raise Errors::IllegalRecordError, "Cannot have entries after end_record"
  end
  if empty_
    if entry_.record_id.nil?
      raise Errors::IllegalRecordError, "Entry has no record_id"
    end
  else
    last_ = @entries.last
    if last_.record_id != entry_.record_id
      raise Errors::IllegalRecordError, "Entry has a mismatching record_id"
    end
    if last_.timestamp > entry_.timestamp
      raise Errors::IllegalRecordError, "Entry's timestamp is earlier than the previous entry"
    end
  end
  case entry_.type
  when :begin_record
    @started = true
  when :end_record
    @complete = true
  when :attribute
    case entry_.operation
    when :set
      @attributes[entry_.key] = entry_.value
    when :append
      val_ = @attributes[entry_.key]
      case val_
      when ::Array
        val_ << entry_.value
      when ::String
        @attributes[entry_.key] = [val_, entry_.value]
      when nil
        @attributes[entry_.key] = [entry_.value]
      end
    end
  when :message
    @message_count += 1
  end
  @entries << entry_
end
all_entries() click to toggle source

Returns an array of all log entries.

# File lib/sawmill/record.rb, line 234
def all_entries
  @entries.dup
end
all_messages() click to toggle source

Returns an array of all log message entries.

# File lib/sawmill/record.rb, line 241
def all_messages
  @entries.find_all{ |entry_| entry_.type == :message }
end
attribute(key_) click to toggle source

Get the value of the given attribute. Returns a string if the attribute has a single value. Returns an array of strings if the attribute has multiple values. Returns nil if the attribute is not set.

# File lib/sawmill/record.rb, line 251
def attribute(key_)
  @attributes[key_.to_s]
end
attribute_keys() click to toggle source

Get an array of attribute keys present in this log record.

# File lib/sawmill/record.rb, line 258
def attribute_keys
  @attributes.keys
end
begin_timestamp() click to toggle source

Returns the beginning timestamp as a Time object, if the log record has been started, or nil otherwise.

# File lib/sawmill/record.rb, line 185
def begin_timestamp
  @started ? @entries.first.timestamp : nil
end
complete?() click to toggle source

Returns true if the final end_record has been added.

# File lib/sawmill/record.rb, line 170
def complete?
  @complete
end
compute(key_) { |self| ... } click to toggle source

Compute and cache a value. This is a convenient way for RecordProcessor objects to share computed information about a record.

Returns the computed value with the given key. If the given key has not been computed yet, computes it by calling the given block and passing self.

# File lib/sawmill/record.rb, line 271
def compute(key_)
  @computations[key_] ||= yield self
end
each_entry(&block_) click to toggle source

Iterate over all log entries, passing each to the given block.

# File lib/sawmill/record.rb, line 216
def each_entry(&block_)
  @entries.each(&block_)
end
each_message() { |entry_| ... } click to toggle source

Iterate over all log message entries, passing each to the given block.

# File lib/sawmill/record.rb, line 223
def each_message
  @entries.each do |entry_|
    if entry_.type == :message
      yield entry_
    end
  end
end
end_timestamp() click to toggle source

Returns the ending timestamp as a Time object, if the log record has been completed, or nil otherwise.

# File lib/sawmill/record.rb, line 193
def end_timestamp
  @complete ? @entries.last.timestamp : nil
end
entry_count() click to toggle source

Returns the number of log entries currently in this record.

# File lib/sawmill/record.rb, line 200
def entry_count
  @entries.size
end
Also aliased as: size
message_count() click to toggle source

Returns the number of message entries currently in this record.

# File lib/sawmill/record.rb, line 209
def message_count
  @message_count
end
record_id() click to toggle source

Returns the record ID as a string.

# File lib/sawmill/record.rb, line 177
def record_id
  @entries.size > 0 ? @entries.first.record_id : nil
end
size() click to toggle source
Alias for: entry_count
started?() click to toggle source

Returns true if the initial begin_record has been added.

# File lib/sawmill/record.rb, line 163
def started?
  @started
end