Class: OpenC3::BufferedPacketLogWriter

Inherits:
PacketLogWriter show all
Defined in:
lib/openc3/logs/buffered_packet_log_writer.rb

Overview

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

Constant Summary

Constants included from PacketLogConstants

PacketLogConstants::COSMOS2_FILE_HEADER, PacketLogConstants::COSMOS4_FILE_HEADER, PacketLogConstants::OPENC3_CBOR_FLAG_MASK, PacketLogConstants::OPENC3_CMD_FLAG_MASK, PacketLogConstants::OPENC3_ENTRY_TYPE_MASK, PacketLogConstants::OPENC3_EXTRA_FLAG_MASK, PacketLogConstants::OPENC3_EXTRA_LENGTH_FIXED_SIZE, PacketLogConstants::OPENC3_EXTRA_LENGTH_PACK_DIRECTIVE, PacketLogConstants::OPENC3_EXTRA_LENGTH_PACK_ITEMS, PacketLogConstants::OPENC3_FILE_HEADER, PacketLogConstants::OPENC3_HEADER_LENGTH, PacketLogConstants::OPENC3_ID_FIXED_SIZE, PacketLogConstants::OPENC3_ID_FLAG_MASK, PacketLogConstants::OPENC3_INDEX_HEADER, PacketLogConstants::OPENC3_JSON_PACKET_ENTRY_TYPE_MASK, PacketLogConstants::OPENC3_KEY_MAP_ENTRY_TYPE_MASK, PacketLogConstants::OPENC3_KEY_MAP_PACK_DIRECTIVE, PacketLogConstants::OPENC3_KEY_MAP_PACK_ITEMS, PacketLogConstants::OPENC3_KEY_MAP_SECONDARY_FIXED_SIZE, PacketLogConstants::OPENC3_MAX_PACKET_INDEX, PacketLogConstants::OPENC3_MAX_TARGET_INDEX, PacketLogConstants::OPENC3_OFFSET_MARKER_ENTRY_TYPE_MASK, PacketLogConstants::OPENC3_OFFSET_MARKER_PACK_DIRECTIVE, PacketLogConstants::OPENC3_OFFSET_MARKER_PACK_ITEMS, PacketLogConstants::OPENC3_OFFSET_MARKER_SECONDARY_FIXED_SIZE, PacketLogConstants::OPENC3_PACKET_DECLARATION_ENTRY_TYPE_MASK, PacketLogConstants::OPENC3_PACKET_DECLARATION_PACK_DIRECTIVE, PacketLogConstants::OPENC3_PACKET_DECLARATION_PACK_ITEMS, PacketLogConstants::OPENC3_PACKET_DECLARATION_SECONDARY_FIXED_SIZE, PacketLogConstants::OPENC3_PACKET_PACK_DIRECTIVE, PacketLogConstants::OPENC3_PACKET_PACK_ITEMS, PacketLogConstants::OPENC3_PACKET_SECONDARY_FIXED_SIZE, PacketLogConstants::OPENC3_PRIMARY_FIXED_SIZE, PacketLogConstants::OPENC3_RAW_PACKET_ENTRY_TYPE_MASK, PacketLogConstants::OPENC3_RECEIVED_TIME_FIXED_SIZE, PacketLogConstants::OPENC3_RECEIVED_TIME_FLAG_MASK, PacketLogConstants::OPENC3_RECEIVED_TIME_PACK_DIRECTIVE, PacketLogConstants::OPENC3_RECEIVED_TIME_PACK_ITEMS, PacketLogConstants::OPENC3_STORED_FLAG_MASK, PacketLogConstants::OPENC3_TARGET_DECLARATION_ENTRY_TYPE_MASK, PacketLogConstants::OPENC3_TARGET_DECLARATION_PACK_DIRECTIVE, PacketLogConstants::OPENC3_TARGET_DECLARATION_PACK_ITEMS, PacketLogConstants::OPENC3_TARGET_DECLARATION_SECONDARY_FIXED_SIZE

Constants inherited from LogWriter

LogWriter::CLEANUP_DELAY, LogWriter::CYCLE_TIME_INTERVAL

Instance Attribute Summary

Attributes inherited from PacketLogWriter

#data_format

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 PacketLogWriter

#bucket_filename, #extension, #get_packet_index, #start_new_file, #write, #write_entry

Methods inherited from LogWriter

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

Constructor Details

#initialize(remote_log_directory, label, logging_enabled = true, cycle_time = nil, cycle_size = 1_000_000_000, cycle_hour = nil, cycle_minute = nil, enforce_time_order = true, buffer_depth = 60, scope: $openc3_scope) ⇒ BufferedPacketLogWriter

Returns a new instance of BufferedPacketLogWriter.

Parameters:

  • remote_log_directory (String)

    The path to store the log files

  • label (String)

    Label to apply to the log filename

  • logging_enabled (Boolean) (defaults to: true)

    Whether to start with logging enabled

  • cycle_time (Integer) (defaults to: nil)

    The amount of time in seconds before creating a new log file. This can be combined with cycle_size.

  • cycle_size (Integer) (defaults to: 1_000_000_000)

    The size in bytes before creating a new log file. This can be combined with cycle_time.

  • cycle_hour (Integer) (defaults to: nil)

    The time at which to cycle the log. Combined with cycle_minute to cycle the log daily at the specified time. If nil, the log will be cycled hourly at the specified cycle_minute.

  • cycle_minute (Integer) (defaults to: nil)

    The time at which to cycle the log. See cycle_hour for more information.

  • buffer_depth (Integer) (defaults to: 60)

    Number of packets to buffer before writing to file



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/openc3/logs/buffered_packet_log_writer.rb', line 38

def initialize(
  remote_log_directory,
  label,
  logging_enabled = true,
  cycle_time = nil,
  cycle_size = 1_000_000_000,
  cycle_hour = nil,
  cycle_minute = nil,
  enforce_time_order = true,
  buffer_depth = 60, # Default assumes 1 minute of 1Hz data
  scope: $openc3_scope
)
  super(
    remote_log_directory,
    label,
    logging_enabled,
    cycle_time,
    cycle_size,
    cycle_hour,
    cycle_minute,
    enforce_time_order,
    scope: scope
  )
  @buffer_depth = Integer(buffer_depth)
  @buffer = []
end

Instance Method Details

#buffered_first_time_nsecObject



99
100
101
102
103
# File 'lib/openc3/logs/buffered_packet_log_writer.rb', line 99

def buffered_first_time_nsec
  return @first_time if @first_time
  return @buffer[0][4] if @buffer[0]
  return nil
end

#buffered_write(entry_type, cmd_or_tlm, target_name, packet_name, time_nsec_since_epoch, stored, data, id = nil, redis_topic = nil, redis_offset = '0-0', received_time_nsec_since_epoch: nil, extra: nil) ⇒ Object

Write a packet to the log file.

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

Parameters:

  • entry_type (Symbol)

    Type of entry to write. Must be one of :TARGET_DECLARATION, :PACKET_DECLARATION, :RAW_PACKET, :JSON_PACKET, :OFFSET_MARKER, :KEY_MAP

  • cmd_or_tlm (Symbol)

    One of :CMD or :TLM

  • target_name (String)

    Name of the target

  • packet_name (String)

    Name of the packet

  • time_nsec_since_epoch (Integer)

    64 bit integer nsecs since EPOCH

  • stored (Boolean)

    Whether this data is stored telemetry

  • data (String)

    Binary string of data

  • id (Integer) (defaults to: nil)

    Target ID

  • redis_offset (Integer) (defaults to: '0-0')

    The offset of this packet in its Redis stream



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/openc3/logs/buffered_packet_log_writer.rb', line 80

def buffered_write(entry_type, cmd_or_tlm, target_name, packet_name, time_nsec_since_epoch, stored, data, id = nil, redis_topic = nil, redis_offset = '0-0', received_time_nsec_since_epoch: nil, extra: nil)
  case entry_type
  when :RAW_PACKET, :JSON_PACKET
    # If we have data in the buffer, a file should always be open so that cycle time logic will run
    unless @file
      @mutex.synchronize { start_new_file() }
    end

    @buffer << [entry_type, cmd_or_tlm, target_name, packet_name, time_nsec_since_epoch, stored, data, id, redis_topic, redis_offset, received_time_nsec_since_epoch, extra]
    @buffer.sort! {|entry1, entry2| entry1[4] <=> entry2[4] }
    if @buffer.length >= @buffer_depth
      entry = @buffer.shift
      write(*entry[0..-3], received_time_nsec_since_epoch: entry[-2], extra: entry[-1])
    end
  else
    write(entry_type, cmd_or_tlm, target_name, packet_name, time_nsec_since_epoch, stored, data, id, redis_topic, redis_offset, received_time_nsec_since_epoch: received_time_nsec_since_epoch, extra: extra)
  end
end

#close_file(take_mutex = true) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/openc3/logs/buffered_packet_log_writer.rb', line 105

def close_file(take_mutex = true)
  @mutex.lock if take_mutex
  begin
    # Need to write out the buffer before closing out the file
    if @buffer.length > 0
      start_new_file() unless @file
      write_buffer()
    end
    return super(false) # Someone has already taken mutex here
  ensure
    @mutex.unlock if take_mutex
  end
end

#write_bufferObject

Mutex is already taken when this is called so we need to adjust prepare_write and write accordingly



121
122
123
124
125
126
127
128
129
130
# File 'lib/openc3/logs/buffered_packet_log_writer.rb', line 121

def write_buffer
  begin
    @buffer.each do |entry|
      write(*entry[0..-3], allow_new_file: false, take_mutex: false, received_time_nsec_since_epoch: entry[-2], extra: entry[-1])
    end
  rescue => e
    Logger.instance.error "Error writing out buffer : #{e.formatted}"
  end
  @buffer = []
end