blob: 8349a097b33e6b2a6b5ac4750538da603dc4cd9b [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 Schuhb8bca732021-07-30 22:32:00 -070018// TODO(austin): Track if headers are written here much more carefully.
19//
20// TODO(austin): Rename this back to DataWriter once all other callers are of
21// the old DataWriter.
22class NewDataWriter {
23 public:
24 // Constructs a NewDataWriter.
25 // reopen is called whenever a file needs to be reopened.
26 // close is called to close that file and extract any statistics.
27 NewDataWriter(std::function<void(NewDataWriter *)> reopen,
28 std::function<void(NewDataWriter *)> close)
29 : reopen_(std::move(reopen)), close_(std::move(close)) {
30 reopen_(this);
31 }
32
33 NewDataWriter(NewDataWriter &&other) = default;
34 aos::logger::NewDataWriter &operator=(NewDataWriter &&other) = default;
35 NewDataWriter(const NewDataWriter &) = delete;
36 void operator=(const NewDataWriter &) = delete;
37
38 ~NewDataWriter() {
39 if (writer) {
40 Close();
41 }
42 }
43
44 void Rotate() {
45 ++part_number;
46 reopen_(this);
47 }
48
Austin Schuhb8bca732021-07-30 22:32:00 -070049 // TODO(austin): Copy header and add all UUIDs and such when available
50 // whenever data is written.
51 //
52 // TODO(austin): Automatically write the header and update on boot UUID
53 // change.
54 //
55 // TODO(austin): Add known timestamps for each node every time we cycle a log
56 // for sorting.
57
58 void QueueSizedFlatbuffer(flatbuffers::FlatBufferBuilder *fbb,
59 aos::monotonic_clock::time_point now) {
60 writer->QueueSizedFlatbuffer(fbb, now);
61 }
62
Austin Schuh73340842021-07-30 22:32:06 -070063 void QueueHeader(
64 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> &&header) {
65 // TODO(austin): This triggers a dummy allocation that we don't need as part
66 // of releasing. Can we skip it?
67 writer->QueueSizedFlatbuffer(header.Release());
68 }
69
Austin Schuhb8bca732021-07-30 22:32:00 -070070 std::string_view filename() const { return writer->filename(); }
71
72 void Reboot() {
73 uuid_ = UUID::Random();
74 Rotate();
75 }
76
77 void Close() {
78 CHECK(writer);
79 close_(this);
80 writer.reset();
81 }
82
83 std::unique_ptr<DetachedBufferWriter> writer = nullptr;
84 const Node *node = nullptr;
85 size_t part_number = 0;
86 const UUID &uuid() const { return uuid_; }
87
88 private:
89 UUID uuid_ = UUID::Random();
90 std::function<void(NewDataWriter *)> reopen_;
91 std::function<void(NewDataWriter *)> close_;
92};
93
Austin Schuhcb5601b2020-09-10 15:29:59 -070094// Interface describing how to name, track, and add headers to log file parts.
95class LogNamer {
96 public:
97 // Constructs a LogNamer with the primary node (ie the one the logger runs on)
98 // being node.
Austin Schuh73340842021-07-30 22:32:06 -070099 LogNamer(const Configuration *configuration, const Node *node)
100 : configuration_(configuration), node_(node) {
101 nodes_.emplace_back(node_);
102 node_states_.resize(configuration::NodesCount(configuration_));
103 }
Austin Schuhcb5601b2020-09-10 15:29:59 -0700104 virtual ~LogNamer() {}
105
Austin Schuh6bb8a822021-03-31 23:04:39 -0700106 virtual std::string_view base_name() const = 0;
107
108 // Rotate should be called at least once in between calls to set_base_name.
109 // Otherwise temporary files will not be recoverable.
110 // Rotate is called by Logger::RenameLogBase, which is currently the only user
111 // of this method.
112 // Only renaming the folder is supported, not the file base name.
113 virtual void set_base_name(std::string_view base_name) = 0;
114
Austin Schuhcb5601b2020-09-10 15:29:59 -0700115 // Writes the header to all log files for a specific node. This function
116 // needs to be called after all the writers are created.
117 //
118 // Modifies header to contain the uuid and part number for each writer as it
119 // writes it. Since this is done unconditionally, it does not restore the
120 // previous value at the end.
Austin Schuh73340842021-07-30 22:32:06 -0700121 virtual void WriteHeader(const Node *node) = 0;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700122
Brian Silverman87ac0402020-09-17 14:47:01 -0700123 // Returns a writer for writing data from messages on this channel (on the
124 // primary node).
125 //
126 // The returned pointer will stay valid across rotations, but the object it
127 // points to will be assigned to.
Austin Schuhb8bca732021-07-30 22:32:00 -0700128 virtual NewDataWriter *MakeWriter(const Channel *channel) = 0;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700129
Brian Silverman87ac0402020-09-17 14:47:01 -0700130 // Returns a writer for writing timestamps from messages on this channel (on
131 // the primary node).
132 //
133 // The returned pointer will stay valid across rotations, but the object it
134 // points to will be assigned to.
Austin Schuhb8bca732021-07-30 22:32:00 -0700135 virtual NewDataWriter *MakeTimestampWriter(const Channel *channel) = 0;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700136
137 // Returns a writer for writing timestamps delivered over the special
138 // /aos/remote_timestamps/* channels. node is the node that the timestamps
Brian Silverman87ac0402020-09-17 14:47:01 -0700139 // are forwarded back from (to the primary node).
140 //
141 // The returned pointer will stay valid across rotations, but the object it
142 // points to will be assigned to.
Austin Schuh73340842021-07-30 22:32:06 -0700143 virtual NewDataWriter *MakeForwardedTimestampWriter(const Channel *channel,
144 const Node *node) = 0;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700145
Austin Schuh73340842021-07-30 22:32:06 -0700146 // Rotates all log files for the provided node.
147 virtual void Rotate(const Node *node) = 0;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700148
Austin Schuh73340842021-07-30 22:32:06 -0700149 // Reboots all log files for the provided node. Resets any parts UUIDs.
150 virtual void Reboot(const Node *node) = 0;
Austin Schuh315b96b2020-12-11 21:21:12 -0800151
Austin Schuhcb5601b2020-09-10 15:29:59 -0700152 // Returns all the nodes that data is being written for.
153 const std::vector<const Node *> &nodes() const { return nodes_; }
154
155 // Returns the node the logger is running on.
156 const Node *node() const { return node_; }
157
Austin Schuh8c399962020-12-25 21:51:45 -0800158 // Writes out the nested Configuration object to the config file location.
159 virtual void WriteConfiguration(
160 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> *header,
161 std::string_view config_sha256) = 0;
162
Austin Schuh73340842021-07-30 22:32:06 -0700163 void SetHeaderTemplate(
164 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> header) {
165 header_ = std::move(header);
166 }
Austin Schuhcb5601b2020-09-10 15:29:59 -0700167
Austin Schuh73340842021-07-30 22:32:06 -0700168 void SetStartTimes(size_t node_index,
169 monotonic_clock::time_point monotonic_start_time,
170 realtime_clock::time_point realtime_start_time,
171 monotonic_clock::time_point logger_monotonic_start_time,
172 realtime_clock::time_point logger_realtime_start_time) {
173 node_states_[node_index].monotonic_start_time = monotonic_start_time;
174 node_states_[node_index].realtime_start_time = realtime_start_time;
175 node_states_[node_index].logger_monotonic_start_time =
176 logger_monotonic_start_time;
177 node_states_[node_index].logger_realtime_start_time =
178 logger_realtime_start_time;
179 // TODO(austin): Track that the header has changed and needs to be
180 // rewritten.
181 }
182
183 monotonic_clock::time_point monotonic_start_time(size_t node_index) const {
184 return node_states_[node_index].monotonic_start_time;
185 }
186
187 // TODO(austin): I need to move header writing fully inside NewDataWriter and
188 // delete this method.
189 bool SetBootUUID(size_t node_index, const UUID &uuid) {
190 if (node_states_[node_index].source_node_boot_uuid != uuid) {
191 node_states_[node_index].source_node_boot_uuid = uuid;
192 return true;
193 }
194 return false;
195 }
196
197 protected:
198 // Creates a new header by copying fields out of the template and combining
199 // them with the arguments provided.
200 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> MakeHeader(
201 size_t node_index, const UUID &source_node_boot_uuid,
202 const UUID &parts_uuid, int parts_index) const;
203
204 const Configuration *const configuration_;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700205 const Node *const node_;
206 std::vector<const Node *> nodes_;
Austin Schuh73340842021-07-30 22:32:06 -0700207
208 // Structure with state per node about times and such.
209 // TODO(austin): some of this lives better in NewDataWriter once we move
210 // ownership of deciding when to write headers into LogNamer.
211 struct NodeState {
212 // Time when this node started logging.
213 monotonic_clock::time_point monotonic_start_time =
214 monotonic_clock::min_time;
215 realtime_clock::time_point realtime_start_time = realtime_clock::min_time;
216
217 // Corresponding time on the logger node when it started logging.
218 monotonic_clock::time_point logger_monotonic_start_time =
219 monotonic_clock::min_time;
220 realtime_clock::time_point logger_realtime_start_time =
221 realtime_clock::min_time;
222
223 UUID source_node_boot_uuid = UUID::Zero();
224 };
225 std::vector<NodeState> node_states_;
226
227 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> header_ =
228 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader>::Empty();
Austin Schuhcb5601b2020-09-10 15:29:59 -0700229};
230
231// Local log namer is a simple version which only names things
232// "base_name.part#.bfbs" and increments the part number. It doesn't support
233// any other log type.
234class LocalLogNamer : public LogNamer {
235 public:
Austin Schuh73340842021-07-30 22:32:06 -0700236 LocalLogNamer(std::string_view base_name, const Configuration *configuration,
237 const Node *node)
238 : LogNamer(configuration, node),
Austin Schuhcb5601b2020-09-10 15:29:59 -0700239 base_name_(base_name),
Austin Schuhb8bca732021-07-30 22:32:00 -0700240 data_writer_(
241 [this](NewDataWriter *writer) {
242 writer->writer = std::make_unique<DetachedBufferWriter>(
243 absl::StrCat(base_name_, ".part", writer->part_number,
244 ".bfbs"),
245 std::make_unique<aos::logger::DummyEncoder>());
246 },
247 [](NewDataWriter * /*writer*/) {}) {}
248
249 LocalLogNamer(const LocalLogNamer &) = delete;
250 LocalLogNamer(LocalLogNamer &&) = delete;
251 LocalLogNamer &operator=(const LocalLogNamer &) = delete;
252 LocalLogNamer &operator=(LocalLogNamer &&) = delete;
253
Brian Silverman0465fcf2020-09-24 00:29:18 -0700254 ~LocalLogNamer() override = default;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700255
Austin Schuh6bb8a822021-03-31 23:04:39 -0700256 std::string_view base_name() const final { return base_name_; }
257
258 void set_base_name(std::string_view base_name) final {
259 base_name_ = base_name;
260 }
261
Austin Schuh73340842021-07-30 22:32:06 -0700262 void WriteHeader(const Node *node) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700263
Austin Schuhb8bca732021-07-30 22:32:00 -0700264 NewDataWriter *MakeWriter(const Channel *channel) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700265
Austin Schuh73340842021-07-30 22:32:06 -0700266 void Rotate(const Node *node) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700267
Austin Schuh73340842021-07-30 22:32:06 -0700268 void Reboot(const Node *node) override;
Austin Schuh315b96b2020-12-11 21:21:12 -0800269
Austin Schuhb8bca732021-07-30 22:32:00 -0700270 NewDataWriter *MakeTimestampWriter(const Channel *channel) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700271
Austin Schuh73340842021-07-30 22:32:06 -0700272 NewDataWriter *MakeForwardedTimestampWriter(const Channel * /*channel*/,
273 const Node * /*node*/) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700274
Austin Schuh8c399962020-12-25 21:51:45 -0800275 void WriteConfiguration(
276 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> *header,
277 std::string_view config_sha256) override;
278
Austin Schuhcb5601b2020-09-10 15:29:59 -0700279 private:
Austin Schuh6bb8a822021-03-31 23:04:39 -0700280 std::string base_name_;
Austin Schuhb8bca732021-07-30 22:32:00 -0700281
282 NewDataWriter data_writer_;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700283};
284
285// Log namer which uses a config and a base name to name a bunch of files.
286class MultiNodeLogNamer : public LogNamer {
287 public:
Brian Silvermancb805822020-10-06 17:43:35 -0700288 MultiNodeLogNamer(std::string_view base_name,
289 const Configuration *configuration, const Node *node);
290 ~MultiNodeLogNamer() override;
291
Austin Schuh6bb8a822021-03-31 23:04:39 -0700292 std::string_view base_name() const final { return base_name_; }
293
294 void set_base_name(std::string_view base_name) final {
295 old_base_name_ = base_name_;
296 base_name_ = base_name;
297 }
Brian Silvermancb805822020-10-06 17:43:35 -0700298
Brian Silverman48deab12020-09-30 18:39:28 -0700299 // If temp_suffix is set, then this will write files under names beginning
300 // with the specified suffix, and then rename them to the desired name after
301 // they are fully written.
302 //
303 // This is useful to enable incremental copying of the log files.
304 //
305 // Defaults to writing directly to the final filename.
Brian Silvermancb805822020-10-06 17:43:35 -0700306 void set_temp_suffix(std::string_view temp_suffix) {
307 temp_suffix_ = temp_suffix;
308 }
Austin Schuhcb5601b2020-09-10 15:29:59 -0700309
Brian Silvermancb805822020-10-06 17:43:35 -0700310 // Sets the function for creating encoders.
311 //
312 // Defaults to just creating DummyEncoders.
313 void set_encoder_factory(
314 std::function<std::unique_ptr<DetachedBufferEncoder>()> encoder_factory) {
315 encoder_factory_ = std::move(encoder_factory);
316 }
317
318 // Sets an additional file extension.
319 //
320 // Defaults to nothing.
321 void set_extension(std::string_view extension) { extension_ = extension; }
Brian Silverman1f345222020-09-24 21:14:48 -0700322
Brian Silvermana621f522020-09-30 16:52:43 -0700323 // A list of all the filenames we've written.
324 //
325 // This only includes the part after base_name().
326 const std::vector<std::string> &all_filenames() const {
327 return all_filenames_;
328 }
329
Austin Schuh73340842021-07-30 22:32:06 -0700330 void WriteHeader(const Node *node) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700331
Austin Schuh73340842021-07-30 22:32:06 -0700332 void Rotate(const Node *node) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700333
Austin Schuh73340842021-07-30 22:32:06 -0700334 void Reboot(const Node *node) override;
Austin Schuh315b96b2020-12-11 21:21:12 -0800335
Austin Schuh8c399962020-12-25 21:51:45 -0800336 void WriteConfiguration(
337 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> *header,
338 std::string_view config_sha256) override;
339
Austin Schuhb8bca732021-07-30 22:32:00 -0700340 NewDataWriter *MakeWriter(const Channel *channel) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700341
Austin Schuhb8bca732021-07-30 22:32:00 -0700342 NewDataWriter *MakeForwardedTimestampWriter(const Channel *channel,
Austin Schuh73340842021-07-30 22:32:06 -0700343 const Node *node) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700344
Austin Schuhb8bca732021-07-30 22:32:00 -0700345 NewDataWriter *MakeTimestampWriter(const Channel *channel) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700346
Brian Silverman0465fcf2020-09-24 00:29:18 -0700347 // Indicates that at least one file ran out of space. Once this happens, we
348 // stop trying to open new files, to avoid writing any files with holes from
349 // previous parts.
350 //
351 // Besides this function, this object will silently stop logging data when
352 // this occurs. If you want to ensure log files are complete, you must call
353 // this method.
Brian Silvermana9f2ec92020-10-06 18:00:53 -0700354 bool ran_out_of_space() const {
355 return accumulate_data_writers<bool>(
Austin Schuhb8bca732021-07-30 22:32:00 -0700356 ran_out_of_space_, [](bool x, const NewDataWriter &data_writer) {
Brian Silvermana9f2ec92020-10-06 18:00:53 -0700357 return x ||
358 (data_writer.writer && data_writer.writer->ran_out_of_space());
359 });
360 }
Brian Silverman0465fcf2020-09-24 00:29:18 -0700361
Brian Silverman1f345222020-09-24 21:14:48 -0700362 // Returns the maximum total_bytes() value for all existing
363 // DetachedBufferWriters.
364 //
365 // Returns 0 if no files are open.
366 size_t maximum_total_bytes() const {
Brian Silvermancb805822020-10-06 17:43:35 -0700367 return accumulate_data_writers<size_t>(
Austin Schuhb8bca732021-07-30 22:32:00 -0700368 0, [](size_t x, const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700369 return std::max(x, data_writer.writer->total_bytes());
370 });
Brian Silverman1f345222020-09-24 21:14:48 -0700371 }
372
Brian Silverman0465fcf2020-09-24 00:29:18 -0700373 // Closes all existing log files. No more data may be written after this.
374 //
375 // This may set ran_out_of_space().
376 void Close();
377
Brian Silvermancb805822020-10-06 17:43:35 -0700378 // Accessors for various statistics. See the identically-named methods in
379 // DetachedBufferWriter for documentation. These are aggregated across all
380 // past and present DetachedBufferWriters.
381 std::chrono::nanoseconds max_write_time() const {
382 return accumulate_data_writers(
383 max_write_time_,
Austin Schuhb8bca732021-07-30 22:32:00 -0700384 [](std::chrono::nanoseconds x, const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700385 return std::max(x, data_writer.writer->max_write_time());
386 });
387 }
388 int max_write_time_bytes() const {
389 return std::get<0>(accumulate_data_writers(
390 std::make_tuple(max_write_time_bytes_, max_write_time_),
391 [](std::tuple<int, std::chrono::nanoseconds> x,
Austin Schuhb8bca732021-07-30 22:32:00 -0700392 const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700393 if (data_writer.writer->max_write_time() > std::get<1>(x)) {
394 return std::make_tuple(data_writer.writer->max_write_time_bytes(),
395 data_writer.writer->max_write_time());
396 }
397 return x;
398 }));
399 }
400 int max_write_time_messages() const {
401 return std::get<0>(accumulate_data_writers(
402 std::make_tuple(max_write_time_messages_, max_write_time_),
403 [](std::tuple<int, std::chrono::nanoseconds> x,
Austin Schuhb8bca732021-07-30 22:32:00 -0700404 const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700405 if (data_writer.writer->max_write_time() > std::get<1>(x)) {
406 return std::make_tuple(
407 data_writer.writer->max_write_time_messages(),
408 data_writer.writer->max_write_time());
409 }
410 return x;
411 }));
412 }
413 std::chrono::nanoseconds total_write_time() const {
414 return accumulate_data_writers(
415 total_write_time_,
Austin Schuhb8bca732021-07-30 22:32:00 -0700416 [](std::chrono::nanoseconds x, const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700417 return x + data_writer.writer->total_write_time();
418 });
419 }
420 int total_write_count() const {
421 return accumulate_data_writers(
Austin Schuhb8bca732021-07-30 22:32:00 -0700422 total_write_count_, [](int x, const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700423 return x + data_writer.writer->total_write_count();
424 });
425 }
426 int total_write_messages() const {
427 return accumulate_data_writers(
Austin Schuhb8bca732021-07-30 22:32:00 -0700428 total_write_messages_, [](int x, const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700429 return x + data_writer.writer->total_write_messages();
430 });
431 }
432 int total_write_bytes() const {
433 return accumulate_data_writers(
Austin Schuhb8bca732021-07-30 22:32:00 -0700434 total_write_bytes_, [](int x, const NewDataWriter &data_writer) {
Brian Silvermancb805822020-10-06 17:43:35 -0700435 return x + data_writer.writer->total_write_bytes();
436 });
437 }
438
439 void ResetStatistics();
440
Austin Schuhcb5601b2020-09-10 15:29:59 -0700441 private:
Austin Schuh315b96b2020-12-11 21:21:12 -0800442 // Implements Rotate and Reboot, controlled by the 'reboot' flag. The only
443 // difference between the two is if DataWriter::uuid is reset or not.
Austin Schuh73340842021-07-30 22:32:06 -0700444 void DoRotate(const Node *node, bool reboot);
Austin Schuh315b96b2020-12-11 21:21:12 -0800445
Austin Schuhcb5601b2020-09-10 15:29:59 -0700446 // Opens up a writer for timestamps forwarded back.
447 void OpenForwardedTimestampWriter(const Channel *channel,
Austin Schuhb8bca732021-07-30 22:32:00 -0700448 NewDataWriter *data_writer);
Austin Schuhcb5601b2020-09-10 15:29:59 -0700449
450 // Opens up a writer for remote data.
Austin Schuhb8bca732021-07-30 22:32:00 -0700451 void OpenWriter(const Channel *channel, NewDataWriter *data_writer);
Austin Schuhcb5601b2020-09-10 15:29:59 -0700452
453 // Opens the main data writer file for this node responsible for data_writer_.
Brian Silvermana621f522020-09-30 16:52:43 -0700454 void OpenDataWriter();
Austin Schuhcb5601b2020-09-10 15:29:59 -0700455
Brian Silvermana621f522020-09-30 16:52:43 -0700456 void CreateBufferWriter(std::string_view path,
Brian Silverman0465fcf2020-09-24 00:29:18 -0700457 std::unique_ptr<DetachedBufferWriter> *destination);
458
Brian Silverman48deab12020-09-30 18:39:28 -0700459 void RenameTempFile(DetachedBufferWriter *destination);
460
Brian Silvermancb805822020-10-06 17:43:35 -0700461 void CloseWriter(std::unique_ptr<DetachedBufferWriter> *writer_pointer);
Austin Schuhcb5601b2020-09-10 15:29:59 -0700462
Brian Silvermancb805822020-10-06 17:43:35 -0700463 // A version of std::accumulate which operates over all of our DataWriters.
464 template <typename T, typename BinaryOperation>
465 T accumulate_data_writers(T t, BinaryOperation op) const {
Austin Schuhb8bca732021-07-30 22:32:00 -0700466 for (const std::pair<const Channel *const, NewDataWriter> &data_writer :
Brian Silvermancb805822020-10-06 17:43:35 -0700467 data_writers_) {
Austin Schuhad0cfc32020-12-21 12:34:26 -0800468 if (!data_writer.second.writer) continue;
Brian Silvermancb805822020-10-06 17:43:35 -0700469 t = op(std::move(t), data_writer.second);
470 }
Austin Schuhb8bca732021-07-30 22:32:00 -0700471 if (data_writer_) {
472 t = op(std::move(t), *data_writer_);
Brian Silvermancb805822020-10-06 17:43:35 -0700473 }
474 return t;
475 }
476
Austin Schuh6bb8a822021-03-31 23:04:39 -0700477 std::string base_name_;
478 std::string old_base_name_;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700479
Brian Silverman0465fcf2020-09-24 00:29:18 -0700480 bool ran_out_of_space_ = false;
Brian Silvermana621f522020-09-30 16:52:43 -0700481 std::vector<std::string> all_filenames_;
Brian Silverman0465fcf2020-09-24 00:29:18 -0700482
Brian Silvermancb805822020-10-06 17:43:35 -0700483 std::string temp_suffix_;
484 std::function<std::unique_ptr<DetachedBufferEncoder>()> encoder_factory_ =
485 []() { return std::make_unique<DummyEncoder>(); };
486 std::string extension_;
487
488 // Storage for statistics from previously-rotated DetachedBufferWriters.
489 std::chrono::nanoseconds max_write_time_ = std::chrono::nanoseconds::zero();
490 int max_write_time_bytes_ = -1;
491 int max_write_time_messages_ = -1;
492 std::chrono::nanoseconds total_write_time_ = std::chrono::nanoseconds::zero();
493 int total_write_count_ = 0;
494 int total_write_messages_ = 0;
495 int total_write_bytes_ = 0;
496
Austin Schuhcb5601b2020-09-10 15:29:59 -0700497 // File to write both delivery timestamps and local data to.
Austin Schuhb8bca732021-07-30 22:32:00 -0700498 std::unique_ptr<NewDataWriter> data_writer_;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700499
Austin Schuhb8bca732021-07-30 22:32:00 -0700500 std::map<const Channel *, NewDataWriter> data_writers_;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700501};
502
503} // namespace logger
504} // namespace aos
505
506#endif // AOS_EVENTS_LOGGING_LOG_NAMER_H_