Class: Cosmos::PacketLogWriter

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

Overview

Creates a packet log of either commands or telemetry. Can automatically cycle the log based on an elasped time period or when the log file reaches a predefined size.

Direct Known Subclasses

MetaPacketLogWriter

Constant Summary collapse

LOG_TYPES =

The allowable log types

[:CMD, :TLM]
CYCLE_TIME_INTERVAL =

The cycle time interval. Cycle times are only checked at this level of granularity.

2

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(log_type, log_name = nil, logging_enabled = true, cycle_time = nil, cycle_size = 2000000000, log_directory = nil, asynchronous = false) ⇒ PacketLogWriter

Returns a new instance of PacketLogWriter.

Parameters:

  • log_type (Symbol)

    The type of packet log to create. Must be :CMD or :TLM.

  • log_name (String|nil) (defaults to: nil)

    Identifier to put in the log file name. This will be prepended with a date / time stamp and appended by the log_type. Thus passing 'test' for a :CMD log will result in a filename of 'YYYY_MM_DD_HH_MM_SS_testcmd.bin'. Pass nil to ignore this parameter.

  • 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 but is better used independently.

  • cycle_size (Integer) (defaults to: 2000000000)

    The size in bytes before creating a new log file. This can be combined with cycle_time but is better used independently.

  • log_directory (String) (defaults to: nil)

    The directory to store the log files. Passing nil will use the system default 'LOGS' directory.

  • asynchronous (Boolean) (defaults to: false)

    Whether to spawn a new thread to write packets to the log rather than writing the packets in the current thread context. Note that this is (alot) slower overall but may reduce interface receive latency



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/cosmos/packet_logs/packet_log_writer.rb', line 58

def initialize(
  log_type,
  log_name = nil,
  logging_enabled = true,
  cycle_time = nil,
  cycle_size = 2000000000,
  log_directory = nil,
  asynchronous = false
)
  raise "log_type must be :CMD or :TLM" unless LOG_TYPES.include? log_type
  @log_type = log_type
  if ConfigParser.handle_nil(log_name)
    @log_name = (log_name.to_s + @log_type.to_s.downcase).freeze
  else
    @log_name = @log_type.to_s.downcase.freeze
  end
  @logging_enabled = ConfigParser.handle_true_false(logging_enabled)
  @cycle_time = ConfigParser.handle_nil(cycle_time)
  @cycle_time = Integer(@cycle_time) if @cycle_time
  @cycle_size = ConfigParser.handle_nil(cycle_size)
  @cycle_size = Integer(@cycle_size) if @cycle_size
  if ConfigParser.handle_nil(log_directory)
    @log_directory = log_directory
  else
    @log_directory = System.instance.paths['LOGS']
  end
  @asynchronous = ConfigParser.handle_true_false(asynchronous)
  @queue = Queue.new
  @mutex = Mutex.new
  @file = nil
  @file_size = 0
  @filename = nil
  @label = nil
  @entry_header = String.new
  @start_time = Time.now

  @cancel_threads = false
  @logging_thread = nil
  if @asynchronous
    @logging_thread = Cosmos.safe_thread("Packet log") do
      logging_thread_body()
    end
  end

  @cycle_thread = nil
  if @cycle_time
    @cycle_sleeper = Sleeper.new
    @cycle_thread = Cosmos.safe_thread("Packet log cycle") do
      cycle_thread_body()
    end
  end
end

Instance Attribute Details

#filenameString (readonly)

Returns The filename of the packet log.

Returns:

  • (String)

    The filename of the packet log



23
24
25
# File 'lib/cosmos/packet_logs/packet_log_writer.rb', line 23

def filename
  @filename
end

#logging_enabledtrue/false (readonly)

Returns Whether logging is enabled.

Returns:

  • (true/false)

    Whether logging is enabled



26
27
28
# File 'lib/cosmos/packet_logs/packet_log_writer.rb', line 26

def logging_enabled
  @logging_enabled
end

#queueQueue (readonly)

Returns Queue for asynchronous logging.

Returns:

  • (Queue)

    Queue for asynchronous logging



29
30
31
# File 'lib/cosmos/packet_logs/packet_log_writer.rb', line 29

def queue
  @queue
end

Instance Method Details

#graceful_killObject



166
167
168
169
# File 'lib/cosmos/packet_logs/packet_log_writer.rb', line 166

def graceful_kill
  @cancel_threads = true
  @queue << nil
end

#shutdownObject

Stop all logging, close the current log file, and kill the logging threads.



156
157
158
159
160
161
162
163
164
# File 'lib/cosmos/packet_logs/packet_log_writer.rb', line 156

def shutdown
  stop()
  if @cycle_thread
    @cycle_sleeper.cancel
    Cosmos.kill_thread(self, @cycle_thread)
    @cycle_thread = nil
  end
  Cosmos.kill_thread(self, @logging_thread)
end

#start(label = nil) ⇒ Object

Starts a new log file by closing the existing log file. New log files are not created until packets are written by #write so this does not immediately create a log file on the filesystem.

Parameters:

  • label (String) (defaults to: nil)

    Label to append to the logfile name. This label will be placed after the cmd or tlm in the filename. For example, if 'test' is given to a command log file, the filename will be 'YYYY_MM_DD_HH_MM_SS_cmd_test.bin'.



136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/cosmos/packet_logs/packet_log_writer.rb', line 136

def start(label = nil)
  new_label = label.to_s.strip
  if new_label.length == 0
    @label = nil
  elsif new_label =~ /^[a-zA-Z0-9]*$/
    @label = new_label
  else
    # Invalid label - Clear out existing
    @label = nil
  end

  @mutex.synchronize { close_file(false); @logging_enabled = true }
end

#stopObject

Stops all logging and closes the current log file.



151
152
153
# File 'lib/cosmos/packet_logs/packet_log_writer.rb', line 151

def stop
  @mutex.synchronize { @logging_enabled = false; close_file(false) }
end

#write(packet) ⇒ Object

Write a packet to the log file. If the log file was created with asynchronous = true the packet will be put on a queue and written by the log writer thread. Otherwise the packet will be written in the caller’s thread context.

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

Parameters:

  • packet (Packet)

    The packet to write to the log file



120
121
122
123
124
125
126
# File 'lib/cosmos/packet_logs/packet_log_writer.rb', line 120

def write(packet)
  if @asynchronous
    @queue << packet.clone
  else
    write_packet(packet)
  end
end