blob: c2c8dd1f62f9351d10e39cf048121018de8b252a [file] [log] [blame]
Austin Schuhcb5601b2020-09-10 15:29:59 -07001#ifndef AOS_EVENTS_LOGGING_LOG_NAMER_H_
2#define AOS_EVENTS_LOGGING_LOG_NAMER_H_
3
4#include <functional>
5#include <map>
6#include <memory>
7#include <string_view>
8#include <vector>
9
10#include "aos/events/logging/logfile_utils.h"
11#include "aos/events/logging/logger_generated.h"
Austin Schuh4385b142021-03-14 21:31:13 -070012#include "aos/uuid.h"
Austin Schuhcb5601b2020-09-10 15:29:59 -070013#include "flatbuffers/flatbuffers.h"
14
15namespace aos {
16namespace logger {
17
Austin Schuh572924a2021-07-30 22:32:12 -070018class LogNamer;
19
Austin Schuhb8bca732021-07-30 22:32:00 -070020// TODO(austin): Rename this back to DataWriter once all other callers are of
21// the old DataWriter.
Austin Schuh572924a2021-07-30 22:32:12 -070022//
23// Class to manage writing data to log files. This lets us track which boot the
24// written header has in it, and if the header has been written or not.
Austin Schuhb8bca732021-07-30 22:32:00 -070025class NewDataWriter {
26 public:
27 // Constructs a NewDataWriter.
Austin Schuh572924a2021-07-30 22:32:12 -070028 // log_namer is the log namer which holds the config and any other data we
29 // need for our header.
30 // node is the node whom's prespective we are logging from.
Austin Schuhb8bca732021-07-30 22:32:00 -070031 // reopen is called whenever a file needs to be reopened.
32 // close is called to close that file and extract any statistics.
Austin Schuh572924a2021-07-30 22:32:12 -070033 NewDataWriter(LogNamer *log_namer, const Node *node,
34 std::function<void(NewDataWriter *)> reopen,
35 std::function<void(NewDataWriter *)> close);
Austin Schuhb8bca732021-07-30 22:32:00 -070036
37 NewDataWriter(NewDataWriter &&other) = default;
38 aos::logger::NewDataWriter &operator=(NewDataWriter &&other) = default;
39 NewDataWriter(const NewDataWriter &) = delete;
40 void operator=(const NewDataWriter &) = delete;
41
Austin Schuh572924a2021-07-30 22:32:12 -070042 ~NewDataWriter();
Austin Schuhb8bca732021-07-30 22:32:00 -070043
Austin Schuh572924a2021-07-30 22:32:12 -070044 // Rotates the log file, delaying writing the new header until data arrives.
45 void Rotate();
Austin Schuhb8bca732021-07-30 22:32:00 -070046
Austin Schuh72211ae2021-08-05 14:02:30 -070047 void UpdateRemote(size_t remote_node_index, const UUID &remote_node_boot_uuid,
48 monotonic_clock::time_point monotonic_remote_time,
49 monotonic_clock::time_point monotonic_event_time,
50 bool reliable);
Austin Schuh572924a2021-07-30 22:32:12 -070051 // Queues up a message with the provided boot UUID.
Austin Schuhe46492f2021-07-31 19:49:41 -070052 void QueueMessage(flatbuffers::FlatBufferBuilder *fbb,
53 const UUID &node_boot_uuid,
54 aos::monotonic_clock::time_point now);
Austin Schuhb8bca732021-07-30 22:32:00 -070055
Austin Schuh572924a2021-07-30 22:32:12 -070056 // Returns the filename of the writer.
Austin Schuhb8bca732021-07-30 22:32:00 -070057 std::string_view filename() const { return writer->filename(); }
58
Austin Schuh572924a2021-07-30 22:32:12 -070059 void Close();
Austin Schuhb8bca732021-07-30 22:32:00 -070060
61 std::unique_ptr<DetachedBufferWriter> writer = nullptr;
Austin Schuh572924a2021-07-30 22:32:12 -070062
63 size_t node_index() const { return node_index_; }
64 const UUID &parts_uuid() const { return parts_uuid_; }
65 size_t parts_index() const { return parts_index_; }
66 const Node *node() const { return node_; }
Austin Schuhb8bca732021-07-30 22:32:00 -070067
Austin Schuh72211ae2021-08-05 14:02:30 -070068 // Datastructure used to capture all the information about a remote node.
69 struct State {
70 // Boot UUID of the node.
71 UUID boot_uuid = UUID::Zero();
72 // Timestamp on the remote monotonic clock of the oldest message sent to
73 // node_index_.
74 monotonic_clock::time_point oldest_remote_monotonic_timestamp =
75 monotonic_clock::max_time;
76 // Timestamp on the local monotonic clock of the message in
77 // oldest_remote_monotonic_timestamp.
78 monotonic_clock::time_point oldest_local_monotonic_timestamp =
79 monotonic_clock::max_time;
80 // Timestamp on the remote monotonic clock of the oldest message sent to
81 // node_index_, excluding messages forwarded with time_to_live() == 0.
82 monotonic_clock::time_point oldest_remote_unreliable_monotonic_timestamp =
83 monotonic_clock::max_time;
84 // Timestamp on the local monotonic clock of the message in
85 // oldest_local_unreliable_monotonic_timestamp.
86 monotonic_clock::time_point oldest_local_unreliable_monotonic_timestamp =
87 monotonic_clock::max_time;
88 };
89
Austin Schuhb8bca732021-07-30 22:32:00 -070090 private:
Austin Schuhe46492f2021-07-31 19:49:41 -070091 // Signals that a node has rebooted.
92 void Reboot();
93
Austin Schuh572924a2021-07-30 22:32:12 -070094 void QueueHeader(
95 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> &&header);
96
Austin Schuhe46492f2021-07-31 19:49:41 -070097 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> MakeHeader();
98
Austin Schuh572924a2021-07-30 22:32:12 -070099 const Node *const node_ = nullptr;
Austin Schuhe46492f2021-07-31 19:49:41 -0700100 const size_t node_index_ = 0;
Austin Schuh572924a2021-07-30 22:32:12 -0700101 LogNamer *log_namer_;
102 UUID parts_uuid_ = UUID::Random();
103 size_t parts_index_ = 0;
104
Austin Schuhb8bca732021-07-30 22:32:00 -0700105 std::function<void(NewDataWriter *)> reopen_;
106 std::function<void(NewDataWriter *)> close_;
Austin Schuh572924a2021-07-30 22:32:12 -0700107 bool header_written_ = false;
Austin Schuhe46492f2021-07-31 19:49:41 -0700108
Austin Schuh72211ae2021-08-05 14:02:30 -0700109 std::vector<State> state_;
Austin Schuhb8bca732021-07-30 22:32:00 -0700110};
111
Austin Schuhcb5601b2020-09-10 15:29:59 -0700112// Interface describing how to name, track, and add headers to log file parts.
113class LogNamer {
114 public:
115 // Constructs a LogNamer with the primary node (ie the one the logger runs on)
116 // being node.
Austin Schuh5b728b72021-06-16 14:57:15 -0700117 LogNamer(const aos::Configuration *configuration, EventLoop *event_loop,
118 const aos::Node *node)
Austin Schuha499cea2021-07-31 19:49:53 -0700119 : event_loop_(event_loop),
Austin Schuh5b728b72021-06-16 14:57:15 -0700120 configuration_(configuration),
121 node_(node),
Austin Schuha499cea2021-07-31 19:49:53 -0700122 logger_node_index_(configuration::GetNodeIndex(configuration_, node_)) {
Austin Schuh73340842021-07-30 22:32:06 -0700123 nodes_.emplace_back(node_);
124 node_states_.resize(configuration::NodesCount(configuration_));
125 }
Austin Schuhcb5601b2020-09-10 15:29:59 -0700126 virtual ~LogNamer() {}
127
Austin Schuh6bb8a822021-03-31 23:04:39 -0700128 virtual std::string_view base_name() const = 0;
129
130 // Rotate should be called at least once in between calls to set_base_name.
131 // Otherwise temporary files will not be recoverable.
132 // Rotate is called by Logger::RenameLogBase, which is currently the only user
133 // of this method.
134 // Only renaming the folder is supported, not the file base name.
135 virtual void set_base_name(std::string_view base_name) = 0;
136
Brian Silverman87ac0402020-09-17 14:47:01 -0700137 // Returns a writer for writing data from messages on this channel (on the
138 // primary node).
139 //
140 // The returned pointer will stay valid across rotations, but the object it
141 // points to will be assigned to.
Austin Schuhb8bca732021-07-30 22:32:00 -0700142 virtual NewDataWriter *MakeWriter(const Channel *channel) = 0;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700143
Brian Silverman87ac0402020-09-17 14:47:01 -0700144 // Returns a writer for writing timestamps from messages on this channel (on
145 // the primary node).
146 //
147 // The returned pointer will stay valid across rotations, but the object it
148 // points to will be assigned to.
Austin Schuhb8bca732021-07-30 22:32:00 -0700149 virtual NewDataWriter *MakeTimestampWriter(const Channel *channel) = 0;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700150
151 // Returns a writer for writing timestamps delivered over the special
152 // /aos/remote_timestamps/* channels. node is the node that the timestamps
Brian Silverman87ac0402020-09-17 14:47:01 -0700153 // are forwarded back from (to the primary node).
154 //
155 // The returned pointer will stay valid across rotations, but the object it
156 // points to will be assigned to.
Austin Schuh73340842021-07-30 22:32:06 -0700157 virtual NewDataWriter *MakeForwardedTimestampWriter(const Channel *channel,
158 const Node *node) = 0;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700159
Austin Schuh73340842021-07-30 22:32:06 -0700160 // Rotates all log files for the provided node.
161 virtual void Rotate(const Node *node) = 0;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700162
163 // Returns all the nodes that data is being written for.
164 const std::vector<const Node *> &nodes() const { return nodes_; }
165
166 // Returns the node the logger is running on.
167 const Node *node() const { return node_; }
Austin Schuhe46492f2021-07-31 19:49:41 -0700168 const UUID &logger_node_boot_uuid() const { return logger_node_boot_uuid_; }
169 size_t logger_node_index() const { return logger_node_index_; }
Austin Schuhcb5601b2020-09-10 15:29:59 -0700170
Austin Schuh8c399962020-12-25 21:51:45 -0800171 // Writes out the nested Configuration object to the config file location.
172 virtual void WriteConfiguration(
173 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> *header,
174 std::string_view config_sha256) = 0;
175
Austin Schuh73340842021-07-30 22:32:06 -0700176 void SetHeaderTemplate(
177 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> header) {
178 header_ = std::move(header);
Austin Schuhe46492f2021-07-31 19:49:41 -0700179 logger_node_boot_uuid_ =
180 UUID::FromString(header_.message().logger_node_boot_uuid());
Austin Schuh73340842021-07-30 22:32:06 -0700181 }
Austin Schuhcb5601b2020-09-10 15:29:59 -0700182
Austin Schuh73340842021-07-30 22:32:06 -0700183 void SetStartTimes(size_t node_index,
184 monotonic_clock::time_point monotonic_start_time,
185 realtime_clock::time_point realtime_start_time,
186 monotonic_clock::time_point logger_monotonic_start_time,
187 realtime_clock::time_point logger_realtime_start_time) {
188 node_states_[node_index].monotonic_start_time = monotonic_start_time;
189 node_states_[node_index].realtime_start_time = realtime_start_time;
190 node_states_[node_index].logger_monotonic_start_time =
191 logger_monotonic_start_time;
192 node_states_[node_index].logger_realtime_start_time =
193 logger_realtime_start_time;
Austin Schuh572924a2021-07-30 22:32:12 -0700194
Austin Schuh73340842021-07-30 22:32:06 -0700195 // TODO(austin): Track that the header has changed and needs to be
Austin Schuh572924a2021-07-30 22:32:12 -0700196 // rewritten down here rather than up in log_writer.
Austin Schuh73340842021-07-30 22:32:06 -0700197 }
198
199 monotonic_clock::time_point monotonic_start_time(size_t node_index) const {
200 return node_states_[node_index].monotonic_start_time;
201 }
202
Austin Schuh73340842021-07-30 22:32:06 -0700203 protected:
204 // Creates a new header by copying fields out of the template and combining
205 // them with the arguments provided.
206 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> MakeHeader(
Austin Schuh72211ae2021-08-05 14:02:30 -0700207 size_t node_index, const std::vector<NewDataWriter::State> &state,
Austin Schuh73340842021-07-30 22:32:06 -0700208 const UUID &parts_uuid, int parts_index) const;
209
Austin Schuha499cea2021-07-31 19:49:53 -0700210 EventLoop *event_loop_;
Austin Schuh73340842021-07-30 22:32:06 -0700211 const Configuration *const configuration_;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700212 const Node *const node_;
Austin Schuhe46492f2021-07-31 19:49:41 -0700213 const size_t logger_node_index_;
214 UUID logger_node_boot_uuid_;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700215 std::vector<const Node *> nodes_;
Austin Schuh73340842021-07-30 22:32:06 -0700216
Austin Schuh572924a2021-07-30 22:32:12 -0700217 friend NewDataWriter;
218
Austin Schuh73340842021-07-30 22:32:06 -0700219 // Structure with state per node about times and such.
220 // TODO(austin): some of this lives better in NewDataWriter once we move
221 // ownership of deciding when to write headers into LogNamer.
222 struct NodeState {
223 // Time when this node started logging.
224 monotonic_clock::time_point monotonic_start_time =
225 monotonic_clock::min_time;
226 realtime_clock::time_point realtime_start_time = realtime_clock::min_time;
227
228 // Corresponding time on the logger node when it started logging.
229 monotonic_clock::time_point logger_monotonic_start_time =
230 monotonic_clock::min_time;
231 realtime_clock::time_point logger_realtime_start_time =
232 realtime_clock::min_time;
Austin Schuh73340842021-07-30 22:32:06 -0700233 };
234 std::vector<NodeState> node_states_;
235
236 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> header_ =
237 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader>::Empty();
Austin Schuhcb5601b2020-09-10 15:29:59 -0700238};
239
240// Local log namer is a simple version which only names things
241// "base_name.part#.bfbs" and increments the part number. It doesn't support
242// any other log type.
243class LocalLogNamer : public LogNamer {
244 public:
Austin Schuh5b728b72021-06-16 14:57:15 -0700245 LocalLogNamer(std::string_view base_name, aos::EventLoop *event_loop,
246 const aos::Node *node)
247 : LogNamer(event_loop->configuration(), event_loop, node),
Austin Schuhcb5601b2020-09-10 15:29:59 -0700248 base_name_(base_name),
Austin Schuh5b728b72021-06-16 14:57:15 -0700249 data_writer_(this, node,
Austin Schuh572924a2021-07-30 22:32:12 -0700250 [this](NewDataWriter *writer) {
251 writer->writer = std::make_unique<DetachedBufferWriter>(
252 absl::StrCat(base_name_, ".part",
253 writer->parts_index(), ".bfbs"),
254 std::make_unique<aos::logger::DummyEncoder>());
255 },
256 [](NewDataWriter * /*writer*/) {}) {}
Austin Schuhb8bca732021-07-30 22:32:00 -0700257
258 LocalLogNamer(const LocalLogNamer &) = delete;
259 LocalLogNamer(LocalLogNamer &&) = delete;
260 LocalLogNamer &operator=(const LocalLogNamer &) = delete;
261 LocalLogNamer &operator=(LocalLogNamer &&) = delete;
262
Brian Silverman0465fcf2020-09-24 00:29:18 -0700263 ~LocalLogNamer() override = default;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700264
Austin Schuh6bb8a822021-03-31 23:04:39 -0700265 std::string_view base_name() const final { return base_name_; }
266
267 void set_base_name(std::string_view base_name) final {
268 base_name_ = base_name;
269 }
270
Austin Schuhb8bca732021-07-30 22:32:00 -0700271 NewDataWriter *MakeWriter(const Channel *channel) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700272
Austin Schuh73340842021-07-30 22:32:06 -0700273 void Rotate(const Node *node) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700274
Austin Schuhb8bca732021-07-30 22:32:00 -0700275 NewDataWriter *MakeTimestampWriter(const Channel *channel) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700276
Austin Schuh73340842021-07-30 22:32:06 -0700277 NewDataWriter *MakeForwardedTimestampWriter(const Channel * /*channel*/,
278 const Node * /*node*/) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700279
Austin Schuh8c399962020-12-25 21:51:45 -0800280 void WriteConfiguration(
281 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> *header,
282 std::string_view config_sha256) override;
283
Austin Schuhcb5601b2020-09-10 15:29:59 -0700284 private:
Austin Schuh6bb8a822021-03-31 23:04:39 -0700285 std::string base_name_;
Austin Schuhb8bca732021-07-30 22:32:00 -0700286
287 NewDataWriter data_writer_;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700288};
289
290// Log namer which uses a config and a base name to name a bunch of files.
291class MultiNodeLogNamer : public LogNamer {
292 public:
Austin Schuha499cea2021-07-31 19:49:53 -0700293 MultiNodeLogNamer(std::string_view base_name, EventLoop *event_loop);
Austin Schuh5b728b72021-06-16 14:57:15 -0700294 MultiNodeLogNamer(std::string_view base_name,
295 const Configuration *configuration, EventLoop *event_loop,
296 const Node *node);
Brian Silvermancb805822020-10-06 17:43:35 -0700297 ~MultiNodeLogNamer() override;
298
Austin Schuh6bb8a822021-03-31 23:04:39 -0700299 std::string_view base_name() const final { return base_name_; }
300
301 void set_base_name(std::string_view base_name) final {
302 old_base_name_ = base_name_;
303 base_name_ = base_name;
304 }
Brian Silvermancb805822020-10-06 17:43:35 -0700305
Brian Silverman48deab12020-09-30 18:39:28 -0700306 // If temp_suffix is set, then this will write files under names beginning
307 // with the specified suffix, and then rename them to the desired name after
308 // they are fully written.
309 //
310 // This is useful to enable incremental copying of the log files.
311 //
312 // Defaults to writing directly to the final filename.
Brian Silvermancb805822020-10-06 17:43:35 -0700313 void set_temp_suffix(std::string_view temp_suffix) {
314 temp_suffix_ = temp_suffix;
315 }
Austin Schuhcb5601b2020-09-10 15:29:59 -0700316
Brian Silvermancb805822020-10-06 17:43:35 -0700317 // Sets the function for creating encoders.
318 //
319 // Defaults to just creating DummyEncoders.
320 void set_encoder_factory(
321 std::function<std::unique_ptr<DetachedBufferEncoder>()> encoder_factory) {
322 encoder_factory_ = std::move(encoder_factory);
323 }
324
325 // Sets an additional file extension.
326 //
327 // Defaults to nothing.
328 void set_extension(std::string_view extension) { extension_ = extension; }
Brian Silverman1f345222020-09-24 21:14:48 -0700329
Brian Silvermana621f522020-09-30 16:52:43 -0700330 // A list of all the filenames we've written.
331 //
332 // This only includes the part after base_name().
333 const std::vector<std::string> &all_filenames() const {
334 return all_filenames_;
335 }
336
Austin Schuh73340842021-07-30 22:32:06 -0700337 void Rotate(const Node *node) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700338
Austin Schuh8c399962020-12-25 21:51:45 -0800339 void WriteConfiguration(
340 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> *header,
341 std::string_view config_sha256) override;
342
Austin Schuhb8bca732021-07-30 22:32:00 -0700343 NewDataWriter *MakeWriter(const Channel *channel) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700344
Austin Schuhb8bca732021-07-30 22:32:00 -0700345 NewDataWriter *MakeForwardedTimestampWriter(const Channel *channel,
Austin Schuh73340842021-07-30 22:32:06 -0700346 const Node *node) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700347
Austin Schuhb8bca732021-07-30 22:32:00 -0700348 NewDataWriter *MakeTimestampWriter(const Channel *channel) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700349
Brian Silverman0465fcf2020-09-24 00:29:18 -0700350 // Indicates that at least one file ran out of space. Once this happens, we
351 // stop trying to open new files, to avoid writing any files with holes from
352 // previous parts.
353 //
354 // Besides this function, this object will silently stop logging data when
355 // this occurs. If you want to ensure log files are complete, you must call
356 // this method.
Brian Silvermana9f2ec92020-10-06 18:00:53 -0700357 bool ran_out_of_space() const {
358 return accumulate_data_writers<bool>(
Austin Schuhb8bca732021-07-30 22:32:00 -0700359 ran_out_of_space_, [](bool x, const NewDataWriter &data_writer) {
Brian Silvermana9f2ec92020-10-06 18:00:53 -0700360 return x ||
361 (data_writer.writer && data_writer.writer->ran_out_of_space());
362 });
363 }
Brian Silverman0465fcf2020-09-24 00:29:18 -0700364
Brian Silverman1f345222020-09-24 21:14:48 -0700365 // Returns the maximum total_bytes() value for all existing
366 // DetachedBufferWriters.
367 //
368 // Returns 0 if no files are open.
369 size_t maximum_total_bytes() const {
Brian Silvermancb805822020-10-06 17:43:35 -0700370 return accumulate_data_writers<size_t>(
Austin Schuhb8bca732021-07-30 22:32:00 -0700371 0, [](size_t x, const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700372 return std::max(x, data_writer.writer->total_bytes());
373 });
Brian Silverman1f345222020-09-24 21:14:48 -0700374 }
375
Brian Silverman0465fcf2020-09-24 00:29:18 -0700376 // Closes all existing log files. No more data may be written after this.
377 //
378 // This may set ran_out_of_space().
379 void Close();
380
Brian Silvermancb805822020-10-06 17:43:35 -0700381 // Accessors for various statistics. See the identically-named methods in
382 // DetachedBufferWriter for documentation. These are aggregated across all
383 // past and present DetachedBufferWriters.
384 std::chrono::nanoseconds max_write_time() const {
385 return accumulate_data_writers(
386 max_write_time_,
Austin Schuhb8bca732021-07-30 22:32:00 -0700387 [](std::chrono::nanoseconds x, const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700388 return std::max(x, data_writer.writer->max_write_time());
389 });
390 }
391 int max_write_time_bytes() const {
392 return std::get<0>(accumulate_data_writers(
393 std::make_tuple(max_write_time_bytes_, max_write_time_),
394 [](std::tuple<int, std::chrono::nanoseconds> x,
Austin Schuhb8bca732021-07-30 22:32:00 -0700395 const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700396 if (data_writer.writer->max_write_time() > std::get<1>(x)) {
397 return std::make_tuple(data_writer.writer->max_write_time_bytes(),
398 data_writer.writer->max_write_time());
399 }
400 return x;
401 }));
402 }
403 int max_write_time_messages() const {
404 return std::get<0>(accumulate_data_writers(
405 std::make_tuple(max_write_time_messages_, max_write_time_),
406 [](std::tuple<int, std::chrono::nanoseconds> x,
Austin Schuhb8bca732021-07-30 22:32:00 -0700407 const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700408 if (data_writer.writer->max_write_time() > std::get<1>(x)) {
409 return std::make_tuple(
410 data_writer.writer->max_write_time_messages(),
411 data_writer.writer->max_write_time());
412 }
413 return x;
414 }));
415 }
416 std::chrono::nanoseconds total_write_time() const {
417 return accumulate_data_writers(
418 total_write_time_,
Austin Schuhb8bca732021-07-30 22:32:00 -0700419 [](std::chrono::nanoseconds x, const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700420 return x + data_writer.writer->total_write_time();
421 });
422 }
423 int total_write_count() const {
424 return accumulate_data_writers(
Austin Schuhb8bca732021-07-30 22:32:00 -0700425 total_write_count_, [](int x, const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700426 return x + data_writer.writer->total_write_count();
427 });
428 }
429 int total_write_messages() const {
430 return accumulate_data_writers(
Austin Schuhb8bca732021-07-30 22:32:00 -0700431 total_write_messages_, [](int x, const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700432 return x + data_writer.writer->total_write_messages();
433 });
434 }
435 int total_write_bytes() const {
436 return accumulate_data_writers(
Austin Schuhb8bca732021-07-30 22:32:00 -0700437 total_write_bytes_, [](int x, const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700438 return x + data_writer.writer->total_write_bytes();
439 });
440 }
441
442 void ResetStatistics();
443
Austin Schuhcb5601b2020-09-10 15:29:59 -0700444 private:
Austin Schuhcb5601b2020-09-10 15:29:59 -0700445 // Opens up a writer for timestamps forwarded back.
446 void OpenForwardedTimestampWriter(const Channel *channel,
Austin Schuhb8bca732021-07-30 22:32:00 -0700447 NewDataWriter *data_writer);
Austin Schuhcb5601b2020-09-10 15:29:59 -0700448
449 // Opens up a writer for remote data.
Austin Schuhb8bca732021-07-30 22:32:00 -0700450 void OpenWriter(const Channel *channel, NewDataWriter *data_writer);
Austin Schuhcb5601b2020-09-10 15:29:59 -0700451
452 // Opens the main data writer file for this node responsible for data_writer_.
Brian Silvermana621f522020-09-30 16:52:43 -0700453 void OpenDataWriter();
Austin Schuhcb5601b2020-09-10 15:29:59 -0700454
Brian Silvermana621f522020-09-30 16:52:43 -0700455 void CreateBufferWriter(std::string_view path,
Brian Silverman0465fcf2020-09-24 00:29:18 -0700456 std::unique_ptr<DetachedBufferWriter> *destination);
457
Brian Silverman48deab12020-09-30 18:39:28 -0700458 void RenameTempFile(DetachedBufferWriter *destination);
459
Brian Silvermancb805822020-10-06 17:43:35 -0700460 void CloseWriter(std::unique_ptr<DetachedBufferWriter> *writer_pointer);
Austin Schuhcb5601b2020-09-10 15:29:59 -0700461
Brian Silvermancb805822020-10-06 17:43:35 -0700462 // A version of std::accumulate which operates over all of our DataWriters.
463 template <typename T, typename BinaryOperation>
464 T accumulate_data_writers(T t, BinaryOperation op) const {
Austin Schuhb8bca732021-07-30 22:32:00 -0700465 for (const std::pair<const Channel *const, NewDataWriter> &data_writer :
Brian Silvermancb805822020-10-06 17:43:35 -0700466 data_writers_) {
Austin Schuhad0cfc32020-12-21 12:34:26 -0800467 if (!data_writer.second.writer) continue;
Brian Silvermancb805822020-10-06 17:43:35 -0700468 t = op(std::move(t), data_writer.second);
469 }
Austin Schuhb8bca732021-07-30 22:32:00 -0700470 if (data_writer_) {
471 t = op(std::move(t), *data_writer_);
Brian Silvermancb805822020-10-06 17:43:35 -0700472 }
473 return t;
474 }
475
Austin Schuh6bb8a822021-03-31 23:04:39 -0700476 std::string base_name_;
477 std::string old_base_name_;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700478
Brian Silverman0465fcf2020-09-24 00:29:18 -0700479 bool ran_out_of_space_ = false;
Brian Silvermana621f522020-09-30 16:52:43 -0700480 std::vector<std::string> all_filenames_;
Brian Silverman0465fcf2020-09-24 00:29:18 -0700481
Brian Silvermancb805822020-10-06 17:43:35 -0700482 std::string temp_suffix_;
483 std::function<std::unique_ptr<DetachedBufferEncoder>()> encoder_factory_ =
484 []() { return std::make_unique<DummyEncoder>(); };
485 std::string extension_;
486
487 // Storage for statistics from previously-rotated DetachedBufferWriters.
488 std::chrono::nanoseconds max_write_time_ = std::chrono::nanoseconds::zero();
489 int max_write_time_bytes_ = -1;
490 int max_write_time_messages_ = -1;
491 std::chrono::nanoseconds total_write_time_ = std::chrono::nanoseconds::zero();
492 int total_write_count_ = 0;
493 int total_write_messages_ = 0;
494 int total_write_bytes_ = 0;
495
Austin Schuhcb5601b2020-09-10 15:29:59 -0700496 // File to write both delivery timestamps and local data to.
Austin Schuhb8bca732021-07-30 22:32:00 -0700497 std::unique_ptr<NewDataWriter> data_writer_;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700498
Austin Schuhb8bca732021-07-30 22:32:00 -0700499 std::map<const Channel *, NewDataWriter> data_writers_;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700500};
501
502} // namespace logger
503} // namespace aos
504
505#endif // AOS_EVENTS_LOGGING_LOG_NAMER_H_