Austin Schuh | e309d2a | 2019-11-29 13:25:21 -0800 | [diff] [blame] | 1 | #ifndef AOS_EVENTS_LOGGER_H_ |
| 2 | #define AOS_EVENTS_LOGGER_H_ |
| 3 | |
| 4 | #include <deque> |
| 5 | #include <vector> |
Austin Schuh | 05b7047 | 2020-01-01 17:11:17 -0800 | [diff] [blame] | 6 | #include <string_view> |
Austin Schuh | e309d2a | 2019-11-29 13:25:21 -0800 | [diff] [blame] | 7 | |
Austin Schuh | e309d2a | 2019-11-29 13:25:21 -0800 | [diff] [blame] | 8 | #include "absl/types/span.h" |
| 9 | #include "aos/events/event_loop.h" |
Austin Schuh | a36c890 | 2019-12-30 18:07:15 -0800 | [diff] [blame] | 10 | #include "aos/events/logging/logfile_utils.h" |
James Kuszmaul | 38735e8 | 2019-12-07 16:42:06 -0800 | [diff] [blame] | 11 | #include "aos/events/logging/logger_generated.h" |
Austin Schuh | 9254752 | 2019-12-28 14:33:43 -0800 | [diff] [blame] | 12 | #include "aos/events/simulated_event_loop.h" |
Austin Schuh | e309d2a | 2019-11-29 13:25:21 -0800 | [diff] [blame] | 13 | #include "aos/time/time.h" |
| 14 | #include "flatbuffers/flatbuffers.h" |
| 15 | |
| 16 | namespace aos { |
| 17 | namespace logger { |
| 18 | |
Austin Schuh | e309d2a | 2019-11-29 13:25:21 -0800 | [diff] [blame] | 19 | // 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. |
| 22 | class Logger { |
| 23 | public: |
| 24 | Logger(DetachedBufferWriter *writer, EventLoop *event_loop, |
| 25 | std::chrono::milliseconds polling_period = |
| 26 | std::chrono::milliseconds(100)); |
| 27 | |
| 28 | private: |
| 29 | void DoLogData(); |
| 30 | |
| 31 | EventLoop *event_loop_; |
| 32 | DetachedBufferWriter *writer_; |
| 33 | |
| 34 | // Structure to track both a fetcher, and if the data fetched has been |
| 35 | // written. We may want to delay writing data to disk so that we don't let |
| 36 | // data get too far out of order when written to disk so we can avoid making |
| 37 | // it too hard to sort when reading. |
| 38 | struct FetcherStruct { |
| 39 | std::unique_ptr<RawFetcher> fetcher; |
| 40 | bool written = false; |
Austin Schuh | 15649d6 | 2019-12-28 16:36:38 -0800 | [diff] [blame] | 41 | |
| 42 | LogType log_type; |
Austin Schuh | e309d2a | 2019-11-29 13:25:21 -0800 | [diff] [blame] | 43 | }; |
| 44 | |
| 45 | std::vector<FetcherStruct> fetchers_; |
| 46 | TimerHandler *timer_handler_; |
| 47 | |
| 48 | // Period to poll the channels. |
| 49 | const std::chrono::milliseconds polling_period_; |
| 50 | |
| 51 | // Last time that data was written for all channels to disk. |
| 52 | monotonic_clock::time_point last_synchronized_time_; |
| 53 | |
| 54 | // Max size that the header has consumed. This much extra data will be |
| 55 | // reserved in the builder to avoid reallocating. |
| 56 | size_t max_header_size_ = 0; |
| 57 | }; |
| 58 | |
| 59 | // Replays all the channels in the logfile to the event loop. |
| 60 | class LogReader { |
| 61 | public: |
Austin Schuh | 05b7047 | 2020-01-01 17:11:17 -0800 | [diff] [blame] | 62 | LogReader(std::string_view filename); |
James Kuszmaul | 7daef36 | 2019-12-31 18:28:17 -0800 | [diff] [blame] | 63 | ~LogReader(); |
Austin Schuh | e309d2a | 2019-11-29 13:25:21 -0800 | [diff] [blame] | 64 | |
| 65 | // Registers the timer and senders used to resend the messages from the log |
| 66 | // file. |
| 67 | void Register(EventLoop *event_loop); |
Austin Schuh | 9254752 | 2019-12-28 14:33:43 -0800 | [diff] [blame] | 68 | // Registers everything, but also updates the real time time in sync. Runs |
| 69 | // until the log file starts. |
| 70 | void Register(SimulatedEventLoopFactory *factory); |
Austin Schuh | e309d2a | 2019-11-29 13:25:21 -0800 | [diff] [blame] | 71 | // Unregisters the senders. |
| 72 | void Deregister(); |
| 73 | |
| 74 | // TODO(austin): Remap channels? |
| 75 | |
| 76 | // Returns the configuration from the log file. |
Austin Schuh | 15649d6 | 2019-12-28 16:36:38 -0800 | [diff] [blame] | 77 | const Configuration *configuration() const; |
| 78 | |
| 79 | // Returns the node that this log file was created on. |
| 80 | const Node *node() const; |
Austin Schuh | e309d2a | 2019-11-29 13:25:21 -0800 | [diff] [blame] | 81 | |
| 82 | // Returns the starting timestamp for the log file. |
| 83 | monotonic_clock::time_point monotonic_start_time(); |
| 84 | realtime_clock::time_point realtime_start_time(); |
| 85 | |
| 86 | // TODO(austin): Add the ability to re-publish the fetched messages. Add 2 |
| 87 | // options, one which publishes them *now*, and another which publishes them |
| 88 | // to the simulated event loop factory back in time where they actually |
| 89 | // happened. |
| 90 | |
| 91 | private: |
Austin Schuh | e309d2a | 2019-11-29 13:25:21 -0800 | [diff] [blame] | 92 | // Queues at least max_out_of_order_duration_ messages into channels_. |
| 93 | void QueueMessages(); |
| 94 | |
Austin Schuh | 05b7047 | 2020-01-01 17:11:17 -0800 | [diff] [blame] | 95 | // Log chunk reader. |
| 96 | SortedMessageReader sorted_message_reader_; |
Austin Schuh | e309d2a | 2019-11-29 13:25:21 -0800 | [diff] [blame] | 97 | |
Austin Schuh | 05b7047 | 2020-01-01 17:11:17 -0800 | [diff] [blame] | 98 | std::vector<std::unique_ptr<RawSender>> channels_; |
Austin Schuh | e309d2a | 2019-11-29 13:25:21 -0800 | [diff] [blame] | 99 | |
Austin Schuh | 9254752 | 2019-12-28 14:33:43 -0800 | [diff] [blame] | 100 | SimulatedEventLoopFactory *event_loop_factory_ = nullptr; |
| 101 | std::unique_ptr<EventLoop> event_loop_unique_ptr_; |
| 102 | EventLoop *event_loop_ = nullptr; |
Austin Schuh | e309d2a | 2019-11-29 13:25:21 -0800 | [diff] [blame] | 103 | TimerHandler *timer_handler_; |
Austin Schuh | e309d2a | 2019-11-29 13:25:21 -0800 | [diff] [blame] | 104 | }; |
| 105 | |
| 106 | } // namespace logger |
| 107 | } // namespace aos |
| 108 | |
| 109 | #endif // AOS_EVENTS_LOGGER_H_ |