Class: OpenC3::TextLogWriter

Inherits:
LogWriter show all
Defined in:
lib/openc3/logs/text_log_writer.rb

Overview

Creates a text log. Can automatically cycle the log based on an elapsed time period or when the log file reaches a predefined size.

Constant Summary collapse

NEWLINE =
"\n".freeze

Constants inherited from LogWriter

LogWriter::CLEANUP_DELAY, LogWriter::CYCLE_TIME_INTERVAL

Instance Attribute Summary

Attributes inherited from LogWriter

#cleanup_offsets, #cleanup_times, #cycle_hour, #cycle_minute, #cycle_size, #cycle_time, #filename, #logging_enabled, #mutex, #start_time

Instance Method Summary collapse

Methods inherited from LogWriter

#create_unique_filename, #cycle_thread_body, #first_timestamp, #graceful_kill, #last_timestamp, #prepare_write, #shutdown, #start, #start_new_file, #stop

Constructor Details

#initialize(*args) ⇒ TextLogWriter

Returns a new instance of TextLogWriter.



31
32
33
34
# File 'lib/openc3/logs/text_log_writer.rb', line 31

def initialize(*args)
  super(*args)
  @container_name = Socket.gethostname
end

Instance Method Details

#bucket_filenameObject



64
65
66
67
68
69
70
71
# File 'lib/openc3/logs/text_log_writer.rb', line 64

def bucket_filename
  # Put the name of the redis topic in the filename, but remove the scope
  # because we're already in a directory with the scope name
  redis_topic = @last_offsets.keys[0].to_s
  split_index = redis_topic.index("__") + 2
  topic_name = redis_topic[split_index, redis_topic.length - split_index]
  "#{first_timestamp}__#{last_timestamp}__#{topic_name}" + extension
end

#close_file(take_mutex = true) ⇒ Object

Closing a log file isn’t critical so we just log an error Returns threads that moves log to bucket



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/openc3/logs/text_log_writer.rb', line 75

def close_file(take_mutex = true)
  threads = []
  @mutex.lock if take_mutex
  begin
    # Need to write the OFFSET_MARKER for each packet
    @last_offsets.each do |redis_topic, last_offset|
      time = Time.now.utc
      # timestamp iso8601 with 6 decimal places to match the python output format
      data = { time: time.to_nsec_from_epoch, '@timestamp' => time.iso8601(6), level: 'INFO', "microservice_name" => Logger.microservice_name, "container_name" => @container_name, "last_offset" => last_offset, "redis_topic" => redis_topic, "type" => "offset" }
      write_entry(time.to_nsec_from_epoch, data.as_json(allow_nan: true).to_json(allow_nan: true)) if @file
    end

    threads.concat(super(false))

  ensure
    @mutex.unlock if take_mutex
  end
  return threads
end

#extensionObject



95
96
97
# File 'lib/openc3/logs/text_log_writer.rb', line 95

def extension
  '.txt'.freeze
end

#write(time_nsec_since_epoch, data, redis_topic, redis_offset) ⇒ Object

Write to the log file.

If no log file currently exists in the filesystem, a new file will be created.

Parameters:

  • time_nsec_since_epoch (Integer)

    64 bit integer nsecs since EPOCH

  • data (String)

    String of data

  • redis_offset (Integer)

    The offset of this packet in its Redis stream



44
45
46
47
48
49
50
51
52
53
54
# File 'lib/openc3/logs/text_log_writer.rb', line 44

def write(time_nsec_since_epoch, data, redis_topic, redis_offset)
  return if !@logging_enabled

  @mutex.synchronize do
    prepare_write(time_nsec_since_epoch, data.length, redis_topic, redis_offset)
    write_entry(time_nsec_since_epoch, data) if @file
  end
rescue => e
  Logger.instance.error "Error writing #{@filename} : #{e.formatted}"
  OpenC3.handle_critical_exception(e)
end

#write_entry(time_nsec_since_epoch, data) ⇒ Object



56
57
58
59
60
61
62
# File 'lib/openc3/logs/text_log_writer.rb', line 56

def write_entry(time_nsec_since_epoch, data)
  @file.write(data)
  @file.write(NEWLINE)
  @file_size += (data.length + NEWLINE.length)
  @first_time = time_nsec_since_epoch if !@first_time or time_nsec_since_epoch < @first_time
  @last_time = time_nsec_since_epoch if !@last_time or time_nsec_since_epoch > @last_time
end