blob: 8a44c97837d7032fcce892a93744016f6a307427 [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 Schuha499cea2021-07-31 19:49:53 -0700117 LogNamer(EventLoop *event_loop)
118 : event_loop_(event_loop),
119 configuration_(event_loop_->configuration()),
120 node_(event_loop_->node()),
121 logger_node_index_(configuration::GetNodeIndex(configuration_, node_)) {
Austin Schuh73340842021-07-30 22:32:06 -0700122 nodes_.emplace_back(node_);
123 node_states_.resize(configuration::NodesCount(configuration_));
124 }
Austin Schuhcb5601b2020-09-10 15:29:59 -0700125 virtual ~LogNamer() {}
126
Austin Schuh6bb8a822021-03-31 23:04:39 -0700127 virtual std::string_view base_name() const = 0;
128
129 // Rotate should be called at least once in between calls to set_base_name.
130 // Otherwise temporary files will not be recoverable.
131 // Rotate is called by Logger::RenameLogBase, which is currently the only user
132 // of this method.
133 // Only renaming the folder is supported, not the file base name.
134 virtual void set_base_name(std::string_view base_name) = 0;
135
Brian Silverman87ac0402020-09-17 14:47:01 -0700136 // Returns a writer for writing data from messages on this channel (on the
137 // primary node).
138 //
139 // The returned pointer will stay valid across rotations, but the object it
140 // points to will be assigned to.
Austin Schuhb8bca732021-07-30 22:32:00 -0700141 virtual NewDataWriter *MakeWriter(const Channel *channel) = 0;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700142
Brian Silverman87ac0402020-09-17 14:47:01 -0700143 // Returns a writer for writing timestamps from messages on this channel (on
144 // the primary node).
145 //
146 // The returned pointer will stay valid across rotations, but the object it
147 // points to will be assigned to.
Austin Schuhb8bca732021-07-30 22:32:00 -0700148 virtual NewDataWriter *MakeTimestampWriter(const Channel *channel) = 0;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700149
150 // Returns a writer for writing timestamps delivered over the special
151 // /aos/remote_timestamps/* channels. node is the node that the timestamps
Brian Silverman87ac0402020-09-17 14:47:01 -0700152 // are forwarded back from (to the primary node).
153 //
154 // The returned pointer will stay valid across rotations, but the object it
155 // points to will be assigned to.
Austin Schuh73340842021-07-30 22:32:06 -0700156 virtual NewDataWriter *MakeForwardedTimestampWriter(const Channel *channel,
157 const Node *node) = 0;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700158
Austin Schuh73340842021-07-30 22:32:06 -0700159 // Rotates all log files for the provided node.
160 virtual void Rotate(const Node *node) = 0;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700161
162 // Returns all the nodes that data is being written for.
163 const std::vector<const Node *> &nodes() const { return nodes_; }
164
165 // Returns the node the logger is running on.
166 const Node *node() const { return node_; }
Austin Schuhe46492f2021-07-31 19:49:41 -0700167 const UUID &logger_node_boot_uuid() const { return logger_node_boot_uuid_; }
168 size_t logger_node_index() const { return logger_node_index_; }
Austin Schuhcb5601b2020-09-10 15:29:59 -0700169
Austin Schuh8c399962020-12-25 21:51:45 -0800170 // Writes out the nested Configuration object to the config file location.
171 virtual void WriteConfiguration(
172 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> *header,
173 std::string_view config_sha256) = 0;
174
Austin Schuh73340842021-07-30 22:32:06 -0700175 void SetHeaderTemplate(
176 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> header) {
177 header_ = std::move(header);
Austin Schuhe46492f2021-07-31 19:49:41 -0700178 logger_node_boot_uuid_ =
179 UUID::FromString(header_.message().logger_node_boot_uuid());
Austin Schuh73340842021-07-30 22:32:06 -0700180 }
Austin Schuhcb5601b2020-09-10 15:29:59 -0700181
Austin Schuh73340842021-07-30 22:32:06 -0700182 void SetStartTimes(size_t node_index,
183 monotonic_clock::time_point monotonic_start_time,
184 realtime_clock::time_point realtime_start_time,
185 monotonic_clock::time_point logger_monotonic_start_time,
186 realtime_clock::time_point logger_realtime_start_time) {
187 node_states_[node_index].monotonic_start_time = monotonic_start_time;
188 node_states_[node_index].realtime_start_time = realtime_start_time;
189 node_states_[node_index].logger_monotonic_start_time =
190 logger_monotonic_start_time;
191 node_states_[node_index].logger_realtime_start_time =
192 logger_realtime_start_time;
Austin Schuh572924a2021-07-30 22:32:12 -0700193
Austin Schuh73340842021-07-30 22:32:06 -0700194 // TODO(austin): Track that the header has changed and needs to be
Austin Schuh572924a2021-07-30 22:32:12 -0700195 // rewritten down here rather than up in log_writer.
Austin Schuh73340842021-07-30 22:32:06 -0700196 }
197
198 monotonic_clock::time_point monotonic_start_time(size_t node_index) const {
199 return node_states_[node_index].monotonic_start_time;
200 }
201
Austin Schuh73340842021-07-30 22:32:06 -0700202 protected:
203 // Creates a new header by copying fields out of the template and combining
204 // them with the arguments provided.
205 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> MakeHeader(
Austin Schuh72211ae2021-08-05 14:02:30 -0700206 size_t node_index, const std::vector<NewDataWriter::State> &state,
Austin Schuh73340842021-07-30 22:32:06 -0700207 const UUID &parts_uuid, int parts_index) const;
208
Austin Schuha499cea2021-07-31 19:49:53 -0700209 EventLoop *event_loop_;
Austin Schuh73340842021-07-30 22:32:06 -0700210 const Configuration *const configuration_;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700211 const Node *const node_;
Austin Schuhe46492f2021-07-31 19:49:41 -0700212 const size_t logger_node_index_;
213 UUID logger_node_boot_uuid_;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700214 std::vector<const Node *> nodes_;
Austin Schuh73340842021-07-30 22:32:06 -0700215
Austin Schuh572924a2021-07-30 22:32:12 -0700216 friend NewDataWriter;
217
Austin Schuh73340842021-07-30 22:32:06 -0700218 // Structure with state per node about times and such.
219 // TODO(austin): some of this lives better in NewDataWriter once we move
220 // ownership of deciding when to write headers into LogNamer.
221 struct NodeState {
222 // Time when this node started logging.
223 monotonic_clock::time_point monotonic_start_time =
224 monotonic_clock::min_time;
225 realtime_clock::time_point realtime_start_time = realtime_clock::min_time;
226
227 // Corresponding time on the logger node when it started logging.
228 monotonic_clock::time_point logger_monotonic_start_time =
229 monotonic_clock::min_time;
230 realtime_clock::time_point logger_realtime_start_time =
231 realtime_clock::min_time;
Austin Schuh73340842021-07-30 22:32:06 -0700232 };
233 std::vector<NodeState> node_states_;
234
235 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> header_ =
236 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader>::Empty();
Austin Schuhcb5601b2020-09-10 15:29:59 -0700237};
238
239// Local log namer is a simple version which only names things
240// "base_name.part#.bfbs" and increments the part number. It doesn't support
241// any other log type.
242class LocalLogNamer : public LogNamer {
243 public:
Austin Schuha499cea2021-07-31 19:49:53 -0700244 LocalLogNamer(std::string_view base_name, aos::EventLoop *event_loop)
245 : LogNamer(event_loop),
Austin Schuhcb5601b2020-09-10 15:29:59 -0700246 base_name_(base_name),
Austin Schuha499cea2021-07-31 19:49:53 -0700247 data_writer_(this, node(),
Austin Schuh572924a2021-07-30 22:32:12 -0700248 [this](NewDataWriter *writer) {
249 writer->writer = std::make_unique<DetachedBufferWriter>(
250 absl::StrCat(base_name_, ".part",
251 writer->parts_index(), ".bfbs"),
252 std::make_unique<aos::logger::DummyEncoder>());
253 },
254 [](NewDataWriter * /*writer*/) {}) {}
Austin Schuhb8bca732021-07-30 22:32:00 -0700255
256 LocalLogNamer(const LocalLogNamer &) = delete;
257 LocalLogNamer(LocalLogNamer &&) = delete;
258 LocalLogNamer &operator=(const LocalLogNamer &) = delete;
259 LocalLogNamer &operator=(LocalLogNamer &&) = delete;
260
Brian Silverman0465fcf2020-09-24 00:29:18 -0700261 ~LocalLogNamer() override = default;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700262
Austin Schuh6bb8a822021-03-31 23:04:39 -0700263 std::string_view base_name() const final { return base_name_; }
264
265 void set_base_name(std::string_view base_name) final {
266 base_name_ = base_name;
267 }
268
Austin Schuhb8bca732021-07-30 22:32:00 -0700269 NewDataWriter *MakeWriter(const Channel *channel) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700270
Austin Schuh73340842021-07-30 22:32:06 -0700271 void Rotate(const Node *node) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700272
Austin Schuhb8bca732021-07-30 22:32:00 -0700273 NewDataWriter *MakeTimestampWriter(const Channel *channel) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700274
Austin Schuh73340842021-07-30 22:32:06 -0700275 NewDataWriter *MakeForwardedTimestampWriter(const Channel * /*channel*/,
276 const Node * /*node*/) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700277
Austin Schuh8c399962020-12-25 21:51:45 -0800278 void WriteConfiguration(
279 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> *header,
280 std::string_view config_sha256) override;
281
Austin Schuhcb5601b2020-09-10 15:29:59 -0700282 private:
Austin Schuh6bb8a822021-03-31 23:04:39 -0700283 std::string base_name_;
Austin Schuhb8bca732021-07-30 22:32:00 -0700284
285 NewDataWriter data_writer_;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700286};
287
288// Log namer which uses a config and a base name to name a bunch of files.
289class MultiNodeLogNamer : public LogNamer {
290 public:
Austin Schuha499cea2021-07-31 19:49:53 -0700291 MultiNodeLogNamer(std::string_view base_name, EventLoop *event_loop);
Brian Silvermancb805822020-10-06 17:43:35 -0700292 ~MultiNodeLogNamer() override;
293
Austin Schuh6bb8a822021-03-31 23:04:39 -0700294 std::string_view base_name() const final { return base_name_; }
295
296 void set_base_name(std::string_view base_name) final {
297 old_base_name_ = base_name_;
298 base_name_ = base_name;
299 }
Brian Silvermancb805822020-10-06 17:43:35 -0700300
Brian Silverman48deab12020-09-30 18:39:28 -0700301 // If temp_suffix is set, then this will write files under names beginning
302 // with the specified suffix, and then rename them to the desired name after
303 // they are fully written.
304 //
305 // This is useful to enable incremental copying of the log files.
306 //
307 // Defaults to writing directly to the final filename.
Brian Silvermancb805822020-10-06 17:43:35 -0700308 void set_temp_suffix(std::string_view temp_suffix) {
309 temp_suffix_ = temp_suffix;
310 }
Austin Schuhcb5601b2020-09-10 15:29:59 -0700311
Brian Silvermancb805822020-10-06 17:43:35 -0700312 // Sets the function for creating encoders.
313 //
314 // Defaults to just creating DummyEncoders.
315 void set_encoder_factory(
316 std::function<std::unique_ptr<DetachedBufferEncoder>()> encoder_factory) {
317 encoder_factory_ = std::move(encoder_factory);
318 }
319
320 // Sets an additional file extension.
321 //
322 // Defaults to nothing.
323 void set_extension(std::string_view extension) { extension_ = extension; }
Brian Silverman1f345222020-09-24 21:14:48 -0700324
Brian Silvermana621f522020-09-30 16:52:43 -0700325 // A list of all the filenames we've written.
326 //
327 // This only includes the part after base_name().
328 const std::vector<std::string> &all_filenames() const {
329 return all_filenames_;
330 }
331
Austin Schuh73340842021-07-30 22:32:06 -0700332 void Rotate(const Node *node) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700333
Austin Schuh8c399962020-12-25 21:51:45 -0800334 void WriteConfiguration(
335 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> *header,
336 std::string_view config_sha256) override;
337
Austin Schuhb8bca732021-07-30 22:32:00 -0700338 NewDataWriter *MakeWriter(const Channel *channel) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700339
Austin Schuhb8bca732021-07-30 22:32:00 -0700340 NewDataWriter *MakeForwardedTimestampWriter(const Channel *channel,
Austin Schuh73340842021-07-30 22:32:06 -0700341 const Node *node) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700342
Austin Schuhb8bca732021-07-30 22:32:00 -0700343 NewDataWriter *MakeTimestampWriter(const Channel *channel) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700344
Brian Silverman0465fcf2020-09-24 00:29:18 -0700345 // Indicates that at least one file ran out of space. Once this happens, we
346 // stop trying to open new files, to avoid writing any files with holes from
347 // previous parts.
348 //
349 // Besides this function, this object will silently stop logging data when
350 // this occurs. If you want to ensure log files are complete, you must call
351 // this method.
Brian Silvermana9f2ec92020-10-06 18:00:53 -0700352 bool ran_out_of_space() const {
353 return accumulate_data_writers<bool>(
Austin Schuhb8bca732021-07-30 22:32:00 -0700354 ran_out_of_space_, [](bool x, const NewDataWriter &data_writer) {
Brian Silvermana9f2ec92020-10-06 18:00:53 -0700355 return x ||
356 (data_writer.writer && data_writer.writer->ran_out_of_space());
357 });
358 }
Brian Silverman0465fcf2020-09-24 00:29:18 -0700359
Brian Silverman1f345222020-09-24 21:14:48 -0700360 // Returns the maximum total_bytes() value for all existing
361 // DetachedBufferWriters.
362 //
363 // Returns 0 if no files are open.
364 size_t maximum_total_bytes() const {
Brian Silvermancb805822020-10-06 17:43:35 -0700365 return accumulate_data_writers<size_t>(
Austin Schuhb8bca732021-07-30 22:32:00 -0700366 0, [](size_t x, const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700367 return std::max(x, data_writer.writer->total_bytes());
368 });
Brian Silverman1f345222020-09-24 21:14:48 -0700369 }
370
Brian Silverman0465fcf2020-09-24 00:29:18 -0700371 // Closes all existing log files. No more data may be written after this.
372 //
373 // This may set ran_out_of_space().
374 void Close();
375
Brian Silvermancb805822020-10-06 17:43:35 -0700376 // Accessors for various statistics. See the identically-named methods in
377 // DetachedBufferWriter for documentation. These are aggregated across all
378 // past and present DetachedBufferWriters.
379 std::chrono::nanoseconds max_write_time() const {
380 return accumulate_data_writers(
381 max_write_time_,
Austin Schuhb8bca732021-07-30 22:32:00 -0700382 [](std::chrono::nanoseconds x, const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700383 return std::max(x, data_writer.writer->max_write_time());
384 });
385 }
386 int max_write_time_bytes() const {
387 return std::get<0>(accumulate_data_writers(
388 std::make_tuple(max_write_time_bytes_, max_write_time_),
389 [](std::tuple<int, std::chrono::nanoseconds> x,
Austin Schuhb8bca732021-07-30 22:32:00 -0700390 const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700391 if (data_writer.writer->max_write_time() > std::get<1>(x)) {
392 return std::make_tuple(data_writer.writer->max_write_time_bytes(),
393 data_writer.writer->max_write_time());
394 }
395 return x;
396 }));
397 }
398 int max_write_time_messages() const {
399 return std::get<0>(accumulate_data_writers(
400 std::make_tuple(max_write_time_messages_, max_write_time_),
401 [](std::tuple<int, std::chrono::nanoseconds> x,
Austin Schuhb8bca732021-07-30 22:32:00 -0700402 const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700403 if (data_writer.writer->max_write_time() > std::get<1>(x)) {
404 return std::make_tuple(
405 data_writer.writer->max_write_time_messages(),
406 data_writer.writer->max_write_time());
407 }
408 return x;
409 }));
410 }
411 std::chrono::nanoseconds total_write_time() const {
412 return accumulate_data_writers(
413 total_write_time_,
Austin Schuhb8bca732021-07-30 22:32:00 -0700414 [](std::chrono::nanoseconds x, const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700415 return x + data_writer.writer->total_write_time();
416 });
417 }
418 int total_write_count() const {
419 return accumulate_data_writers(
Austin Schuhb8bca732021-07-30 22:32:00 -0700420 total_write_count_, [](int x, const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700421 return x + data_writer.writer->total_write_count();
422 });
423 }
424 int total_write_messages() const {
425 return accumulate_data_writers(
Austin Schuhb8bca732021-07-30 22:32:00 -0700426 total_write_messages_, [](int x, const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700427 return x + data_writer.writer->total_write_messages();
428 });
429 }
430 int total_write_bytes() const {
431 return accumulate_data_writers(
Austin Schuhb8bca732021-07-30 22:32:00 -0700432 total_write_bytes_, [](int x, const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700433 return x + data_writer.writer->total_write_bytes();
434 });
435 }
436
437 void ResetStatistics();
438
Austin Schuhcb5601b2020-09-10 15:29:59 -0700439 private:
Austin Schuhcb5601b2020-09-10 15:29:59 -0700440 // Opens up a writer for timestamps forwarded back.
441 void OpenForwardedTimestampWriter(const Channel *channel,
Austin Schuhb8bca732021-07-30 22:32:00 -0700442 NewDataWriter *data_writer);
Austin Schuhcb5601b2020-09-10 15:29:59 -0700443
444 // Opens up a writer for remote data.
Austin Schuhb8bca732021-07-30 22:32:00 -0700445 void OpenWriter(const Channel *channel, NewDataWriter *data_writer);
Austin Schuhcb5601b2020-09-10 15:29:59 -0700446
447 // Opens the main data writer file for this node responsible for data_writer_.
Brian Silvermana621f522020-09-30 16:52:43 -0700448 void OpenDataWriter();
Austin Schuhcb5601b2020-09-10 15:29:59 -0700449
Brian Silvermana621f522020-09-30 16:52:43 -0700450 void CreateBufferWriter(std::string_view path,
Brian Silverman0465fcf2020-09-24 00:29:18 -0700451 std::unique_ptr<DetachedBufferWriter> *destination);
452
Brian Silverman48deab12020-09-30 18:39:28 -0700453 void RenameTempFile(DetachedBufferWriter *destination);
454
Brian Silvermancb805822020-10-06 17:43:35 -0700455 void CloseWriter(std::unique_ptr<DetachedBufferWriter> *writer_pointer);
Austin Schuhcb5601b2020-09-10 15:29:59 -0700456
Brian Silvermancb805822020-10-06 17:43:35 -0700457 // A version of std::accumulate which operates over all of our DataWriters.
458 template <typename T, typename BinaryOperation>
459 T accumulate_data_writers(T t, BinaryOperation op) const {
Austin Schuhb8bca732021-07-30 22:32:00 -0700460 for (const std::pair<const Channel *const, NewDataWriter> &data_writer :
Brian Silvermancb805822020-10-06 17:43:35 -0700461 data_writers_) {
Austin Schuhad0cfc32020-12-21 12:34:26 -0800462 if (!data_writer.second.writer) continue;
Brian Silvermancb805822020-10-06 17:43:35 -0700463 t = op(std::move(t), data_writer.second);
464 }
Austin Schuhb8bca732021-07-30 22:32:00 -0700465 if (data_writer_) {
466 t = op(std::move(t), *data_writer_);
Brian Silvermancb805822020-10-06 17:43:35 -0700467 }
468 return t;
469 }
470
Austin Schuh6bb8a822021-03-31 23:04:39 -0700471 std::string base_name_;
472 std::string old_base_name_;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700473
Brian Silverman0465fcf2020-09-24 00:29:18 -0700474 bool ran_out_of_space_ = false;
Brian Silvermana621f522020-09-30 16:52:43 -0700475 std::vector<std::string> all_filenames_;
Brian Silverman0465fcf2020-09-24 00:29:18 -0700476
Brian Silvermancb805822020-10-06 17:43:35 -0700477 std::string temp_suffix_;
478 std::function<std::unique_ptr<DetachedBufferEncoder>()> encoder_factory_ =
479 []() { return std::make_unique<DummyEncoder>(); };
480 std::string extension_;
481
482 // Storage for statistics from previously-rotated DetachedBufferWriters.
483 std::chrono::nanoseconds max_write_time_ = std::chrono::nanoseconds::zero();
484 int max_write_time_bytes_ = -1;
485 int max_write_time_messages_ = -1;
486 std::chrono::nanoseconds total_write_time_ = std::chrono::nanoseconds::zero();
487 int total_write_count_ = 0;
488 int total_write_messages_ = 0;
489 int total_write_bytes_ = 0;
490
Austin Schuhcb5601b2020-09-10 15:29:59 -0700491 // File to write both delivery timestamps and local data to.
Austin Schuhb8bca732021-07-30 22:32:00 -0700492 std::unique_ptr<NewDataWriter> data_writer_;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700493
Austin Schuhb8bca732021-07-30 22:32:00 -0700494 std::map<const Channel *, NewDataWriter> data_writers_;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700495};
496
497} // namespace logger
498} // namespace aos
499
500#endif // AOS_EVENTS_LOGGING_LOG_NAMER_H_