blob: ceeba9525934888639939b8b4cbb5639db5da7ff [file] [log] [blame]
Austin Schuhcb5601b2020-09-10 15:29:59 -07001#include "aos/events/logging/log_namer.h"
2
3#include <functional>
4#include <map>
5#include <memory>
6#include <string_view>
7#include <vector>
8
9#include "absl/strings/str_cat.h"
10#include "aos/events/logging/logfile_utils.h"
11#include "aos/events/logging/logger_generated.h"
Austin Schuh73340842021-07-30 22:32:06 -070012#include "aos/flatbuffer_merge.h"
Austin Schuh4385b142021-03-14 21:31:13 -070013#include "aos/uuid.h"
Austin Schuhcb5601b2020-09-10 15:29:59 -070014#include "flatbuffers/flatbuffers.h"
15#include "glog/logging.h"
16
17namespace aos {
18namespace logger {
19
Austin Schuh572924a2021-07-30 22:32:12 -070020NewDataWriter::NewDataWriter(LogNamer *log_namer, const Node *node,
21 std::function<void(NewDataWriter *)> reopen,
22 std::function<void(NewDataWriter *)> close)
23 : node_(node),
24 node_index_(configuration::GetNodeIndex(log_namer->configuration_, node)),
25 log_namer_(log_namer),
26 reopen_(std::move(reopen)),
27 close_(std::move(close)) {
Austin Schuh72211ae2021-08-05 14:02:30 -070028 state_.resize(configuration::NodesCount(log_namer->configuration_));
29 CHECK_LT(node_index_, state_.size());
Austin Schuh572924a2021-07-30 22:32:12 -070030}
31
32NewDataWriter::~NewDataWriter() {
33 if (writer) {
34 Close();
35 }
36}
37
38void NewDataWriter::Rotate() {
Austin Schuhe46492f2021-07-31 19:49:41 -070039 // No need to rotate if nothing has been written.
40 if (header_written_) {
Austin Schuh58646e22021-08-23 23:51:46 -070041 VLOG(1) << "Rotated " << filename();
Austin Schuhe46492f2021-07-31 19:49:41 -070042 ++parts_index_;
43 reopen_(this);
44 header_written_ = false;
45 QueueHeader(MakeHeader());
46 }
Austin Schuh572924a2021-07-30 22:32:12 -070047}
48
Austin Schuh5e14d842022-01-21 12:02:15 -080049void NewDataWriter::Reboot(const UUID &source_node_boot_uuid) {
Austin Schuh572924a2021-07-30 22:32:12 -070050 parts_uuid_ = UUID::Random();
51 ++parts_index_;
52 reopen_(this);
53 header_written_ = false;
Austin Schuh5e14d842022-01-21 12:02:15 -080054 for (State &state : state_) {
55 state.boot_uuid = UUID::Zero();
56 state.oldest_remote_monotonic_timestamp = monotonic_clock::max_time;
57 state.oldest_local_monotonic_timestamp = monotonic_clock::max_time;
58 state.oldest_remote_unreliable_monotonic_timestamp =
59 monotonic_clock::max_time;
60 state.oldest_local_unreliable_monotonic_timestamp =
61 monotonic_clock::max_time;
Austin Schuhbfe6c572022-01-27 20:48:20 -080062 state.oldest_remote_reliable_monotonic_timestamp =
63 monotonic_clock::max_time;
64 state.oldest_local_reliable_monotonic_timestamp =
65 monotonic_clock::max_time;
Austin Schuh5e14d842022-01-21 12:02:15 -080066 }
67
68 state_[node_index_].boot_uuid = source_node_boot_uuid;
69
70 VLOG(1) << "Rebooted " << filename();
71}
72
73void NewDataWriter::UpdateBoot(const UUID &source_node_boot_uuid) {
74 if (state_[node_index_].boot_uuid != source_node_boot_uuid) {
75 state_[node_index_].boot_uuid = source_node_boot_uuid;
76 if (header_written_) {
77 Reboot(source_node_boot_uuid);
78 }
79 }
Austin Schuh572924a2021-07-30 22:32:12 -070080}
81
Austin Schuh72211ae2021-08-05 14:02:30 -070082void NewDataWriter::UpdateRemote(
83 const size_t remote_node_index, const UUID &remote_node_boot_uuid,
84 const monotonic_clock::time_point monotonic_remote_time,
85 const monotonic_clock::time_point monotonic_event_time,
86 const bool reliable) {
Austin Schuh58646e22021-08-23 23:51:46 -070087 // Trigger rotation if anything in the header changes.
Austin Schuh72211ae2021-08-05 14:02:30 -070088 bool rotate = false;
89 CHECK_LT(remote_node_index, state_.size());
90 State &state = state_[remote_node_index];
Austin Schuh58646e22021-08-23 23:51:46 -070091
92 // Did the remote boot UUID change?
Austin Schuh72211ae2021-08-05 14:02:30 -070093 if (state.boot_uuid != remote_node_boot_uuid) {
Austin Schuhe46492f2021-07-31 19:49:41 -070094 VLOG(1) << filename() << " Remote " << remote_node_index << " updated to "
Austin Schuh72211ae2021-08-05 14:02:30 -070095 << remote_node_boot_uuid << " from " << state.boot_uuid;
96 state.boot_uuid = remote_node_boot_uuid;
97 state.oldest_remote_monotonic_timestamp = monotonic_clock::max_time;
98 state.oldest_local_monotonic_timestamp = monotonic_clock::max_time;
99 state.oldest_remote_unreliable_monotonic_timestamp =
100 monotonic_clock::max_time;
101 state.oldest_local_unreliable_monotonic_timestamp =
102 monotonic_clock::max_time;
Austin Schuhbfe6c572022-01-27 20:48:20 -0800103 state.oldest_remote_reliable_monotonic_timestamp =
104 monotonic_clock::max_time;
105 state.oldest_local_reliable_monotonic_timestamp =
106 monotonic_clock::max_time;
Austin Schuh72211ae2021-08-05 14:02:30 -0700107 rotate = true;
108 }
109
Austin Schuh58646e22021-08-23 23:51:46 -0700110 // Did the unreliable timestamps change?
Austin Schuh72211ae2021-08-05 14:02:30 -0700111 if (!reliable) {
112 if (state.oldest_remote_unreliable_monotonic_timestamp >
113 monotonic_remote_time) {
Austin Schuh58646e22021-08-23 23:51:46 -0700114 VLOG(1) << filename() << " Remote " << remote_node_index
115 << " oldest_remote_unreliable_monotonic_timestamp updated from "
116 << state.oldest_remote_unreliable_monotonic_timestamp << " to "
117 << monotonic_remote_time;
Austin Schuh72211ae2021-08-05 14:02:30 -0700118 state.oldest_remote_unreliable_monotonic_timestamp =
119 monotonic_remote_time;
120 state.oldest_local_unreliable_monotonic_timestamp = monotonic_event_time;
121 rotate = true;
122 }
Austin Schuhbfe6c572022-01-27 20:48:20 -0800123 } else {
124 if (state.oldest_remote_reliable_monotonic_timestamp >
125 monotonic_remote_time) {
126 VLOG(1) << filename() << " Remote " << remote_node_index
127 << " oldest_remote_reliable_monotonic_timestamp updated from "
128 << state.oldest_remote_reliable_monotonic_timestamp << " to "
129 << monotonic_remote_time;
130 state.oldest_remote_reliable_monotonic_timestamp = monotonic_remote_time;
131 state.oldest_local_reliable_monotonic_timestamp = monotonic_event_time;
132 rotate = true;
133 }
Austin Schuh72211ae2021-08-05 14:02:30 -0700134 }
135
Austin Schuh58646e22021-08-23 23:51:46 -0700136 // Did any of the timestamps change?
Austin Schuh72211ae2021-08-05 14:02:30 -0700137 if (state.oldest_remote_monotonic_timestamp > monotonic_remote_time) {
Austin Schuh58646e22021-08-23 23:51:46 -0700138 VLOG(1) << filename() << " Remote " << remote_node_index
139 << " oldest_remote_monotonic_timestamp updated from "
140 << state.oldest_remote_monotonic_timestamp << " to "
141 << monotonic_remote_time;
Austin Schuh72211ae2021-08-05 14:02:30 -0700142 state.oldest_remote_monotonic_timestamp = monotonic_remote_time;
143 state.oldest_local_monotonic_timestamp = monotonic_event_time;
144 rotate = true;
145 }
146
147 if (rotate) {
Austin Schuhe46492f2021-07-31 19:49:41 -0700148 Rotate();
149 }
150}
151
152void NewDataWriter::QueueMessage(flatbuffers::FlatBufferBuilder *fbb,
153 const UUID &source_node_boot_uuid,
154 aos::monotonic_clock::time_point now) {
Austin Schuh58646e22021-08-23 23:51:46 -0700155 // Trigger a reboot if we detect the boot UUID change.
Austin Schuh5e14d842022-01-21 12:02:15 -0800156 UpdateBoot(source_node_boot_uuid);
Austin Schuh572924a2021-07-30 22:32:12 -0700157
Austin Schuh5e14d842022-01-21 12:02:15 -0800158 if (!header_written_) {
Austin Schuhe46492f2021-07-31 19:49:41 -0700159 QueueHeader(MakeHeader());
Austin Schuh572924a2021-07-30 22:32:12 -0700160 }
Austin Schuh58646e22021-08-23 23:51:46 -0700161
162 // If the start time has changed for this node, trigger a rotation.
163 if (log_namer_->monotonic_start_time(node_index_, source_node_boot_uuid) !=
Austin Schuh5e14d842022-01-21 12:02:15 -0800164 monotonic_start_time_) {
Austin Schuh58646e22021-08-23 23:51:46 -0700165 CHECK(header_written_);
166 Rotate();
167 }
168
169 CHECK_EQ(log_namer_->monotonic_start_time(node_index_, source_node_boot_uuid),
170 monotonic_start_time_);
Austin Schuh72211ae2021-08-05 14:02:30 -0700171 CHECK_EQ(state_[node_index_].boot_uuid, source_node_boot_uuid);
milind-ua50344f2021-08-25 18:22:20 -0700172 CHECK(writer);
Austin Schuh572924a2021-07-30 22:32:12 -0700173 CHECK(header_written_) << ": Attempting to write message before header to "
174 << writer->filename();
175 writer->QueueSizedFlatbuffer(fbb, now);
176}
177
Austin Schuhe46492f2021-07-31 19:49:41 -0700178aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader>
179NewDataWriter::MakeHeader() {
180 const size_t logger_node_index = log_namer_->logger_node_index();
181 const UUID &logger_node_boot_uuid = log_namer_->logger_node_boot_uuid();
Austin Schuh72211ae2021-08-05 14:02:30 -0700182 if (state_[logger_node_index].boot_uuid == UUID::Zero()) {
Austin Schuhe46492f2021-07-31 19:49:41 -0700183 VLOG(1) << filename() << " Logger node is " << logger_node_index
184 << " and uuid is " << logger_node_boot_uuid;
Austin Schuh72211ae2021-08-05 14:02:30 -0700185 state_[logger_node_index].boot_uuid = logger_node_boot_uuid;
Austin Schuhe46492f2021-07-31 19:49:41 -0700186 } else {
Austin Schuh72211ae2021-08-05 14:02:30 -0700187 CHECK_EQ(state_[logger_node_index].boot_uuid, logger_node_boot_uuid);
Austin Schuhe46492f2021-07-31 19:49:41 -0700188 }
Austin Schuh72211ae2021-08-05 14:02:30 -0700189 return log_namer_->MakeHeader(node_index_, state_, parts_uuid(),
Austin Schuhe46492f2021-07-31 19:49:41 -0700190 parts_index_);
191}
192
Austin Schuh572924a2021-07-30 22:32:12 -0700193void NewDataWriter::QueueHeader(
194 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> &&header) {
195 CHECK(!header_written_) << ": Attempting to write duplicate header to "
196 << writer->filename();
197 CHECK(header.message().has_source_node_boot_uuid());
Austin Schuh72211ae2021-08-05 14:02:30 -0700198 CHECK_EQ(state_[node_index_].boot_uuid,
Austin Schuhe46492f2021-07-31 19:49:41 -0700199 UUID::FromString(header.message().source_node_boot_uuid()));
Austin Schuh510dc622021-08-06 18:47:30 -0700200 if (!writer) {
201 reopen_(this);
202 }
203
Austin Schuh58646e22021-08-23 23:51:46 -0700204 VLOG(1) << "Writing to " << filename() << " "
205 << aos::FlatbufferToJson(
206 header, {.multi_line = false, .max_vector_size = 100});
207
Austin Schuh572924a2021-07-30 22:32:12 -0700208 // TODO(austin): This triggers a dummy allocation that we don't need as part
209 // of releasing. Can we skip it?
Austin Schuh510dc622021-08-06 18:47:30 -0700210 CHECK(writer);
Austin Schuh572924a2021-07-30 22:32:12 -0700211 writer->QueueSizedFlatbuffer(header.Release());
212 header_written_ = true;
Austin Schuh58646e22021-08-23 23:51:46 -0700213 monotonic_start_time_ = log_namer_->monotonic_start_time(
214 node_index_, state_[node_index_].boot_uuid);
Austin Schuh572924a2021-07-30 22:32:12 -0700215}
216
217void NewDataWriter::Close() {
218 CHECK(writer);
219 close_(this);
220 writer.reset();
221 header_written_ = false;
222}
223
Austin Schuh58646e22021-08-23 23:51:46 -0700224LogNamer::NodeState *LogNamer::GetNodeState(size_t node_index,
225 const UUID &boot_uuid) {
226 auto it = node_states_.find(std::make_pair(node_index, boot_uuid));
227 if (it == node_states_.end()) {
228 it =
229 node_states_.emplace(std::make_pair(node_index, boot_uuid), NodeState())
230 .first;
231 }
232 return &it->second;
233}
234
Austin Schuh73340842021-07-30 22:32:06 -0700235aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> LogNamer::MakeHeader(
Austin Schuh72211ae2021-08-05 14:02:30 -0700236 size_t node_index, const std::vector<NewDataWriter::State> &state,
Austin Schuh58646e22021-08-23 23:51:46 -0700237 const UUID &parts_uuid, int parts_index) {
Austin Schuh72211ae2021-08-05 14:02:30 -0700238 const UUID &source_node_boot_uuid = state[node_index].boot_uuid;
Austin Schuh73340842021-07-30 22:32:06 -0700239 const Node *const source_node =
240 configuration::GetNode(configuration_, node_index);
Austin Schuhbfe6c572022-01-27 20:48:20 -0800241 CHECK_EQ(LogFileHeader::MiniReflectTypeTable()->num_elems, 30u);
Austin Schuh73340842021-07-30 22:32:06 -0700242 flatbuffers::FlatBufferBuilder fbb;
243 fbb.ForceDefaults(true);
244
245 flatbuffers::Offset<flatbuffers::String> config_sha256_offset;
246 flatbuffers::Offset<aos::Configuration> configuration_offset;
247 if (header_.message().has_configuration()) {
248 CHECK(!header_.message().has_configuration_sha256());
249 configuration_offset =
250 CopyFlatBuffer(header_.message().configuration(), &fbb);
251 } else {
252 CHECK(!header_.message().has_configuration());
253 CHECK(header_.message().has_configuration_sha256());
254 config_sha256_offset = fbb.CreateString(
255 header_.message().configuration_sha256()->string_view());
256 }
257
258 CHECK(header_.message().has_name());
259 const flatbuffers::Offset<flatbuffers::String> name_offset =
260 fbb.CreateString(header_.message().name()->string_view());
261
262 CHECK(header_.message().has_log_event_uuid());
263 const flatbuffers::Offset<flatbuffers::String> log_event_uuid_offset =
264 fbb.CreateString(header_.message().log_event_uuid()->string_view());
265
266 CHECK(header_.message().has_logger_instance_uuid());
267 const flatbuffers::Offset<flatbuffers::String> logger_instance_uuid_offset =
268 fbb.CreateString(header_.message().logger_instance_uuid()->string_view());
269
270 flatbuffers::Offset<flatbuffers::String> log_start_uuid_offset;
271 if (header_.message().has_log_start_uuid()) {
272 log_start_uuid_offset =
273 fbb.CreateString(header_.message().log_start_uuid()->string_view());
274 }
275
276 CHECK(header_.message().has_logger_node_boot_uuid());
277 const flatbuffers::Offset<flatbuffers::String> logger_node_boot_uuid_offset =
278 fbb.CreateString(
279 header_.message().logger_node_boot_uuid()->string_view());
280
281 CHECK_NE(source_node_boot_uuid, UUID::Zero());
282 const flatbuffers::Offset<flatbuffers::String> source_node_boot_uuid_offset =
283 source_node_boot_uuid.PackString(&fbb);
284
285 const flatbuffers::Offset<flatbuffers::String> parts_uuid_offset =
286 parts_uuid.PackString(&fbb);
287
288 flatbuffers::Offset<Node> node_offset;
289 flatbuffers::Offset<Node> logger_node_offset;
290
291 if (configuration::MultiNode(configuration_)) {
292 node_offset = RecursiveCopyFlatBuffer(source_node, &fbb);
293 logger_node_offset = RecursiveCopyFlatBuffer(node_, &fbb);
294 }
295
Austin Schuhe46492f2021-07-31 19:49:41 -0700296 std::vector<flatbuffers::Offset<flatbuffers::String>> boot_uuid_offsets;
Austin Schuh72211ae2021-08-05 14:02:30 -0700297 boot_uuid_offsets.reserve(state.size());
Austin Schuhe46492f2021-07-31 19:49:41 -0700298
Austin Schuh4db9ec92021-09-22 13:11:12 -0700299 int64_t *unused;
Austin Schuh72211ae2021-08-05 14:02:30 -0700300 flatbuffers::Offset<flatbuffers::Vector<int64_t>>
301 oldest_remote_monotonic_timestamps_offset = fbb.CreateUninitializedVector(
Austin Schuh4db9ec92021-09-22 13:11:12 -0700302 state.size(), &unused);
Austin Schuh72211ae2021-08-05 14:02:30 -0700303
Austin Schuh72211ae2021-08-05 14:02:30 -0700304 flatbuffers::Offset<flatbuffers::Vector<int64_t>>
305 oldest_local_monotonic_timestamps_offset = fbb.CreateUninitializedVector(
Austin Schuh4db9ec92021-09-22 13:11:12 -0700306 state.size(), &unused);
Austin Schuh72211ae2021-08-05 14:02:30 -0700307
Austin Schuh72211ae2021-08-05 14:02:30 -0700308 flatbuffers::Offset<flatbuffers::Vector<int64_t>>
309 oldest_remote_unreliable_monotonic_timestamps_offset =
310 fbb.CreateUninitializedVector(
Austin Schuh4db9ec92021-09-22 13:11:12 -0700311 state.size(), &unused);
Austin Schuh72211ae2021-08-05 14:02:30 -0700312
Austin Schuh72211ae2021-08-05 14:02:30 -0700313 flatbuffers::Offset<flatbuffers::Vector<int64_t>>
314 oldest_local_unreliable_monotonic_timestamps_offset =
315 fbb.CreateUninitializedVector(
Austin Schuh4db9ec92021-09-22 13:11:12 -0700316 state.size(), &unused);
Austin Schuh72211ae2021-08-05 14:02:30 -0700317
Austin Schuhbfe6c572022-01-27 20:48:20 -0800318 flatbuffers::Offset<flatbuffers::Vector<int64_t>>
319 oldest_remote_reliable_monotonic_timestamps_offset =
320 fbb.CreateUninitializedVector(
321 state.size(), &unused);
322
323 flatbuffers::Offset<flatbuffers::Vector<int64_t>>
324 oldest_local_reliable_monotonic_timestamps_offset =
325 fbb.CreateUninitializedVector(
326 state.size(), &unused);
327
Austin Schuh72211ae2021-08-05 14:02:30 -0700328 for (size_t i = 0; i < state.size(); ++i) {
Austin Schuh4db9ec92021-09-22 13:11:12 -0700329 if (state[i].boot_uuid != UUID::Zero()) {
330 boot_uuid_offsets.emplace_back(state[i].boot_uuid.PackString(&fbb));
331 } else {
332 boot_uuid_offsets.emplace_back(fbb.CreateString(""));
333 }
Austin Schuh5ae8f4a2021-09-11 19:09:50 -0700334 if (state[i].boot_uuid == UUID::Zero()) {
335 CHECK_EQ(state[i].oldest_remote_monotonic_timestamp,
336 monotonic_clock::max_time);
337 CHECK_EQ(state[i].oldest_local_monotonic_timestamp,
338 monotonic_clock::max_time);
339 CHECK_EQ(state[i].oldest_remote_unreliable_monotonic_timestamp,
340 monotonic_clock::max_time);
341 CHECK_EQ(state[i].oldest_local_unreliable_monotonic_timestamp,
342 monotonic_clock::max_time);
Austin Schuhbfe6c572022-01-27 20:48:20 -0800343 CHECK_EQ(state[i].oldest_remote_reliable_monotonic_timestamp,
344 monotonic_clock::max_time);
345 CHECK_EQ(state[i].oldest_local_reliable_monotonic_timestamp,
346 monotonic_clock::max_time);
Austin Schuh5ae8f4a2021-09-11 19:09:50 -0700347 }
348
Austin Schuh4db9ec92021-09-22 13:11:12 -0700349 flatbuffers::GetMutableTemporaryPointer(
350 fbb, oldest_remote_monotonic_timestamps_offset)
351 ->Mutate(i, state[i]
352 .oldest_remote_monotonic_timestamp.time_since_epoch()
353 .count());
354 flatbuffers::GetMutableTemporaryPointer(
355 fbb, oldest_local_monotonic_timestamps_offset)
356 ->Mutate(i, state[i]
357 .oldest_local_monotonic_timestamp.time_since_epoch()
358 .count());
359 flatbuffers::GetMutableTemporaryPointer(
360 fbb, oldest_remote_unreliable_monotonic_timestamps_offset)
361 ->Mutate(i, state[i]
Austin Schuhbfe6c572022-01-27 20:48:20 -0800362 .oldest_remote_unreliable_monotonic_timestamp
363 .time_since_epoch()
Austin Schuh4db9ec92021-09-22 13:11:12 -0700364 .count());
365 flatbuffers::GetMutableTemporaryPointer(
366 fbb, oldest_local_unreliable_monotonic_timestamps_offset)
367 ->Mutate(i, state[i]
Austin Schuhbfe6c572022-01-27 20:48:20 -0800368 .oldest_local_unreliable_monotonic_timestamp
369 .time_since_epoch()
Austin Schuh4db9ec92021-09-22 13:11:12 -0700370 .count());
Austin Schuhbfe6c572022-01-27 20:48:20 -0800371
372 flatbuffers::GetMutableTemporaryPointer(
373 fbb, oldest_remote_reliable_monotonic_timestamps_offset)
374 ->Mutate(i, state[i]
375 .oldest_remote_reliable_monotonic_timestamp
376 .time_since_epoch()
377 .count());
378 flatbuffers::GetMutableTemporaryPointer(
379 fbb, oldest_local_reliable_monotonic_timestamps_offset)
380 ->Mutate(
381 i, state[i]
382 .oldest_local_reliable_monotonic_timestamp.time_since_epoch()
383 .count());
Austin Schuh72211ae2021-08-05 14:02:30 -0700384 }
385
Austin Schuh4db9ec92021-09-22 13:11:12 -0700386 flatbuffers::Offset<
387 flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>>
388 boot_uuids_offset = fbb.CreateVector(boot_uuid_offsets);
389
Austin Schuh73340842021-07-30 22:32:06 -0700390 aos::logger::LogFileHeader::Builder log_file_header_builder(fbb);
391
392 log_file_header_builder.add_name(name_offset);
393
394 // Only add the node if we are running in a multinode configuration.
395 if (!logger_node_offset.IsNull()) {
396 log_file_header_builder.add_node(node_offset);
397 log_file_header_builder.add_logger_node(logger_node_offset);
398 }
399
400 if (!configuration_offset.IsNull()) {
401 log_file_header_builder.add_configuration(configuration_offset);
402 }
403 log_file_header_builder.add_max_out_of_order_duration(
404 header_.message().max_out_of_order_duration());
405
Austin Schuh58646e22021-08-23 23:51:46 -0700406 NodeState *node_state = GetNodeState(node_index, source_node_boot_uuid);
Austin Schuh73340842021-07-30 22:32:06 -0700407 log_file_header_builder.add_monotonic_start_time(
408 std::chrono::duration_cast<std::chrono::nanoseconds>(
Austin Schuh58646e22021-08-23 23:51:46 -0700409 node_state->monotonic_start_time.time_since_epoch())
Austin Schuh73340842021-07-30 22:32:06 -0700410 .count());
411 if (source_node == node_) {
412 log_file_header_builder.add_realtime_start_time(
413 std::chrono::duration_cast<std::chrono::nanoseconds>(
Austin Schuh58646e22021-08-23 23:51:46 -0700414 node_state->realtime_start_time.time_since_epoch())
Austin Schuh73340842021-07-30 22:32:06 -0700415 .count());
416 } else {
417 // Fill out the legacy start times. Since these were implemented to never
418 // change on reboot, they aren't very helpful in tracking what happened.
419 log_file_header_builder.add_logger_monotonic_start_time(
420 std::chrono::duration_cast<std::chrono::nanoseconds>(
Austin Schuh58646e22021-08-23 23:51:46 -0700421 node_state->logger_monotonic_start_time.time_since_epoch())
Austin Schuh73340842021-07-30 22:32:06 -0700422 .count());
423 log_file_header_builder.add_logger_realtime_start_time(
424 std::chrono::duration_cast<std::chrono::nanoseconds>(
Austin Schuh58646e22021-08-23 23:51:46 -0700425 node_state->logger_realtime_start_time.time_since_epoch())
Austin Schuh73340842021-07-30 22:32:06 -0700426 .count());
427 }
428
429 // TODO(austin): Add more useful times. When was this part started? What do
430 // we know about both the logger and remote then?
431
432 log_file_header_builder.add_log_event_uuid(log_event_uuid_offset);
433 log_file_header_builder.add_logger_instance_uuid(logger_instance_uuid_offset);
434 if (!log_start_uuid_offset.IsNull()) {
435 log_file_header_builder.add_log_start_uuid(log_start_uuid_offset);
436 }
437 log_file_header_builder.add_logger_node_boot_uuid(
438 logger_node_boot_uuid_offset);
439 log_file_header_builder.add_source_node_boot_uuid(
440 source_node_boot_uuid_offset);
441
442 log_file_header_builder.add_parts_uuid(parts_uuid_offset);
443 log_file_header_builder.add_parts_index(parts_index);
444
445 if (!config_sha256_offset.IsNull()) {
446 log_file_header_builder.add_configuration_sha256(config_sha256_offset);
447 }
448
Austin Schuhe46492f2021-07-31 19:49:41 -0700449 log_file_header_builder.add_boot_uuids(boot_uuids_offset);
Austin Schuha499cea2021-07-31 19:49:53 -0700450 log_file_header_builder.add_logger_part_monotonic_start_time(
451 std::chrono::duration_cast<std::chrono::nanoseconds>(
452 event_loop_->monotonic_now().time_since_epoch())
453 .count());
454 log_file_header_builder.add_logger_part_realtime_start_time(
455 std::chrono::duration_cast<std::chrono::nanoseconds>(
456 event_loop_->realtime_now().time_since_epoch())
457 .count());
Austin Schuh72211ae2021-08-05 14:02:30 -0700458 log_file_header_builder.add_oldest_remote_monotonic_timestamps(
459 oldest_remote_monotonic_timestamps_offset);
460 log_file_header_builder.add_oldest_local_monotonic_timestamps(
461 oldest_local_monotonic_timestamps_offset);
462 log_file_header_builder.add_oldest_remote_unreliable_monotonic_timestamps(
463 oldest_remote_unreliable_monotonic_timestamps_offset);
464 log_file_header_builder.add_oldest_local_unreliable_monotonic_timestamps(
465 oldest_local_unreliable_monotonic_timestamps_offset);
Austin Schuhbfe6c572022-01-27 20:48:20 -0800466 log_file_header_builder.add_oldest_remote_reliable_monotonic_timestamps(
467 oldest_remote_reliable_monotonic_timestamps_offset);
468 log_file_header_builder.add_oldest_local_reliable_monotonic_timestamps(
469 oldest_local_reliable_monotonic_timestamps_offset);
Austin Schuh73340842021-07-30 22:32:06 -0700470 fbb.FinishSizePrefixed(log_file_header_builder.Finish());
471 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> result(
472 fbb.Release());
473
474 CHECK(result.Verify()) << ": Built a corrupted header.";
475
476 return result;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700477}
478
Austin Schuhb8bca732021-07-30 22:32:00 -0700479NewDataWriter *LocalLogNamer::MakeWriter(const Channel *channel) {
Austin Schuhdf576472020-10-19 09:39:37 -0700480 CHECK(configuration::ChannelIsSendableOnNode(channel, node()))
481 << ": " << configuration::CleanedChannelToString(channel);
Austin Schuhb8bca732021-07-30 22:32:00 -0700482 return &data_writer_;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700483}
484
Austin Schuh73340842021-07-30 22:32:06 -0700485void LocalLogNamer::Rotate(const Node *node) {
Austin Schuhcb5601b2020-09-10 15:29:59 -0700486 CHECK(node == this->node());
Austin Schuhb8bca732021-07-30 22:32:00 -0700487 data_writer_.Rotate();
Austin Schuhcb5601b2020-09-10 15:29:59 -0700488}
Austin Schuh8c399962020-12-25 21:51:45 -0800489
490void LocalLogNamer::WriteConfiguration(
491 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> *header,
492 std::string_view config_sha256) {
493 const std::string filename = absl::StrCat(base_name_, config_sha256, ".bfbs");
494
495 std::unique_ptr<DetachedBufferWriter> writer =
496 std::make_unique<DetachedBufferWriter>(
497 filename, std::make_unique<aos::logger::DummyEncoder>());
498 writer->QueueSizedFlatbuffer(header->Release());
499}
500
Austin Schuhb8bca732021-07-30 22:32:00 -0700501NewDataWriter *LocalLogNamer::MakeTimestampWriter(const Channel *channel) {
Austin Schuhcb5601b2020-09-10 15:29:59 -0700502 CHECK(configuration::ChannelIsReadableOnNode(channel, node_))
503 << ": Message is not delivered to this node.";
504 CHECK(node_ != nullptr) << ": Can't log timestamps in a single node world";
505 CHECK(configuration::ConnectionDeliveryTimeIsLoggedOnNode(channel, node_,
506 node_))
507 << ": Delivery times aren't logged for this channel on this node.";
Austin Schuhb8bca732021-07-30 22:32:00 -0700508 return &data_writer_;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700509}
510
Austin Schuhb8bca732021-07-30 22:32:00 -0700511NewDataWriter *LocalLogNamer::MakeForwardedTimestampWriter(
Austin Schuhcb5601b2020-09-10 15:29:59 -0700512 const Channel * /*channel*/, const Node * /*node*/) {
513 LOG(FATAL) << "Can't log forwarded timestamps in a singe log file.";
514 return nullptr;
515}
Austin Schuhcb5601b2020-09-10 15:29:59 -0700516MultiNodeLogNamer::MultiNodeLogNamer(std::string_view base_name,
Austin Schuha499cea2021-07-31 19:49:53 -0700517 EventLoop *event_loop)
Austin Schuh5b728b72021-06-16 14:57:15 -0700518 : MultiNodeLogNamer(base_name, event_loop->configuration(), event_loop,
519 event_loop->node()) {}
520
521MultiNodeLogNamer::MultiNodeLogNamer(std::string_view base_name,
522 const Configuration *configuration,
523 EventLoop *event_loop, const Node *node)
524 : LogNamer(configuration, event_loop, node),
525 base_name_(base_name),
526 old_base_name_() {}
Austin Schuhcb5601b2020-09-10 15:29:59 -0700527
Brian Silverman48deab12020-09-30 18:39:28 -0700528MultiNodeLogNamer::~MultiNodeLogNamer() {
529 if (!ran_out_of_space_) {
530 // This handles renaming temporary files etc.
531 Close();
532 }
533}
534
Austin Schuh572924a2021-07-30 22:32:12 -0700535void MultiNodeLogNamer::Rotate(const Node *node) {
Austin Schuhcb5601b2020-09-10 15:29:59 -0700536 if (node == this->node()) {
Austin Schuhb8bca732021-07-30 22:32:00 -0700537 if (data_writer_) {
Austin Schuh572924a2021-07-30 22:32:12 -0700538 data_writer_->Rotate();
Brian Silvermancb805822020-10-06 17:43:35 -0700539 }
Austin Schuhcb5601b2020-09-10 15:29:59 -0700540 } else {
Austin Schuhb8bca732021-07-30 22:32:00 -0700541 for (std::pair<const Channel *const, NewDataWriter> &data_writer :
Austin Schuhcb5601b2020-09-10 15:29:59 -0700542 data_writers_) {
Austin Schuh572924a2021-07-30 22:32:12 -0700543 if (node == data_writer.second.node()) {
544 data_writer.second.Rotate();
Austin Schuhcb5601b2020-09-10 15:29:59 -0700545 }
546 }
547 }
548}
549
Austin Schuh8c399962020-12-25 21:51:45 -0800550void MultiNodeLogNamer::WriteConfiguration(
551 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> *header,
552 std::string_view config_sha256) {
553 if (ran_out_of_space_) {
554 return;
555 }
556
557 const std::string_view separator = base_name_.back() == '/' ? "" : "_";
558 const std::string filename = absl::StrCat(
559 base_name_, separator, config_sha256, ".bfbs", extension_, temp_suffix_);
560
561 std::unique_ptr<DetachedBufferWriter> writer =
562 std::make_unique<DetachedBufferWriter>(filename, encoder_factory_());
563
564 writer->QueueSizedFlatbuffer(header->Release());
565
566 if (!writer->ran_out_of_space()) {
Austin Schuh5b728b72021-06-16 14:57:15 -0700567 all_filenames_.emplace_back(
568 absl::StrCat(config_sha256, ".bfbs", extension_));
Austin Schuh8c399962020-12-25 21:51:45 -0800569 }
570 CloseWriter(&writer);
571}
572
Austin Schuhb8bca732021-07-30 22:32:00 -0700573NewDataWriter *MultiNodeLogNamer::MakeWriter(const Channel *channel) {
Austin Schuhcb5601b2020-09-10 15:29:59 -0700574 // See if we can read the data on this node at all.
575 const bool is_readable =
576 configuration::ChannelIsReadableOnNode(channel, this->node());
577 if (!is_readable) {
578 return nullptr;
579 }
580
581 // Then, see if we are supposed to log the data here.
582 const bool log_message =
583 configuration::ChannelMessageIsLoggedOnNode(channel, this->node());
584
585 if (!log_message) {
586 return nullptr;
587 }
588
589 // Now, sort out if this is data generated on this node, or not. It is
590 // generated if it is sendable on this node.
591 if (configuration::ChannelIsSendableOnNode(channel, this->node())) {
Austin Schuhb8bca732021-07-30 22:32:00 -0700592 if (!data_writer_) {
Brian Silvermancb805822020-10-06 17:43:35 -0700593 OpenDataWriter();
594 }
Austin Schuhb8bca732021-07-30 22:32:00 -0700595 return data_writer_.get();
Austin Schuhcb5601b2020-09-10 15:29:59 -0700596 }
597
598 // Ok, we have data that is being forwarded to us that we are supposed to
599 // log. It needs to be logged with send timestamps, but be sorted enough
600 // to be able to be processed.
601 CHECK(data_writers_.find(channel) == data_writers_.end());
602
603 // Track that this node is being logged.
604 const Node *source_node = configuration::GetNode(
605 configuration_, channel->source_node()->string_view());
606
607 if (std::find(nodes_.begin(), nodes_.end(), source_node) == nodes_.end()) {
608 nodes_.emplace_back(source_node);
609 }
610
Austin Schuh572924a2021-07-30 22:32:12 -0700611 NewDataWriter data_writer(this, source_node,
612 [this, channel](NewDataWriter *data_writer) {
613 OpenWriter(channel, data_writer);
614 },
615 [this](NewDataWriter *data_writer) {
616 CloseWriter(&data_writer->writer);
617 });
Austin Schuhb8bca732021-07-30 22:32:00 -0700618 return &(
619 data_writers_.emplace(channel, std::move(data_writer)).first->second);
Austin Schuhcb5601b2020-09-10 15:29:59 -0700620}
621
Austin Schuhb8bca732021-07-30 22:32:00 -0700622NewDataWriter *MultiNodeLogNamer::MakeForwardedTimestampWriter(
Austin Schuhcb5601b2020-09-10 15:29:59 -0700623 const Channel *channel, const Node *node) {
624 // See if we can read the data on this node at all.
625 const bool is_readable =
626 configuration::ChannelIsReadableOnNode(channel, this->node());
627 CHECK(is_readable) << ": " << configuration::CleanedChannelToString(channel);
628
629 CHECK(data_writers_.find(channel) == data_writers_.end());
630
631 if (std::find(nodes_.begin(), nodes_.end(), node) == nodes_.end()) {
632 nodes_.emplace_back(node);
633 }
634
Austin Schuh5b728b72021-06-16 14:57:15 -0700635 NewDataWriter data_writer(this, configuration::GetNode(configuration_, node),
Austin Schuh572924a2021-07-30 22:32:12 -0700636 [this, channel](NewDataWriter *data_writer) {
637 OpenForwardedTimestampWriter(channel,
638 data_writer);
639 },
640 [this](NewDataWriter *data_writer) {
641 CloseWriter(&data_writer->writer);
642 });
Austin Schuhb8bca732021-07-30 22:32:00 -0700643 return &(
644 data_writers_.emplace(channel, std::move(data_writer)).first->second);
Austin Schuhcb5601b2020-09-10 15:29:59 -0700645}
646
Austin Schuhb8bca732021-07-30 22:32:00 -0700647NewDataWriter *MultiNodeLogNamer::MakeTimestampWriter(const Channel *channel) {
Brian Silverman0465fcf2020-09-24 00:29:18 -0700648 bool log_delivery_times = false;
649 if (this->node() != nullptr) {
650 log_delivery_times = configuration::ConnectionDeliveryTimeIsLoggedOnNode(
651 channel, this->node(), this->node());
652 }
Austin Schuhcb5601b2020-09-10 15:29:59 -0700653 if (!log_delivery_times) {
654 return nullptr;
655 }
656
Austin Schuhb8bca732021-07-30 22:32:00 -0700657 if (!data_writer_) {
Brian Silvermancb805822020-10-06 17:43:35 -0700658 OpenDataWriter();
659 }
Austin Schuhb8bca732021-07-30 22:32:00 -0700660 return data_writer_.get();
Austin Schuhcb5601b2020-09-10 15:29:59 -0700661}
662
Brian Silverman0465fcf2020-09-24 00:29:18 -0700663void MultiNodeLogNamer::Close() {
Austin Schuhb8bca732021-07-30 22:32:00 -0700664 data_writers_.clear();
665 data_writer_.reset();
Brian Silvermancb805822020-10-06 17:43:35 -0700666}
667
668void MultiNodeLogNamer::ResetStatistics() {
Austin Schuhb8bca732021-07-30 22:32:00 -0700669 for (std::pair<const Channel *const, NewDataWriter> &data_writer :
Brian Silvermancb805822020-10-06 17:43:35 -0700670 data_writers_) {
Austin Schuhad0cfc32020-12-21 12:34:26 -0800671 if (!data_writer.second.writer) continue;
Brian Silvermancb805822020-10-06 17:43:35 -0700672 data_writer.second.writer->ResetStatistics();
Brian Silverman0465fcf2020-09-24 00:29:18 -0700673 }
Austin Schuhb8bca732021-07-30 22:32:00 -0700674 if (data_writer_) {
675 data_writer_->writer->ResetStatistics();
Brian Silvermancb805822020-10-06 17:43:35 -0700676 }
677 max_write_time_ = std::chrono::nanoseconds::zero();
678 max_write_time_bytes_ = -1;
679 max_write_time_messages_ = -1;
680 total_write_time_ = std::chrono::nanoseconds::zero();
681 total_write_count_ = 0;
682 total_write_messages_ = 0;
683 total_write_bytes_ = 0;
Brian Silverman0465fcf2020-09-24 00:29:18 -0700684}
685
Austin Schuhb8bca732021-07-30 22:32:00 -0700686void MultiNodeLogNamer::OpenForwardedTimestampWriter(
687 const Channel *channel, NewDataWriter *data_writer) {
Austin Schuhcb5601b2020-09-10 15:29:59 -0700688 std::string filename =
Austin Schuhe715eae2020-10-10 15:39:30 -0700689 absl::StrCat("timestamps", channel->name()->string_view(), "/",
Brian Silvermana621f522020-09-30 16:52:43 -0700690 channel->type()->string_view(), ".part",
Austin Schuh572924a2021-07-30 22:32:12 -0700691 data_writer->parts_index(), ".bfbs", extension_);
Brian Silverman0465fcf2020-09-24 00:29:18 -0700692 CreateBufferWriter(filename, &data_writer->writer);
Austin Schuhcb5601b2020-09-10 15:29:59 -0700693}
694
695void MultiNodeLogNamer::OpenWriter(const Channel *channel,
Austin Schuhb8bca732021-07-30 22:32:00 -0700696 NewDataWriter *data_writer) {
Austin Schuhcb5601b2020-09-10 15:29:59 -0700697 const std::string filename = absl::StrCat(
Austin Schuhe715eae2020-10-10 15:39:30 -0700698 CHECK_NOTNULL(channel->source_node())->string_view(), "_data",
Brian Silvermana621f522020-09-30 16:52:43 -0700699 channel->name()->string_view(), "/", channel->type()->string_view(),
Austin Schuh572924a2021-07-30 22:32:12 -0700700 ".part", data_writer->parts_index(), ".bfbs", extension_);
Brian Silverman0465fcf2020-09-24 00:29:18 -0700701 CreateBufferWriter(filename, &data_writer->writer);
Austin Schuhcb5601b2020-09-10 15:29:59 -0700702}
703
Brian Silvermana621f522020-09-30 16:52:43 -0700704void MultiNodeLogNamer::OpenDataWriter() {
Austin Schuhb8bca732021-07-30 22:32:00 -0700705 if (!data_writer_) {
706 data_writer_ = std::make_unique<NewDataWriter>(
Austin Schuh572924a2021-07-30 22:32:12 -0700707 this, node_,
Austin Schuhb8bca732021-07-30 22:32:00 -0700708 [this](NewDataWriter *writer) {
709 std::string name;
710 if (node() != nullptr) {
711 name = absl::StrCat(name, node()->name()->string_view(), "_");
712 }
Austin Schuh572924a2021-07-30 22:32:12 -0700713 absl::StrAppend(&name, "data.part", writer->parts_index(), ".bfbs",
Austin Schuhb8bca732021-07-30 22:32:00 -0700714 extension_);
715 CreateBufferWriter(name, &writer->writer);
716 },
717 [this](NewDataWriter *data_writer) {
718 CloseWriter(&data_writer->writer);
719 });
Brian Silverman7af8c902020-09-29 16:14:04 -0700720 }
Austin Schuhcb5601b2020-09-10 15:29:59 -0700721}
722
Brian Silverman0465fcf2020-09-24 00:29:18 -0700723void MultiNodeLogNamer::CreateBufferWriter(
Brian Silvermana621f522020-09-30 16:52:43 -0700724 std::string_view path, std::unique_ptr<DetachedBufferWriter> *destination) {
Brian Silverman0465fcf2020-09-24 00:29:18 -0700725 if (ran_out_of_space_) {
726 // Refuse to open any new files, which might skip data. Any existing files
727 // are in the same folder, which means they're on the same filesystem, which
728 // means they're probably going to run out of space and get stuck too.
Austin Schuha426f1f2021-03-31 22:27:41 -0700729 if (!destination->get()) {
730 // But avoid leaving a nullptr writer if we're out of space when
731 // attempting to open the first file.
732 *destination = std::make_unique<DetachedBufferWriter>(
733 DetachedBufferWriter::already_out_of_space_t());
734 }
Brian Silverman0465fcf2020-09-24 00:29:18 -0700735 return;
736 }
Austin Schuhe715eae2020-10-10 15:39:30 -0700737 const std::string_view separator = base_name_.back() == '/' ? "" : "_";
738 const std::string filename =
739 absl::StrCat(base_name_, separator, path, temp_suffix_);
Brian Silverman0465fcf2020-09-24 00:29:18 -0700740 if (!destination->get()) {
Brian Silvermana9f2ec92020-10-06 18:00:53 -0700741 if (ran_out_of_space_) {
742 *destination = std::make_unique<DetachedBufferWriter>(
743 DetachedBufferWriter::already_out_of_space_t());
744 return;
745 }
Brian Silvermancb805822020-10-06 17:43:35 -0700746 *destination =
747 std::make_unique<DetachedBufferWriter>(filename, encoder_factory_());
Brian Silvermana9f2ec92020-10-06 18:00:53 -0700748 if (!destination->get()->ran_out_of_space()) {
749 all_filenames_.emplace_back(path);
750 }
Brian Silverman0465fcf2020-09-24 00:29:18 -0700751 return;
752 }
Brian Silvermancb805822020-10-06 17:43:35 -0700753
754 CloseWriter(destination);
755 if (ran_out_of_space_) {
Brian Silvermana9f2ec92020-10-06 18:00:53 -0700756 *destination->get() =
757 DetachedBufferWriter(DetachedBufferWriter::already_out_of_space_t());
Brian Silverman0465fcf2020-09-24 00:29:18 -0700758 return;
759 }
Brian Silvermana9f2ec92020-10-06 18:00:53 -0700760
Brian Silvermancb805822020-10-06 17:43:35 -0700761 *destination->get() = DetachedBufferWriter(filename, encoder_factory_());
Brian Silvermana9f2ec92020-10-06 18:00:53 -0700762 if (!destination->get()->ran_out_of_space()) {
763 all_filenames_.emplace_back(path);
764 }
Brian Silverman0465fcf2020-09-24 00:29:18 -0700765}
766
Brian Silverman48deab12020-09-30 18:39:28 -0700767void MultiNodeLogNamer::RenameTempFile(DetachedBufferWriter *destination) {
768 if (temp_suffix_.empty()) {
769 return;
770 }
Austin Schuh6bb8a822021-03-31 23:04:39 -0700771 std::string current_filename = std::string(destination->filename());
Brian Silverman48deab12020-09-30 18:39:28 -0700772 CHECK(current_filename.size() > temp_suffix_.size());
Austin Schuh6bb8a822021-03-31 23:04:39 -0700773 std::string final_filename =
Brian Silverman48deab12020-09-30 18:39:28 -0700774 current_filename.substr(0, current_filename.size() - temp_suffix_.size());
Austin Schuh6bb8a822021-03-31 23:04:39 -0700775 int result = rename(current_filename.c_str(), final_filename.c_str());
776
777 // When changing the base name, we rename the log folder while there active
778 // buffer writers. Therefore, the name of that active buffer may still refer
779 // to the old file location rather than the new one. This minimized changes to
780 // existing code.
781 if (result != 0 && errno != ENOSPC && !old_base_name_.empty()) {
782 auto offset = current_filename.find(old_base_name_);
783 if (offset != std::string::npos) {
784 current_filename.replace(offset, old_base_name_.length(), base_name_);
785 }
786 offset = final_filename.find(old_base_name_);
787 if (offset != std::string::npos) {
788 final_filename.replace(offset, old_base_name_.length(), base_name_);
789 }
790 result = rename(current_filename.c_str(), final_filename.c_str());
791 }
792
Brian Silverman48deab12020-09-30 18:39:28 -0700793 if (result != 0) {
794 if (errno == ENOSPC) {
795 ran_out_of_space_ = true;
796 return;
797 } else {
798 PLOG(FATAL) << "Renaming " << current_filename << " to " << final_filename
799 << " failed";
800 }
Austin Schuh6bb8a822021-03-31 23:04:39 -0700801 } else {
802 VLOG(1) << "Renamed " << current_filename << " -> " << final_filename;
Brian Silverman48deab12020-09-30 18:39:28 -0700803 }
804}
805
Brian Silvermancb805822020-10-06 17:43:35 -0700806void MultiNodeLogNamer::CloseWriter(
807 std::unique_ptr<DetachedBufferWriter> *writer_pointer) {
808 DetachedBufferWriter *const writer = writer_pointer->get();
809 if (!writer) {
810 return;
811 }
Brian Silvermana9f2ec92020-10-06 18:00:53 -0700812 const bool was_open = writer->is_open();
Brian Silvermancb805822020-10-06 17:43:35 -0700813 writer->Close();
814
815 if (writer->max_write_time() > max_write_time_) {
816 max_write_time_ = writer->max_write_time();
817 max_write_time_bytes_ = writer->max_write_time_bytes();
818 max_write_time_messages_ = writer->max_write_time_messages();
819 }
820 total_write_time_ += writer->total_write_time();
821 total_write_count_ += writer->total_write_count();
822 total_write_messages_ += writer->total_write_messages();
823 total_write_bytes_ += writer->total_write_bytes();
824
825 if (writer->ran_out_of_space()) {
826 ran_out_of_space_ = true;
827 writer->acknowledge_out_of_space();
828 }
Brian Silvermana9f2ec92020-10-06 18:00:53 -0700829 if (was_open) {
830 RenameTempFile(writer);
831 } else {
832 CHECK(access(std::string(writer->filename()).c_str(), F_OK) == -1)
833 << ": File should not exist: " << writer->filename();
834 }
Brian Silvermancb805822020-10-06 17:43:35 -0700835}
836
Austin Schuhcb5601b2020-09-10 15:29:59 -0700837} // namespace logger
838} // namespace aos