class FileSeries

FileSeries rubocop loves comments

Constants

DEFAULT_DIR
DEFAULT_FREQ
DEFAULT_PREFIX
DEFAULT_SEPARATOR
VERSION

Attributes

current_ts[RW]
dir[RW]
file[RW]
separator[RW]

Public Class Methods

new(options = {}) click to toggle source
# File lib/file_series.rb, line 33
def initialize(options = {})
  @dir = options[:dir] || DEFAULT_DIR
  @file = nil
  @current_ts = nil
  @filename_prefix = options[:prefix] || DEFAULT_PREFIX
  @rotate_freq = options[:rotate_every] || DEFAULT_FREQ #seconds
  @binary_mode = options[:binary]
  @separator = options[:separator] || DEFAULT_SEPARATOR
  @sync = options[:sync] || false
end
parse_filename(filename) click to toggle source

extract the parts of a filename

# File lib/file_series.rb, line 87
def self.parse_filename(filename)
  base = File.basename(filename, '.log')
  prefix, date, time, duration = base.split('-')
  {
    prefix: prefix,
    start_time: Time.parse("#{date} #{time}").utc,
    duration: duration.to_i
  }
end

Public Instance Methods

complete_files() click to toggle source

get all files which match our pattern which are not current. (safe for consumption. no longer being written to.)

# File lib/file_series.rb, line 107
def complete_files
  current_file = filename

  Dir.glob(
    File.join(@dir, "#{@filename_prefix}-*-#{@rotate_freq}.log")
  ).select do |name|
    name != current_file
  end
end
each() { |raw| ... } click to toggle source

enumerate over all the writes in a series, across all files.

# File lib/file_series.rb, line 118
def each
  complete_files.sort.each do |file|
    File.open(file, "r#{'b' if @binary_mode}").each_line(@separator) do |raw|
      yield raw
    end
  end
end
filename(ts = nil) click to toggle source

return a string filename for the logfile for the supplied timestamp. defaults to current time period.

changes to filename structure must be matched by changes to parse_filename

# File lib/file_series.rb, line 81
def filename(ts = nil)
  ts ||= this_period
  File.join(@dir, "#{@filename_prefix}-#{Time.at(ts).utc.strftime('%Y%m%d-%H%M%SZ')}-#{@rotate_freq}.log")
end
log_file() click to toggle source

return a File object for the current log file.

# File lib/file_series.rb, line 50
def log_file
  ts = this_period

  # if we're in a new time period, start writing to new file.
  if (! file) || (ts != current_ts)
    rotate(ts)
  end

  file
end
parse_filename(filename) click to toggle source
# File lib/file_series.rb, line 97
def parse_filename(filename)
  self.class.parse_filename(filename)
end
path() click to toggle source
# File lib/file_series.rb, line 101
def path
  filename
end
rotate(ts = nil) click to toggle source

close current file handle and open a new one for a new logging period. ts defaults to the current time period.

# File lib/file_series.rb, line 69
def rotate(ts = nil)
  ts ||= this_period
  @file.close if @file
  @file = File.open(filename(ts), "a#{'b' if @binary_mode}")
  @file.sync = @sync
  @current_ts = ts
end
this_period() click to toggle source

compute the current time period.

# File lib/file_series.rb, line 62
def this_period
  t = Time.now.to_i
  t - (t % @rotate_freq)
end
write(message) click to toggle source

write something to the current log file.

# File lib/file_series.rb, line 45
def write(message)
  log_file.write(message.to_s + @separator)
end