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

#cleanup, #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.



26
27
28
29
# File 'lib/openc3/logs/text_log_writer.rb', line 26

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

Instance Method Details

#bucket_filenameObject



59
60
61
62
63
64
65
66
# File 'lib/openc3/logs/text_log_writer.rb', line 59

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



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/openc3/logs/text_log_writer.rb', line 70

def close_file(take_mutex = true)
  @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

    return super(false)
  ensure
    @mutex.unlock if take_mutex
  end
end

#extensionObject



87
88
89
# File 'lib/openc3/logs/text_log_writer.rb', line 87

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



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/openc3/logs/text_log_writer.rb', line 39

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



51
52
53
54
55
56
57
# File 'lib/openc3/logs/text_log_writer.rb', line 51

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