blob: 54b55d8d71c20118a860cb9a814ce9ede3464e7d [file] [log] [blame]
Austin Schuhe309d2a2019-11-29 13:25:21 -08001#ifndef AOS_EVENTS_LOGGER_H_
2#define AOS_EVENTS_LOGGER_H_
3
4#include <deque>
5#include <vector>
Austin Schuh05b70472020-01-01 17:11:17 -08006#include <string_view>
Austin Schuhe309d2a2019-11-29 13:25:21 -08007
Austin Schuhe309d2a2019-11-29 13:25:21 -08008#include "absl/types/span.h"
9#include "aos/events/event_loop.h"
Austin Schuha36c8902019-12-30 18:07:15 -080010#include "aos/events/logging/logfile_utils.h"
James Kuszmaul38735e82019-12-07 16:42:06 -080011#include "aos/events/logging/logger_generated.h"
Austin Schuh92547522019-12-28 14:33:43 -080012#include "aos/events/simulated_event_loop.h"
Austin Schuhe309d2a2019-11-29 13:25:21 -080013#include "aos/time/time.h"
14#include "flatbuffers/flatbuffers.h"
15
16namespace aos {
17namespace logger {
18
Austin Schuhe309d2a2019-11-29 13:25:21 -080019// Logs all channels available in the event loop to disk every 100 ms.
20// Start by logging one message per channel to capture any state and
21// configuration that is sent rately on a channel and would affect execution.
22class Logger {
23 public:
24 Logger(DetachedBufferWriter *writer, EventLoop *event_loop,
25 std::chrono::milliseconds polling_period =
26 std::chrono::milliseconds(100));
27
Austin Schuhfa895892020-01-07 20:07:41 -080028 // Rotates the log file with the new writer. This writes out the header
29 // again, but keeps going as if nothing else happened.
30 void Rotate(DetachedBufferWriter *writer);
31
Austin Schuhe309d2a2019-11-29 13:25:21 -080032 private:
Austin Schuhfa895892020-01-07 20:07:41 -080033 void WriteHeader();
34
Austin Schuhe309d2a2019-11-29 13:25:21 -080035 void DoLogData();
36
37 EventLoop *event_loop_;
38 DetachedBufferWriter *writer_;
39
40 // Structure to track both a fetcher, and if the data fetched has been
41 // written. We may want to delay writing data to disk so that we don't let
42 // data get too far out of order when written to disk so we can avoid making
43 // it too hard to sort when reading.
44 struct FetcherStruct {
45 std::unique_ptr<RawFetcher> fetcher;
46 bool written = false;
Austin Schuh15649d62019-12-28 16:36:38 -080047
48 LogType log_type;
Austin Schuhe309d2a2019-11-29 13:25:21 -080049 };
50
51 std::vector<FetcherStruct> fetchers_;
52 TimerHandler *timer_handler_;
53
54 // Period to poll the channels.
55 const std::chrono::milliseconds polling_period_;
56
57 // Last time that data was written for all channels to disk.
58 monotonic_clock::time_point last_synchronized_time_;
59
Austin Schuhfa895892020-01-07 20:07:41 -080060 monotonic_clock::time_point monotonic_start_time_;
61 realtime_clock::time_point realtime_start_time_;
62
Austin Schuhe309d2a2019-11-29 13:25:21 -080063 // Max size that the header has consumed. This much extra data will be
64 // reserved in the builder to avoid reallocating.
65 size_t max_header_size_ = 0;
66};
67
68// Replays all the channels in the logfile to the event loop.
69class LogReader {
70 public:
James Kuszmaulc7bbb3e2020-01-03 20:01:00 -080071 // If you want to supply a new configuration that will be used for replay
72 // (e.g., to change message rates, or to populate an updated schema), then
73 // pass it in here. It must provide all the channels that the original logged
74 // config did.
75 LogReader(std::string_view filename,
76 const Configuration *replay_configuration = nullptr);
Austin Schuhfa895892020-01-07 20:07:41 -080077 LogReader(const std::vector<std::string> &filename,
78 const Configuration *replay_configuration = nullptr);
James Kuszmaul7daef362019-12-31 18:28:17 -080079 ~LogReader();
Austin Schuhe309d2a2019-11-29 13:25:21 -080080
Austin Schuh6331ef92020-01-07 18:28:09 -080081 // Registers all the callbacks to send the log file data out on an event loop
82 // created in event_loop_factory. This also updates time to be at the start
83 // of the log file by running until the log file starts.
84 // Note: the configuration used in the factory should be configuration()
85 // below, but can be anything as long as the locations needed to send
86 // everything are available.
James Kuszmaul84ff3e52020-01-03 19:48:53 -080087 void Register(SimulatedEventLoopFactory *event_loop_factory);
Austin Schuh6331ef92020-01-07 18:28:09 -080088 // Creates an SimulatedEventLoopFactory accessible via event_loop_factory(),
89 // and then calls Register.
90 void Register();
91 // Registers callbacks for all the events after the log file starts. This is
92 // only useful when replaying live.
Austin Schuhe309d2a2019-11-29 13:25:21 -080093 void Register(EventLoop *event_loop);
Austin Schuh6331ef92020-01-07 18:28:09 -080094
James Kuszmaul84ff3e52020-01-03 19:48:53 -080095 // Unregisters the senders. You only need to call this if you separately
96 // supplied an event loop or event loop factory and the lifetimes are such
97 // that they need to be explicitly destroyed before the LogReader destructor
98 // gets called.
Austin Schuhe309d2a2019-11-29 13:25:21 -080099 void Deregister();
100
Austin Schuhe309d2a2019-11-29 13:25:21 -0800101 // Returns the configuration from the log file.
James Kuszmaulc7bbb3e2020-01-03 20:01:00 -0800102 const Configuration *logged_configuration() const;
103 // Returns the configuration being used for replay.
Austin Schuh15649d62019-12-28 16:36:38 -0800104 const Configuration *configuration() const;
105
Austin Schuh6331ef92020-01-07 18:28:09 -0800106 const LogFileHeader *log_file_header() const {
107 return sorted_message_reader_.log_file_header();
108 }
109
110 // Returns the node that this log file was created on. This is a pointer to a
111 // node in the nodes() list inside configuration().
Austin Schuh15649d62019-12-28 16:36:38 -0800112 const Node *node() const;
Austin Schuhe309d2a2019-11-29 13:25:21 -0800113
114 // Returns the starting timestamp for the log file.
115 monotonic_clock::time_point monotonic_start_time();
116 realtime_clock::time_point realtime_start_time();
117
James Kuszmaulc7bbb3e2020-01-03 20:01:00 -0800118 // Causes the logger to publish the provided channel on a different name so
119 // that replayed applications can publish on the proper channel name without
120 // interference. This operates on raw channel names, without any node or
121 // application specific mappings.
122 void RemapLoggedChannel(std::string_view name, std::string_view type,
123 std::string_view add_prefix = "/original");
124 template <typename T>
125 void RemapLoggedChannel(std::string_view name,
126 std::string_view add_prefix = "/original") {
127 RemapLoggedChannel(name, T::GetFullyQualifiedName(), add_prefix);
128 }
129
James Kuszmaul84ff3e52020-01-03 19:48:53 -0800130 SimulatedEventLoopFactory *event_loop_factory() {
131 return event_loop_factory_;
132 }
133
Austin Schuhe309d2a2019-11-29 13:25:21 -0800134 // TODO(austin): Add the ability to re-publish the fetched messages. Add 2
135 // options, one which publishes them *now*, and another which publishes them
136 // to the simulated event loop factory back in time where they actually
137 // happened.
138
139 private:
Austin Schuhe309d2a2019-11-29 13:25:21 -0800140 // Queues at least max_out_of_order_duration_ messages into channels_.
141 void QueueMessages();
James Kuszmaulc7bbb3e2020-01-03 20:01:00 -0800142 // Handle constructing a configuration with all the additional remapped
143 // channels from calls to RemapLoggedChannel.
144 void MakeRemappedConfig();
Austin Schuhe309d2a2019-11-29 13:25:21 -0800145
Austin Schuh05b70472020-01-01 17:11:17 -0800146 // Log chunk reader.
147 SortedMessageReader sorted_message_reader_;
Austin Schuhe309d2a2019-11-29 13:25:21 -0800148
James Kuszmaul84ff3e52020-01-03 19:48:53 -0800149 std::unique_ptr<FlatbufferDetachedBuffer<Configuration>>
150 remapped_configuration_buffer_;
151
Austin Schuh05b70472020-01-01 17:11:17 -0800152 std::vector<std::unique_ptr<RawSender>> channels_;
Austin Schuhe309d2a2019-11-29 13:25:21 -0800153
Austin Schuh92547522019-12-28 14:33:43 -0800154 std::unique_ptr<EventLoop> event_loop_unique_ptr_;
Austin Schuhac0771c2020-01-07 18:36:30 -0800155 NodeEventLoopFactory *node_event_loop_factory_ = nullptr;
Austin Schuh92547522019-12-28 14:33:43 -0800156 EventLoop *event_loop_ = nullptr;
Austin Schuhe309d2a2019-11-29 13:25:21 -0800157 TimerHandler *timer_handler_;
James Kuszmaul84ff3e52020-01-03 19:48:53 -0800158
159 std::unique_ptr<SimulatedEventLoopFactory> event_loop_factory_unique_ptr_;
160 SimulatedEventLoopFactory *event_loop_factory_ = nullptr;
James Kuszmaulc7bbb3e2020-01-03 20:01:00 -0800161
162 // Map of channel indices to new name. The channel index will be an index into
163 // logged_configuration(), and the string key will be the name of the channel
164 // to send on instead of the logged channel name.
165 std::map<size_t, std::string> remapped_channels_;
166
167 const Configuration *remapped_configuration_ = nullptr;
168 const Configuration *replay_configuration_ = nullptr;
Austin Schuhe309d2a2019-11-29 13:25:21 -0800169};
170
171} // namespace logger
172} // namespace aos
173
174#endif // AOS_EVENTS_LOGGER_H_