Class: Cosmos::PacketLogReader

Inherits:
Object
  • Object
show all
Defined in:
lib/cosmos/packet_logs/packet_log_reader.rb

Overview

Reads a packet log of either commands or telemetry.

Direct Known Subclasses

CcsdsLogReader

Constant Summary collapse

COSMOS2_MARKER =

COSMOS 2.0 log file header definition

'COSMOS2_'
COSMOS2_HEADER_LENGTH =
128
COSMOS2_MARKER_RANGE =
0..7
COSMOS2_LOG_TYPE_RANGE =
8..10
COSMOS2_CONFIGURATION_NAME_RANGE =
12..43
COSMOS2_HOSTNAME_RANGE =
45..127
COSMOS1_MARKER =

COSMOS 1.0 log file header definition

'COSMOS'
COSMOS1_HEADER_LENGTH =
42
COSMOS1_MARKER_RANGE =
0..5
COSMOS1_LOG_TYPE_RANGE =
6..8
COSMOS1_CONFIGURATION_NAME_RANGE =
10..41

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializePacketLogReader

Create a new log file reader



39
40
41
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 39

def initialize
  reset()
end

Instance Attribute Details

#configuration_nameObject (readonly)

Returns the value of attribute configuration_name.



20
21
22
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 20

def configuration_name
  @configuration_name
end

#hostnameObject (readonly)

Returns the value of attribute hostname.



21
22
23
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 21

def hostname
  @hostname
end

#log_typeObject (readonly)

Returns the value of attribute log_type.



19
20
21
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 19

def log_type
  @log_type
end

Instance Method Details

#bytes_readInteger

Returns The current file position in the log file.

Returns:

  • (Integer)

    The current file position in the log file



215
216
217
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 215

def bytes_read
  @file.pos
end

#closeObject

Closes the current log file



126
127
128
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 126

def close
  @file.close if @file and !@file.closed?
end

#each(filename, identify_and_define = true, start_time = nil, end_time = nil) {|packet| ... } ⇒ Object

Yields back each packet as it is found in the log file.

Parameters:

  • filename (String)

    The log file to read

  • identify_and_define (Boolean) (defaults to: true)

    Once the packet has been read from the log file, whether to both identify the packet by setting the target and packet name, and define the packet by populating all the items.

  • start_time (Time|nil) (defaults to: nil)

    Time at which to start returning packets. Packets found with a timestamp before this time are ignored. Pass nil to return all packets.

  • end_time (Time|nil) (defaults to: nil)

    Time at which to stop returning packets. Packets found with a timestamp after this time are ignored. Pass nil to return all packets.

Yield Parameters:



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 56

def each(filename, identify_and_define = true, start_time = nil, end_time = nil)
  open(filename)

  seek_to_time(start_time) if start_time

  while true
    packet = read(identify_and_define)
    break unless packet

    received_time = packet.received_time
    if received_time
      next if start_time and received_time < start_time
      break if end_time and received_time > end_time
    end

    yield packet
  end
ensure
  close()
end

#firstPacket

Read the first packet from the log file and reset the file position back to the current position. This allows the client to call read multiple times to return packets, call first, and continue calling read which will return the next packet in the file.

Returns:



178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 178

def first
  original_position = @file.pos
  @file.seek(0, IO::SEEK_SET)
  read_file_header()
  packet = read()
  raise "No first packet found" unless packet
  @file.seek(original_position, IO::SEEK_SET)
  packet.clone
rescue => err
  close()
  raise err
end

#lastPacket

Read the last packet from the log file and reset the file position back to the current position. This allows the client to call read multiple times to return packets, call last, and continue calling read which will return the next packet in the file.

Returns:



197
198
199
200
201
202
203
204
205
206
207
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 197

def last
  original_position = @file.pos
  @file.seek(-1, IO::SEEK_END)
  packet = search(-1)
  raise "No last packet found" unless packet
  @file.seek(original_position, IO::SEEK_SET)
  packet.clone
rescue => err
  close()
  raise err
end

#open(filename) ⇒ Boolean, Exception

Returns true if successfully changed to configuration specified in log, otherwise returns false and potentially an Exception class if an error occurred. If no error occurred false indicates that the requested configuration was simply not found

Parameters:

  • filename (String)

    The log filename to open

Returns:

  • (Boolean, Exception)

    Returns true if successfully changed to configuration specified in log, otherwise returns false and potentially an Exception class if an error occurred. If no error occurred false indicates that the requested configuration was simply not found



113
114
115
116
117
118
119
120
121
122
123
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 113

def open(filename)
  close()
  reset()
  @filename = filename
  @file = BufferedFile.open(@filename, 'rb')
  @bytes_read = 0
  return read_file_header()
rescue => err
  close()
  raise err
end

#packet_offsets(filename, progress_callback = nil) ⇒ Array<Array<Integer, Integer, String, String, Time, Time>] Array of arrays for each packet found in the log file consisting of: [File position, length, target name, packet name, time formatted, received time].

Returns an analysis of the log file by reading all the packets and returning information about each packet. This information maps directly to the parameters need by the #read_at_offset method and thus should be called before using #read_at_offset.

Parameters:

  • filename (String)

    The filename to analyze

  • progress_callback (Proc) (defaults to: nil)

    Callback that should receive a single floating point parameter which is the percentage done

Returns:

  • (Array<Array<Integer, Integer, String, String, Time, Time>] Array of arrays for each packet found in the log file consisting of: [File position, length, target name, packet name, time formatted, received time].)

    Array<Array<Integer, Integer, String, String, Time, Time>] Array of arrays for each packet found in the log file consisting of: [File position, length, target name, packet name, time formatted, received time].



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 89

def packet_offsets(filename, progress_callback = nil)
  open(filename)
  offsets = []
  filesize = size().to_f

  while true
    current_pos = @file.pos
    packet = read(false)
    break unless packet
    offsets << current_pos
    if progress_callback
      break if progress_callback.call(current_pos / filesize)
    end
  end

  return offsets
ensure
  close()
end

#read(identify_and_define = true) ⇒ Packet

Read a packet from the log file

Parameters:

  • identify_and_define (Boolean) (defaults to: true)

    Once the packet has been read from the log file, whether to both identify the packet by setting the target and packet name, and define the packet by populating all the items.

Returns:



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 134

def read(identify_and_define = true)
  # Read the Packet Header
  success, target_name, packet_name, received_time = read_entry_header()
  return nil unless success

  # Read Packet Data
  packet_data = @file.read_length_bytes(4)
  return nil unless packet_data and packet_data.length > 0

  if identify_and_define
    packet = identify_and_define_packet_data(target_name, packet_name, received_time, packet_data)
  else
    # Build Packet
    packet = Packet.new(target_name, packet_name, :BIG_ENDIAN, nil, packet_data)
    packet.set_received_time_fast(received_time)
  end

  packet
rescue => err
  close()
  raise err
end

#read_at_offset(file_offset, identify_and_define = true) ⇒ Packet

Reads a packet from the opened log file. Should only be used in conjunction with #packet_offsets.

Parameters:

  • file_offset (Integer)

    Byte offset into the log file to start reading

  • identify_and_define (Boolean) (defaults to: true)

    Once the packet has been read from the log file, whether to both identify the packet by setting the target and packet name, and define the packet by populating all the items.

Returns:



164
165
166
167
168
169
170
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 164

def read_at_offset(file_offset, identify_and_define = true)
  @file.seek(file_offset, IO::SEEK_SET)
  return read(identify_and_define)
rescue => err
  close()
  raise err
end

#sizeInteger

Returns The size of the log file being processed.

Returns:

  • (Integer)

    The size of the log file being processed



210
211
212
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 210

def size
  @file.stat.size
end