openc3 5.0.11 → 5.1.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of openc3 might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Guardfile +3 -0
- data/LICENSE.txt +7 -5
- data/README.md +11 -9
- data/Rakefile +3 -0
- data/bin/cstol_converter +3 -0
- data/bin/openc3cli +29 -18
- data/bin/rubysloc +3 -0
- data/data/config/screen.yaml +10 -2
- data/data/config/target.yaml +1 -1
- data/data/config/widgets.yaml +6 -6
- data/ext/mkrf_conf.rb +3 -0
- data/ext/openc3/ext/array/array.c +3 -0
- data/ext/openc3/ext/buffered_file/buffered_file.c +3 -0
- data/ext/openc3/ext/config_parser/config_parser.c +3 -0
- data/ext/openc3/ext/crc/crc.c +3 -0
- data/ext/openc3/ext/openc3_io/openc3_io.c +3 -0
- data/ext/openc3/ext/packet/packet.c +3 -0
- data/ext/openc3/ext/platform/platform.c +3 -0
- data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +3 -0
- data/ext/openc3/ext/string/string.c +3 -0
- data/ext/openc3/ext/structure/structure.c +3 -0
- data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +3 -0
- data/ext/openc3/ext/telemetry/telemetry.c +3 -0
- data/lib/cosmos.rb +3 -0
- data/lib/cosmosc2.rb +3 -0
- data/lib/openc3/accessors/accessor.rb +3 -0
- data/lib/openc3/accessors/binary_accessor.rb +3 -0
- data/lib/openc3/accessors/cbor_accessor.rb +3 -0
- data/lib/openc3/accessors/html_accessor.rb +3 -0
- data/lib/openc3/accessors/json_accessor.rb +4 -1
- data/lib/openc3/accessors/xml_accessor.rb +3 -0
- data/lib/openc3/accessors.rb +3 -0
- data/lib/openc3/api/api.rb +3 -0
- data/lib/openc3/api/authorized_api.rb +3 -0
- data/lib/openc3/api/cmd_api.rb +6 -3
- data/lib/openc3/api/config_api.rb +3 -0
- data/lib/openc3/api/interface_api.rb +6 -2
- data/lib/openc3/api/limits_api.rb +54 -61
- data/lib/openc3/api/router_api.rb +6 -3
- data/lib/openc3/api/settings_api.rb +3 -0
- data/lib/openc3/api/target_api.rb +3 -0
- data/lib/openc3/api/tlm_api.rb +27 -32
- data/lib/openc3/bridge/bridge.rb +3 -0
- data/lib/openc3/bridge/bridge_config.rb +3 -0
- data/lib/openc3/bridge/bridge_interface_thread.rb +3 -0
- data/lib/openc3/bridge/bridge_router_thread.rb +3 -0
- data/lib/openc3/ccsds/ccsds_packet.rb +3 -0
- data/lib/openc3/ccsds/ccsds_parser.rb +3 -0
- data/lib/openc3/config/config_parser.rb +3 -0
- data/lib/openc3/config/meta_config_parser.rb +3 -0
- data/lib/openc3/conversions/conversion.rb +3 -0
- data/lib/openc3/conversions/generic_conversion.rb +3 -0
- data/lib/openc3/conversions/packet_time_formatted_conversion.rb +3 -0
- data/lib/openc3/conversions/packet_time_seconds_conversion.rb +3 -0
- data/lib/openc3/conversions/polynomial_conversion.rb +3 -0
- data/lib/openc3/conversions/processor_conversion.rb +3 -0
- data/lib/openc3/conversions/received_count_conversion.rb +3 -0
- data/lib/openc3/conversions/received_time_formatted_conversion.rb +3 -0
- data/lib/openc3/conversions/received_time_seconds_conversion.rb +3 -0
- data/lib/openc3/conversions/segmented_polynomial_conversion.rb +3 -0
- data/lib/openc3/conversions/unix_time_conversion.rb +3 -0
- data/lib/openc3/conversions/unix_time_formatted_conversion.rb +3 -0
- data/lib/openc3/conversions/unix_time_seconds_conversion.rb +3 -0
- data/lib/openc3/conversions.rb +3 -0
- data/lib/openc3/core_ext/array.rb +3 -0
- data/lib/openc3/core_ext/binding.rb +3 -0
- data/lib/openc3/core_ext/class.rb +3 -0
- data/lib/openc3/core_ext/exception.rb +3 -0
- data/lib/openc3/core_ext/file.rb +3 -0
- data/lib/openc3/core_ext/hash.rb +3 -0
- data/lib/openc3/core_ext/io.rb +3 -0
- data/lib/openc3/core_ext/kernel.rb +3 -0
- data/lib/openc3/core_ext/math.rb +3 -0
- data/lib/openc3/core_ext/matrix.rb +3 -0
- data/lib/openc3/core_ext/objectspace.rb +3 -0
- data/lib/openc3/core_ext/openc3_io.rb +3 -0
- data/lib/openc3/core_ext/range.rb +3 -0
- data/lib/openc3/core_ext/socket.rb +3 -0
- data/lib/openc3/core_ext/string.rb +3 -0
- data/lib/openc3/core_ext/stringio.rb +3 -0
- data/lib/openc3/core_ext/tempfile.rb +3 -0
- data/lib/openc3/core_ext/time.rb +3 -0
- data/lib/openc3/core_ext.rb +3 -0
- data/lib/openc3/interfaces/interface.rb +3 -0
- data/lib/openc3/interfaces/linc_interface.rb +3 -0
- data/lib/openc3/interfaces/protocols/burst_protocol.rb +3 -0
- data/lib/openc3/interfaces/protocols/crc_protocol.rb +3 -0
- data/lib/openc3/interfaces/protocols/fixed_protocol.rb +3 -0
- data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +3 -0
- data/lib/openc3/interfaces/protocols/length_protocol.rb +3 -0
- data/lib/openc3/interfaces/protocols/override_protocol.rb +3 -0
- data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +3 -0
- data/lib/openc3/interfaces/protocols/protocol.rb +3 -0
- data/lib/openc3/interfaces/protocols/template_protocol.rb +3 -0
- data/lib/openc3/interfaces/protocols/terminated_protocol.rb +3 -0
- data/lib/openc3/interfaces/serial_interface.rb +3 -0
- data/lib/openc3/interfaces/simulated_target_interface.rb +3 -0
- data/lib/openc3/interfaces/stream_interface.rb +3 -0
- data/lib/openc3/interfaces/tcpip_client_interface.rb +3 -0
- data/lib/openc3/interfaces/tcpip_server_interface.rb +3 -0
- data/lib/openc3/interfaces/udp_interface.rb +3 -0
- data/lib/openc3/interfaces.rb +3 -0
- data/lib/openc3/io/buffered_file.rb +3 -0
- data/lib/openc3/io/io_multiplexer.rb +8 -0
- data/lib/openc3/io/json_api_object.rb +5 -2
- data/lib/openc3/io/json_drb.rb +3 -0
- data/lib/openc3/io/json_drb_object.rb +5 -2
- data/lib/openc3/io/json_drb_rack.rb +3 -0
- data/lib/openc3/io/json_rpc.rb +8 -3
- data/lib/openc3/io/openc3_snmp.rb +3 -0
- data/lib/openc3/io/posix_serial_driver.rb +3 -0
- data/lib/openc3/io/raw_logger.rb +3 -0
- data/lib/openc3/io/raw_logger_pair.rb +3 -0
- data/lib/openc3/io/serial_driver.rb +3 -0
- data/lib/openc3/io/stderr.rb +3 -0
- data/lib/openc3/io/stdout.rb +3 -0
- data/lib/openc3/io/udp_sockets.rb +3 -0
- data/lib/openc3/io/win32_serial_driver.rb +3 -0
- data/lib/openc3/logs/buffered_packet_log_reader.rb +65 -0
- data/lib/openc3/logs/buffered_packet_log_writer.rb +120 -0
- data/lib/openc3/logs/log_writer.rb +95 -40
- data/lib/openc3/logs/packet_log_constants.rb +9 -0
- data/lib/openc3/logs/packet_log_reader.rb +34 -3
- data/lib/openc3/logs/packet_log_writer.rb +85 -18
- data/lib/openc3/logs/text_log_writer.rb +9 -5
- data/lib/openc3/logs.rb +8 -2
- data/lib/openc3/microservices/cleanup_microservice.rb +18 -18
- data/lib/openc3/microservices/decom_microservice.rb +30 -24
- data/lib/openc3/microservices/interface_microservice.rb +136 -91
- data/lib/openc3/microservices/log_microservice.rb +35 -13
- data/lib/openc3/microservices/microservice.rb +16 -14
- data/lib/openc3/microservices/plugin_microservice.rb +3 -1
- data/lib/openc3/microservices/reaction_microservice.rb +4 -1
- data/lib/openc3/microservices/reducer_microservice.rb +332 -149
- data/lib/openc3/microservices/router_microservice.rb +3 -0
- data/lib/openc3/microservices/text_log_microservice.rb +22 -7
- data/lib/openc3/microservices/timeline_microservice.rb +4 -1
- data/lib/openc3/microservices/trigger_group_microservice.rb +3 -0
- data/lib/openc3/models/activity_model.rb +3 -0
- data/lib/openc3/models/auth_model.rb +3 -0
- data/lib/openc3/models/cvt_model.rb +14 -5
- data/lib/openc3/models/environment_model.rb +3 -0
- data/lib/openc3/models/gem_model.rb +30 -51
- data/lib/openc3/models/info_model.rb +3 -0
- data/lib/openc3/models/interface_model.rb +3 -0
- data/lib/openc3/models/interface_status_model.rb +4 -1
- data/lib/openc3/models/metadata_model.rb +3 -0
- data/lib/openc3/models/metric_model.rb +3 -0
- data/lib/openc3/models/microservice_model.rb +9 -6
- data/lib/openc3/models/microservice_status_model.rb +4 -1
- data/lib/openc3/models/model.rb +3 -0
- data/lib/openc3/models/note_model.rb +3 -0
- data/lib/openc3/models/notification_model.rb +3 -0
- data/lib/openc3/models/ping_model.rb +3 -0
- data/lib/openc3/models/plugin_model.rb +20 -14
- data/lib/openc3/models/process_status_model.rb +4 -1
- data/lib/openc3/models/reaction_model.rb +3 -0
- data/lib/openc3/models/reducer_model.rb +31 -24
- data/lib/openc3/models/router_model.rb +3 -0
- data/lib/openc3/models/router_status_model.rb +3 -0
- data/lib/openc3/models/scope_model.rb +3 -4
- data/lib/openc3/models/settings_model.rb +3 -0
- data/lib/openc3/models/sorted_model.rb +3 -0
- data/lib/openc3/models/target_model.rb +61 -94
- data/lib/openc3/models/timeline_model.rb +4 -1
- data/lib/openc3/models/tool_config_model.rb +3 -0
- data/lib/openc3/models/tool_model.rb +11 -9
- data/lib/openc3/models/trigger_group_model.rb +3 -0
- data/lib/openc3/models/trigger_model.rb +3 -0
- data/lib/openc3/models/widget_model.rb +18 -11
- data/lib/openc3/operators/microservice_operator.rb +3 -0
- data/lib/openc3/operators/operator.rb +105 -34
- data/lib/openc3/packets/commands.rb +3 -0
- data/lib/openc3/packets/json_packet.rb +87 -14
- data/lib/openc3/packets/limits.rb +4 -1
- data/lib/openc3/packets/limits_response.rb +3 -0
- data/lib/openc3/packets/packet.rb +5 -1
- data/lib/openc3/packets/packet_config.rb +3 -0
- data/lib/openc3/packets/packet_item.rb +9 -3
- data/lib/openc3/packets/packet_item_limits.rb +3 -0
- data/lib/openc3/packets/parsers/format_string_parser.rb +3 -0
- data/lib/openc3/packets/parsers/limits_parser.rb +3 -0
- data/lib/openc3/packets/parsers/limits_response_parser.rb +3 -0
- data/lib/openc3/packets/parsers/packet_item_parser.rb +3 -0
- data/lib/openc3/packets/parsers/packet_parser.rb +3 -0
- data/lib/openc3/packets/parsers/processor_parser.rb +3 -0
- data/lib/openc3/packets/parsers/state_parser.rb +3 -0
- data/lib/openc3/packets/parsers/xtce_converter.rb +3 -0
- data/lib/openc3/packets/parsers/xtce_parser.rb +3 -0
- data/lib/openc3/packets/structure.rb +3 -0
- data/lib/openc3/packets/structure_item.rb +3 -0
- data/lib/openc3/packets/telemetry.rb +3 -0
- data/lib/openc3/processors/processor.rb +3 -0
- data/lib/openc3/processors/statistics_processor.rb +3 -0
- data/lib/openc3/processors/watermark_processor.rb +3 -0
- data/lib/openc3/processors.rb +3 -0
- data/lib/openc3/script/api_shared.rb +35 -6
- data/lib/openc3/script/calendar.rb +3 -0
- data/lib/openc3/script/commands.rb +3 -0
- data/lib/openc3/script/exceptions.rb +3 -0
- data/lib/openc3/script/extract.rb +3 -0
- data/lib/openc3/script/limits.rb +3 -24
- data/lib/openc3/script/script.rb +11 -7
- data/lib/openc3/script/script_runner.rb +3 -0
- data/lib/openc3/script/storage.rb +33 -16
- data/lib/openc3/script/suite.rb +3 -0
- data/lib/openc3/script/suite_results.rb +3 -0
- data/lib/openc3/script/suite_runner.rb +3 -0
- data/lib/openc3/script/telemetry.rb +43 -0
- data/lib/openc3/script.rb +3 -0
- data/lib/openc3/streams/serial_stream.rb +3 -0
- data/lib/openc3/streams/stream.rb +3 -0
- data/lib/openc3/streams/tcpip_client_stream.rb +3 -0
- data/lib/openc3/streams/tcpip_socket_stream.rb +3 -0
- data/lib/openc3/system/system.rb +23 -10
- data/lib/openc3/system/system_config.rb +3 -0
- data/lib/openc3/system/target.rb +3 -0
- data/lib/openc3/system.rb +3 -0
- data/lib/openc3/tools/cmd_tlm_server/api.rb +3 -0
- data/lib/openc3/tools/cmd_tlm_server/cmd_tlm_server_config.rb +3 -0
- data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +3 -0
- data/lib/openc3/tools/table_manager/table.rb +3 -0
- data/lib/openc3/tools/table_manager/table_config.rb +3 -0
- data/lib/openc3/tools/table_manager/table_item.rb +3 -0
- data/lib/openc3/tools/table_manager/table_item_parser.rb +3 -0
- data/lib/openc3/tools/table_manager/table_manager_core.rb +3 -0
- data/lib/openc3/tools/table_manager/table_parser.rb +3 -0
- data/lib/openc3/tools/test_runner/test.rb +3 -0
- data/lib/openc3/top_level.rb +3 -0
- data/lib/openc3/topics/autonomic_topic.rb +3 -0
- data/lib/openc3/topics/calendar_topic.rb +3 -0
- data/lib/openc3/topics/command_decom_topic.rb +4 -1
- data/lib/openc3/topics/command_topic.rb +6 -1
- data/lib/openc3/topics/config_topic.rb +3 -0
- data/lib/openc3/topics/interface_topic.rb +9 -2
- data/lib/openc3/topics/limits_event_topic.rb +144 -10
- data/lib/openc3/topics/notifications_topic.rb +3 -0
- data/lib/openc3/topics/router_topic.rb +10 -3
- data/lib/openc3/topics/telemetry_decom_topic.rb +26 -20
- data/lib/openc3/topics/telemetry_reduced_topics.rb +92 -0
- data/lib/openc3/topics/telemetry_topic.rb +5 -2
- data/lib/openc3/topics/timeline_topic.rb +3 -0
- data/lib/openc3/topics/topic.rb +3 -0
- data/lib/openc3/utilities/authentication.rb +3 -0
- data/lib/openc3/utilities/authorization.rb +3 -0
- data/lib/openc3/utilities/aws_bucket.rb +199 -0
- data/lib/openc3/utilities/bucket.rb +82 -0
- data/lib/openc3/utilities/bucket_file_cache.rb +264 -0
- data/lib/openc3/utilities/bucket_utilities.rb +109 -0
- data/lib/openc3/utilities/crc.rb +3 -0
- data/lib/openc3/utilities/csv.rb +3 -0
- data/lib/openc3/utilities/local_bucket.rb +28 -0
- data/lib/openc3/utilities/local_mode.rb +47 -61
- data/lib/openc3/utilities/logger.rb +7 -1
- data/lib/openc3/utilities/message_log.rb +7 -4
- data/lib/openc3/utilities/metric.rb +4 -1
- data/lib/openc3/utilities/open_telemetry.rb +96 -0
- data/lib/openc3/utilities/process_manager.rb +3 -0
- data/lib/openc3/utilities/quaternion.rb +3 -0
- data/lib/openc3/utilities/ruby_lex_utils.rb +3 -0
- data/lib/openc3/utilities/s3_autoload.rb +3 -3
- data/lib/openc3/utilities/simulated_target.rb +3 -0
- data/lib/openc3/utilities/sleeper.rb +3 -0
- data/lib/openc3/utilities/store.rb +3 -0
- data/lib/openc3/utilities/store_autoload.rb +30 -23
- data/lib/openc3/utilities/target_file.rb +70 -83
- data/lib/openc3/utilities/zip.rb +3 -0
- data/lib/openc3/utilities.rb +3 -0
- data/lib/openc3/version.rb +6 -6
- data/lib/openc3/win32/excel.rb +3 -0
- data/lib/openc3/win32/win32.rb +3 -0
- data/lib/openc3/win32/win32_main.rb +3 -0
- data/lib/openc3.rb +3 -0
- data/tasks/gemfile_stats.rake +3 -0
- data/tasks/spec.rake +3 -0
- data/templates/plugin-template/plugin.gemspec +1 -1
- metadata +112 -6
- data/lib/openc3/utilities/s3.rb +0 -220
- data/lib/openc3/utilities/s3_file_cache.rb +0 -274
@@ -16,6 +16,9 @@
|
|
16
16
|
# Modified by OpenC3, Inc.
|
17
17
|
# All changes Copyright 2022, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
|
+
#
|
20
|
+
# This file may also be used under the terms of a commercial license
|
21
|
+
# if purchased from OpenC3, Inc.
|
19
22
|
|
20
23
|
require 'openc3/win32/win32'
|
21
24
|
require 'timeout' # For Timeout::Error
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
# Copyright 2022 OpenC3, Inc.
|
4
|
+
# All Rights Reserved.
|
5
|
+
#
|
6
|
+
# This program is free software; you can modify and/or redistribute it
|
7
|
+
# under the terms of the GNU Affero General Public License
|
8
|
+
# as published by the Free Software Foundation; version 3 with
|
9
|
+
# attribution addendums as found in the LICENSE.txt
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# This file may also be used under the terms of a commercial license
|
17
|
+
# if purchased from OpenC3, Inc.
|
18
|
+
|
19
|
+
require 'openc3/logs/packet_log_reader'
|
20
|
+
require 'openc3/logs/packet_log_writer'
|
21
|
+
|
22
|
+
module OpenC3
|
23
|
+
# Buffers files so small time differences can be read in time order
|
24
|
+
class BufferedPacketLogReader < PacketLogReader
|
25
|
+
|
26
|
+
attr_reader :bucket_file
|
27
|
+
|
28
|
+
def initialize(bucket_file = nil, buffer_depth = 10)
|
29
|
+
super()
|
30
|
+
@bucket_file = bucket_file
|
31
|
+
@buffer_depth = buffer_depth
|
32
|
+
end
|
33
|
+
|
34
|
+
def next_packet_time
|
35
|
+
fill_buffer()
|
36
|
+
packet = @buffer[0]
|
37
|
+
return packet.packet_time if packet
|
38
|
+
return nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def buffered_read(identify_and_define = true)
|
42
|
+
fill_buffer(identify_and_define)
|
43
|
+
return @buffer.shift
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
def fill_buffer(identify_and_define = true)
|
49
|
+
while true
|
50
|
+
break if @buffer.length >= @buffer_depth
|
51
|
+
packet = read(identify_and_define)
|
52
|
+
break unless packet
|
53
|
+
packet = packet.dup if identify_and_define
|
54
|
+
@buffer << packet
|
55
|
+
@buffer.sort! {|pkt1, pkt2| pkt1.packet_time <=> pkt2.packet_time }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def reset
|
60
|
+
super()
|
61
|
+
@buffer = []
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
# Copyright 2022 OpenC3, Inc.
|
4
|
+
# All Rights Reserved.
|
5
|
+
#
|
6
|
+
# This program is free software; you can modify and/or redistribute it
|
7
|
+
# under the terms of the GNU Affero General Public License
|
8
|
+
# as published by the Free Software Foundation; version 3 with
|
9
|
+
# attribution addendums as found in the LICENSE.txt
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# This file may also be used under the terms of a commercial license
|
17
|
+
# if purchased from OpenC3, Inc.
|
18
|
+
|
19
|
+
require 'openc3/logs/packet_log_writer'
|
20
|
+
|
21
|
+
module OpenC3
|
22
|
+
# Creates a packet log. Can automatically cycle the log based on an elasped
|
23
|
+
# time period or when the log file reaches a predefined size.
|
24
|
+
class BufferedPacketLogWriter < PacketLogWriter
|
25
|
+
# @param remote_log_directory [String] The path to store the log files
|
26
|
+
# @param label [String] Label to apply to the log filename
|
27
|
+
# @param logging_enabled [Boolean] Whether to start with logging enabled
|
28
|
+
# @param cycle_time [Integer] The amount of time in seconds before creating
|
29
|
+
# a new log file. This can be combined with cycle_size but is better used
|
30
|
+
# independently.
|
31
|
+
# @param cycle_size [Integer] The size in bytes before creating a new log
|
32
|
+
# file. This can be combined with cycle_time but is better used
|
33
|
+
# independently.
|
34
|
+
# @param cycle_hour [Integer] The time at which to cycle the log. Combined with
|
35
|
+
# cycle_minute to cycle the log daily at the specified time. If nil, the log
|
36
|
+
# will be cycled hourly at the specified cycle_minute.
|
37
|
+
# @param cycle_minute [Integer] The time at which to cycle the log. See cycle_hour
|
38
|
+
# for more information.
|
39
|
+
# @param buffer_depth [Integer] Number of packets to buffer before writing to file
|
40
|
+
def initialize(
|
41
|
+
remote_log_directory,
|
42
|
+
label,
|
43
|
+
logging_enabled = true,
|
44
|
+
cycle_time = nil,
|
45
|
+
cycle_size = 1_000_000_000,
|
46
|
+
cycle_hour = nil,
|
47
|
+
cycle_minute = nil,
|
48
|
+
enforce_time_order = true,
|
49
|
+
buffer_depth = 10
|
50
|
+
)
|
51
|
+
super(
|
52
|
+
remote_log_directory,
|
53
|
+
label,
|
54
|
+
logging_enabled,
|
55
|
+
cycle_time,
|
56
|
+
cycle_size,
|
57
|
+
cycle_hour,
|
58
|
+
cycle_minute,
|
59
|
+
enforce_time_order
|
60
|
+
)
|
61
|
+
@buffer_depth = Integer(buffer_depth)
|
62
|
+
@buffer = []
|
63
|
+
end
|
64
|
+
|
65
|
+
# Write a packet to the log file.
|
66
|
+
#
|
67
|
+
# If no log file currently exists in the filesystem, a new file will be
|
68
|
+
# created.
|
69
|
+
#
|
70
|
+
# @param entry_type [Symbol] Type of entry to write. Must be one of
|
71
|
+
# :TARGET_DECLARATION, :PACKET_DECLARATION, :RAW_PACKET, :JSON_PACKET, :OFFSET_MARKER, :KEY_MAP
|
72
|
+
# @param cmd_or_tlm [Symbol] One of :CMD or :TLM
|
73
|
+
# @param target_name [String] Name of the target
|
74
|
+
# @param packet_name [String] Name of the packet
|
75
|
+
# @param time_nsec_since_epoch [Integer] 64 bit integer nsecs since EPOCH
|
76
|
+
# @param stored [Boolean] Whether this data is stored telemetry
|
77
|
+
# @param data [String] Binary string of data
|
78
|
+
# @param id [Integer] Target ID
|
79
|
+
# @param redis_offset [Integer] The offset of this packet in its Redis stream
|
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')
|
81
|
+
case entry_type
|
82
|
+
when :RAW_PACKET, :JSON_PACKET
|
83
|
+
@buffer << [entry_type, cmd_or_tlm, target_name, packet_name, time_nsec_since_epoch, stored, data, id, redis_topic, redis_offset]
|
84
|
+
@buffer.sort! {|entry1, entry2| entry1[4] <=> entry2[4] }
|
85
|
+
if @buffer.length >= @buffer_depth
|
86
|
+
entry = @buffer.shift
|
87
|
+
write(*entry)
|
88
|
+
end
|
89
|
+
else
|
90
|
+
write(entry_type, cmd_or_tlm, target_name, packet_name, time_nsec_since_epoch, stored, data, id, redis_topic, redis_offset)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def buffered_first_time_nsec
|
95
|
+
time = first_time()
|
96
|
+
return time.to_nsec_from_epoch if time
|
97
|
+
return @buffer[0][4] if @buffer[0]
|
98
|
+
return nil
|
99
|
+
end
|
100
|
+
|
101
|
+
def start_new_file(empty_buffer = false)
|
102
|
+
write_buffer() if empty_buffer
|
103
|
+
super()
|
104
|
+
end
|
105
|
+
|
106
|
+
def write_buffer
|
107
|
+
@buffer.each do |entry|
|
108
|
+
write(*entry)
|
109
|
+
end
|
110
|
+
@buffer = []
|
111
|
+
end
|
112
|
+
|
113
|
+
# Need to write out all remaining buffer entries and then shutdown
|
114
|
+
# Returns thread that moves final log to bucket
|
115
|
+
def shutdown
|
116
|
+
write_buffer()
|
117
|
+
return super()
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -16,11 +16,14 @@
|
|
16
16
|
# Modified by OpenC3, Inc.
|
17
17
|
# All changes Copyright 2022, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
|
+
#
|
20
|
+
# This file may also be used under the terms of a commercial license
|
21
|
+
# if purchased from OpenC3, Inc.
|
19
22
|
|
20
23
|
require 'thread'
|
21
24
|
require 'openc3/config/config_parser'
|
22
25
|
require 'openc3/topics/topic'
|
23
|
-
require 'openc3/utilities/
|
26
|
+
require 'openc3/utilities/bucket_utilities'
|
24
27
|
|
25
28
|
module OpenC3
|
26
29
|
# Creates a log. Can automatically cycle the log based on an elasped
|
@@ -52,10 +55,19 @@ module OpenC3
|
|
52
55
|
# @return [Mutex] Instance mutex protecting file
|
53
56
|
attr_reader :mutex
|
54
57
|
|
58
|
+
# Redis offsets for each topic to cleanup
|
59
|
+
attr_accessor :cleanup_offsets
|
60
|
+
|
61
|
+
# Time at which to cleanup
|
62
|
+
attr_accessor :cleanup_times
|
63
|
+
|
55
64
|
# The cycle time interval. Cycle times are only checked at this level of
|
56
65
|
# granularity.
|
57
66
|
CYCLE_TIME_INTERVAL = 10
|
58
67
|
|
68
|
+
# Delay in seconds before trimming Redis streams
|
69
|
+
CLEANUP_DELAY = 60
|
70
|
+
|
59
71
|
# Mutex protecting class variables
|
60
72
|
@@mutex = Mutex.new
|
61
73
|
|
@@ -68,7 +80,7 @@ module OpenC3
|
|
68
80
|
# Sleeper used to delay cycle thread
|
69
81
|
@@cycle_sleeper = nil
|
70
82
|
|
71
|
-
# @param remote_log_directory [String] The
|
83
|
+
# @param remote_log_directory [String] The path to store the log files
|
72
84
|
# @param logging_enabled [Boolean] Whether to start with logging enabled
|
73
85
|
# @param cycle_time [Integer] The amount of time in seconds before creating
|
74
86
|
# a new log file. This can be combined with cycle_size but is better used
|
@@ -81,8 +93,6 @@ module OpenC3
|
|
81
93
|
# will be cycled hourly at the specified cycle_minute.
|
82
94
|
# @param cycle_minute [Integer] The time at which to cycle the log. See cycle_hour
|
83
95
|
# for more information.
|
84
|
-
# @param redis_topic [String] The key of the Redis stream to trim when files are
|
85
|
-
# moved to S3
|
86
96
|
def initialize(
|
87
97
|
remote_log_directory,
|
88
98
|
logging_enabled = true,
|
@@ -90,7 +100,7 @@ module OpenC3
|
|
90
100
|
cycle_size = 1000000000,
|
91
101
|
cycle_hour = nil,
|
92
102
|
cycle_minute = nil,
|
93
|
-
|
103
|
+
enforce_time_order = true
|
94
104
|
)
|
95
105
|
@remote_log_directory = remote_log_directory
|
96
106
|
@logging_enabled = ConfigParser.handle_true_false(logging_enabled)
|
@@ -105,6 +115,7 @@ module OpenC3
|
|
105
115
|
@cycle_hour = Integer(@cycle_hour) if @cycle_hour
|
106
116
|
@cycle_minute = ConfigParser.handle_nil(cycle_minute)
|
107
117
|
@cycle_minute = Integer(@cycle_minute) if @cycle_minute
|
118
|
+
@enforce_time_order = ConfigParser.handle_true_false(enforce_time_order)
|
108
119
|
@mutex = Mutex.new
|
109
120
|
@file = nil
|
110
121
|
@file_size = 0
|
@@ -113,22 +124,22 @@ module OpenC3
|
|
113
124
|
@first_time = nil
|
114
125
|
@last_time = nil
|
115
126
|
@cancel_threads = false
|
116
|
-
@
|
117
|
-
@
|
118
|
-
@
|
127
|
+
@last_offsets = {}
|
128
|
+
@cleanup_offsets = []
|
129
|
+
@cleanup_times = []
|
130
|
+
@previous_time_nsec_since_epoch = nil
|
119
131
|
|
120
132
|
# This is an optimization to avoid creating a new entry object
|
121
133
|
# each time we create an entry which we do a LOT!
|
122
134
|
@entry = String.new
|
123
135
|
|
124
|
-
|
125
|
-
|
126
|
-
|
136
|
+
# Always make sure there is a cycle thread - (because it does trimming)
|
137
|
+
@@mutex.synchronize do
|
138
|
+
@@instances << self
|
127
139
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
end
|
140
|
+
unless @@cycle_thread
|
141
|
+
@@cycle_thread = OpenC3.safe_thread("Log cycle") do
|
142
|
+
cycle_thread_body()
|
132
143
|
end
|
133
144
|
end
|
134
145
|
end
|
@@ -143,12 +154,14 @@ module OpenC3
|
|
143
154
|
|
144
155
|
# Stops all logging and closes the current log file.
|
145
156
|
def stop
|
146
|
-
|
157
|
+
threads = nil
|
158
|
+
@mutex.synchronize { @logging_enabled = false; threads = close_file(false) }
|
159
|
+
return threads
|
147
160
|
end
|
148
161
|
|
149
162
|
# Stop all logging, close the current log file, and kill the logging threads.
|
150
163
|
def shutdown
|
151
|
-
stop()
|
164
|
+
threads = stop()
|
152
165
|
@@mutex.synchronize do
|
153
166
|
@@instances.delete(self)
|
154
167
|
if @@instances.length <= 0
|
@@ -157,6 +170,7 @@ module OpenC3
|
|
157
170
|
@@cycle_thread = nil
|
158
171
|
end
|
159
172
|
end
|
173
|
+
return threads
|
160
174
|
end
|
161
175
|
|
162
176
|
def graceful_kill
|
@@ -192,18 +206,41 @@ module OpenC3
|
|
192
206
|
instance.mutex.synchronize do
|
193
207
|
utc_now = Time.now.utc
|
194
208
|
# Logger.debug("start:#{@start_time.to_f} now:#{utc_now.to_f} cycle:#{@cycle_time} new:#{(utc_now - @start_time) > @cycle_time}")
|
195
|
-
if instance.logging_enabled and
|
196
|
-
|
197
|
-
|
198
|
-
(
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
)
|
206
|
-
|
209
|
+
if instance.logging_enabled and instance.filename # Logging and file opened
|
210
|
+
# Cycle based on total time logging
|
211
|
+
if (instance.cycle_time and (utc_now - instance.start_time) > instance.cycle_time)
|
212
|
+
Logger.debug("Log writer start new file due to cycle time")
|
213
|
+
instance.close_file(false)
|
214
|
+
# Cycle daily at a specific time
|
215
|
+
elsif (instance.cycle_hour and instance.cycle_minute and utc_now.hour == instance.cycle_hour and utc_now.min == instance.cycle_minute and instance.start_time.yday != utc_now.yday)
|
216
|
+
Logger.debug("Log writer start new file daily")
|
217
|
+
instance.close_file(false)
|
218
|
+
# Cycle hourly at a specific time
|
219
|
+
elsif (instance.cycle_minute and not instance.cycle_hour and utc_now.min == instance.cycle_minute and instance.start_time.hour != utc_now.hour)
|
220
|
+
Logger.debug("Log writer start new file hourly")
|
221
|
+
instance.close_file(false)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
# Check for cleanup time
|
226
|
+
indexes_to_clear = []
|
227
|
+
instance.cleanup_times.each_with_index do |cleanup_time, index|
|
228
|
+
if cleanup_time <= utc_now
|
229
|
+
# Now that the file is in S3, trim the Redis stream up until the previous file.
|
230
|
+
# This keeps one minute of data in Redis
|
231
|
+
instance.cleanup_offsets[index].each do |redis_topic, cleanup_offset|
|
232
|
+
Topic.trim_topic(redis_topic, cleanup_offset)
|
233
|
+
end
|
234
|
+
indexes_to_clear << index
|
235
|
+
end
|
236
|
+
end
|
237
|
+
if indexes_to_clear.length > 0
|
238
|
+
indexes_to_clear.each do |index|
|
239
|
+
instance.cleanup_offsets[index] = nil
|
240
|
+
instance.cleanup_times[index] = nil
|
241
|
+
end
|
242
|
+
instance.cleanup_offsets.compact!
|
243
|
+
instance.cleanup_times.compact!
|
207
244
|
end
|
208
245
|
end
|
209
246
|
end
|
@@ -231,6 +268,7 @@ module OpenC3
|
|
231
268
|
@start_time = Time.now.utc
|
232
269
|
@first_time = nil
|
233
270
|
@last_time = nil
|
271
|
+
@previous_time_nsec_since_epoch = nil
|
234
272
|
Logger.debug "Log File Opened : #{@filename}"
|
235
273
|
rescue => err
|
236
274
|
Logger.error "Error starting new log file: #{err.formatted}"
|
@@ -238,17 +276,30 @@ module OpenC3
|
|
238
276
|
OpenC3.handle_critical_exception(err)
|
239
277
|
end
|
240
278
|
|
241
|
-
def prepare_write(time_nsec_since_epoch, data_length, redis_offset)
|
279
|
+
def prepare_write(time_nsec_since_epoch, data_length, redis_topic, redis_offset)
|
242
280
|
# This check includes logging_enabled again because it might have changed since we acquired the mutex
|
243
|
-
|
244
|
-
|
281
|
+
# Ensures new files based on size, and ensures always increasing time order in files
|
282
|
+
if @logging_enabled
|
283
|
+
if !@file
|
284
|
+
Logger.debug("Log writer start new file because no file opened")
|
285
|
+
start_new_file()
|
286
|
+
elsif @cycle_size and ((@file_size + data_length) > @cycle_size)
|
287
|
+
Logger.debug("Log writer start new file due to cycle size #{@cycle_size}")
|
288
|
+
start_new_file()
|
289
|
+
elsif @enforce_time_order and @previous_time_nsec_since_epoch and (@previous_time_nsec_since_epoch > time_nsec_since_epoch)
|
290
|
+
Logger.debug("Log writer start new file due to out of order time: #{Time.from_nsec_from_epoch(@previous_time_nsec_since_epoch)} #{Time.from_nsec_from_epoch(time_nsec_since_epoch)}")
|
291
|
+
start_new_file()
|
292
|
+
end
|
245
293
|
end
|
246
|
-
@
|
294
|
+
@last_offsets[redis_topic] = redis_offset if redis_topic and redis_offset # This is needed for the redis offset marker entry at the end of the log file
|
295
|
+
@previous_time_nsec_since_epoch = time_nsec_since_epoch
|
247
296
|
end
|
248
297
|
|
249
298
|
# Closing a log file isn't critical so we just log an error. NOTE: This also trims the Redis stream
|
250
299
|
# to keep a full file's worth of data in the stream. This is what prevents continuous stream growth.
|
300
|
+
# Returns thread that moves log to bucket
|
251
301
|
def close_file(take_mutex = true)
|
302
|
+
threads = []
|
252
303
|
@mutex.lock if take_mutex
|
253
304
|
begin
|
254
305
|
if @file
|
@@ -256,12 +307,15 @@ module OpenC3
|
|
256
307
|
@file.close unless @file.closed?
|
257
308
|
Logger.debug "Log File Closed : #{@filename}"
|
258
309
|
date = first_timestamp[0..7] # YYYYMMDD
|
259
|
-
|
260
|
-
|
261
|
-
# Now that the file is in
|
262
|
-
|
263
|
-
|
264
|
-
|
310
|
+
bucket_key = File.join(@remote_log_directory, date, bucket_filename())
|
311
|
+
threads << BucketUtilities.move_log_file_to_bucket(@filename, bucket_key)
|
312
|
+
# Now that the file is in storage, trim the Redis stream after a delay
|
313
|
+
@cleanup_offsets << {}
|
314
|
+
@last_offsets.each do |redis_topic, last_offset|
|
315
|
+
@cleanup_offsets[-1][redis_topic] = last_offset
|
316
|
+
end
|
317
|
+
@cleanup_times << Time.now + CLEANUP_DELAY
|
318
|
+
@last_offsets.clear
|
265
319
|
rescue Exception => err
|
266
320
|
Logger.instance.error "Error closing #{@filename} : #{err.formatted}"
|
267
321
|
end
|
@@ -273,9 +327,10 @@ module OpenC3
|
|
273
327
|
ensure
|
274
328
|
@mutex.unlock if take_mutex
|
275
329
|
end
|
330
|
+
return threads
|
276
331
|
end
|
277
332
|
|
278
|
-
def
|
333
|
+
def bucket_filename
|
279
334
|
"#{first_timestamp}__#{last_timestamp}" + extension
|
280
335
|
end
|
281
336
|
|
@@ -16,6 +16,9 @@
|
|
16
16
|
# Modified by OpenC3, Inc.
|
17
17
|
# All changes Copyright 2022, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
|
+
#
|
20
|
+
# This file may also be used under the terms of a commercial license
|
21
|
+
# if purchased from OpenC3, Inc.
|
19
22
|
|
20
23
|
module OpenC3
|
21
24
|
module PacketLogConstants
|
@@ -34,6 +37,8 @@ module OpenC3
|
|
34
37
|
OPENC3_RAW_PACKET_ENTRY_TYPE_MASK = 0x3000
|
35
38
|
OPENC3_JSON_PACKET_ENTRY_TYPE_MASK = 0x4000
|
36
39
|
OPENC3_OFFSET_MARKER_ENTRY_TYPE_MASK = 0x5000
|
40
|
+
OPENC3_KEY_MAP_ENTRY_TYPE_MASK = 0x6000
|
41
|
+
OPENC3_CBOR_FLAG_MASK = 0x0100
|
37
42
|
OPENC3_ID_FLAG_MASK = 0x0200
|
38
43
|
OPENC3_STORED_FLAG_MASK = 0x0400
|
39
44
|
OPENC3_CMD_FLAG_MASK = 0x0800
|
@@ -55,6 +60,10 @@ module OpenC3
|
|
55
60
|
OPENC3_OFFSET_MARKER_PACK_DIRECTIVE = 'Nn'.freeze
|
56
61
|
OPENC3_OFFSET_MARKER_PACK_ITEMS = 2 # Useful for testing
|
57
62
|
|
63
|
+
OPENC3_KEY_MAP_SECONDARY_FIXED_SIZE = 2
|
64
|
+
OPENC3_KEY_MAP_PACK_DIRECTIVE = 'Nnn'.freeze
|
65
|
+
OPENC3_KEY_MAP_PACK_ITEMS = 3 # Useful for testing
|
66
|
+
|
58
67
|
OPENC3_PACKET_SECONDARY_FIXED_SIZE = 10
|
59
68
|
OPENC3_PACKET_PACK_DIRECTIVE = 'NnnQ>'.freeze
|
60
69
|
OPENC3_PACKET_PACK_ITEMS = 4 # Useful for testing
|
@@ -16,12 +16,16 @@
|
|
16
16
|
# Modified by OpenC3, Inc.
|
17
17
|
# All changes Copyright 2022, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
|
+
#
|
20
|
+
# This file may also be used under the terms of a commercial license
|
21
|
+
# if purchased from OpenC3, Inc.
|
19
22
|
|
20
23
|
require 'openc3/core_ext/io'
|
21
24
|
require 'openc3/packets/packet'
|
22
25
|
require 'openc3/packets/json_packet'
|
23
26
|
require 'openc3/io/buffered_file'
|
24
27
|
require 'openc3/logs/packet_log_constants'
|
28
|
+
require 'cbor'
|
25
29
|
|
26
30
|
module OpenC3
|
27
31
|
# Reads a packet log of either commands or telemetry.
|
@@ -29,6 +33,8 @@ module OpenC3
|
|
29
33
|
include PacketLogConstants
|
30
34
|
|
31
35
|
attr_reader :redis_offset
|
36
|
+
attr_reader :last_offsets
|
37
|
+
attr_reader :filename
|
32
38
|
|
33
39
|
MAX_READ_SIZE = 1000000000
|
34
40
|
|
@@ -119,16 +125,22 @@ module OpenC3
|
|
119
125
|
stored = true if flags & OPENC3_STORED_FLAG_MASK == OPENC3_STORED_FLAG_MASK
|
120
126
|
id = false
|
121
127
|
id = true if flags & OPENC3_ID_FLAG_MASK == OPENC3_ID_FLAG_MASK
|
128
|
+
cbor = false
|
129
|
+
cbor = true if flags & OPENC3_CBOR_FLAG_MASK == OPENC3_CBOR_FLAG_MASK
|
122
130
|
|
123
131
|
if flags & OPENC3_ENTRY_TYPE_MASK == OPENC3_JSON_PACKET_ENTRY_TYPE_MASK
|
124
132
|
packet_index, time_nsec_since_epoch = entry[2..11].unpack('nQ>')
|
125
133
|
json_data = entry[12..-1]
|
126
|
-
lookup_cmd_or_tlm, target_name, packet_name, id = @packets[packet_index]
|
134
|
+
lookup_cmd_or_tlm, target_name, packet_name, id, key_map = @packets[packet_index]
|
127
135
|
if cmd_or_tlm != lookup_cmd_or_tlm
|
128
136
|
raise "Packet type mismatch, packet:#{cmd_or_tlm}, lookup:#{lookup_cmd_or_tlm}"
|
129
137
|
end
|
130
138
|
|
131
|
-
|
139
|
+
if cbor
|
140
|
+
return JsonPacket.new(cmd_or_tlm, target_name, packet_name, time_nsec_since_epoch, stored, CBOR.decode(json_data), key_map)
|
141
|
+
else
|
142
|
+
return JsonPacket.new(cmd_or_tlm, target_name, packet_name, time_nsec_since_epoch, stored, json_data, key_map)
|
143
|
+
end
|
132
144
|
elsif flags & OPENC3_ENTRY_TYPE_MASK == OPENC3_RAW_PACKET_ENTRY_TYPE_MASK
|
133
145
|
packet_index, time_nsec_since_epoch = entry[2..11].unpack('nQ>')
|
134
146
|
packet_data = entry[12..-1]
|
@@ -171,8 +183,26 @@ module OpenC3
|
|
171
183
|
end
|
172
184
|
@packets << [cmd_or_tlm, target_name, packet_name, id]
|
173
185
|
return read(identify_and_define)
|
186
|
+
elsif flags & OPENC3_ENTRY_TYPE_MASK == OPENC3_KEY_MAP_ENTRY_TYPE_MASK
|
187
|
+
packet_index = entry[2..3].unpack('n')[0]
|
188
|
+
key_map_length = length - OPENC3_PRIMARY_FIXED_SIZE - OPENC3_KEY_MAP_SECONDARY_FIXED_SIZE
|
189
|
+
if cbor
|
190
|
+
key_map = CBOR.decode(entry[4..(key_map_length + 3)])
|
191
|
+
else
|
192
|
+
key_map = JSON.parse(entry[4..(key_map_length + 3)], :allow_nan => true, :create_additions => true)
|
193
|
+
end
|
194
|
+
@packets[packet_index] << key_map
|
195
|
+
return read(identify_and_define)
|
174
196
|
elsif flags & OPENC3_ENTRY_TYPE_MASK == OPENC3_OFFSET_MARKER_ENTRY_TYPE_MASK
|
175
|
-
|
197
|
+
data = entry[2..-1]
|
198
|
+
split_data = data.split(',')
|
199
|
+
redis_offset = split_data[0]
|
200
|
+
redis_topic = split_data[1]
|
201
|
+
if redis_topic
|
202
|
+
@last_offsets[redis_topic] = redis_offset
|
203
|
+
else
|
204
|
+
@redis_offset = redis_offset
|
205
|
+
end
|
176
206
|
return read(identify_and_define)
|
177
207
|
else
|
178
208
|
raise "Invalid Entry Flags: #{flags}"
|
@@ -292,6 +322,7 @@ module OpenC3
|
|
292
322
|
@packets = []
|
293
323
|
@packet_ids = []
|
294
324
|
@redis_offset = nil
|
325
|
+
@last_offsets = {}
|
295
326
|
end
|
296
327
|
|
297
328
|
# This is best effort. May return unidentified/undefined packets
|