blob: 7611cb876d03fc4e07d7ce4ef7743db3ab267257 [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"
12#include "aos/events/logging/uuid.h"
13#include "flatbuffers/flatbuffers.h"
14
15namespace aos {
16namespace logger {
17
18// Interface describing how to name, track, and add headers to log file parts.
19class LogNamer {
20 public:
21 // Constructs a LogNamer with the primary node (ie the one the logger runs on)
22 // being node.
23 LogNamer(const Node *node) : node_(node) { nodes_.emplace_back(node_); }
24 virtual ~LogNamer() {}
25
26 // Writes the header to all log files for a specific node. This function
27 // needs to be called after all the writers are created.
28 //
29 // Modifies header to contain the uuid and part number for each writer as it
30 // writes it. Since this is done unconditionally, it does not restore the
31 // previous value at the end.
32 virtual void WriteHeader(
33 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> *header,
34 const Node *node) = 0;
35
Brian Silverman87ac0402020-09-17 14:47:01 -070036 // Returns a writer for writing data from messages on this channel (on the
37 // primary node).
38 //
39 // The returned pointer will stay valid across rotations, but the object it
40 // points to will be assigned to.
Austin Schuhcb5601b2020-09-10 15:29:59 -070041 virtual DetachedBufferWriter *MakeWriter(const Channel *channel) = 0;
42
Brian Silverman87ac0402020-09-17 14:47:01 -070043 // Returns a writer for writing timestamps from messages on this channel (on
44 // the primary node).
45 //
46 // The returned pointer will stay valid across rotations, but the object it
47 // points to will be assigned to.
Austin Schuhcb5601b2020-09-10 15:29:59 -070048 virtual DetachedBufferWriter *MakeTimestampWriter(const Channel *channel) = 0;
49
50 // Returns a writer for writing timestamps delivered over the special
51 // /aos/remote_timestamps/* channels. node is the node that the timestamps
Brian Silverman87ac0402020-09-17 14:47:01 -070052 // are forwarded back from (to the primary node).
53 //
54 // The returned pointer will stay valid across rotations, but the object it
55 // points to will be assigned to.
Austin Schuhcb5601b2020-09-10 15:29:59 -070056 virtual DetachedBufferWriter *MakeForwardedTimestampWriter(
57 const Channel *channel, const Node *node) = 0;
58
59 // Rotates all log files for the provided node. The provided header will be
60 // modified and written per WriteHeader above.
61 virtual void Rotate(
62 const Node *node,
63 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> *header) = 0;
64
65 // Returns all the nodes that data is being written for.
66 const std::vector<const Node *> &nodes() const { return nodes_; }
67
68 // Returns the node the logger is running on.
69 const Node *node() const { return node_; }
70
71 protected:
72 // Modifies the header to have the provided UUID and part id.
73 void UpdateHeader(
74 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> *header,
75 const UUID &uuid, int part_id) const;
76
77 const Node *const node_;
78 std::vector<const Node *> nodes_;
79};
80
81// Local log namer is a simple version which only names things
82// "base_name.part#.bfbs" and increments the part number. It doesn't support
83// any other log type.
84class LocalLogNamer : public LogNamer {
85 public:
86 LocalLogNamer(std::string_view base_name, const Node *node)
87 : LogNamer(node),
88 base_name_(base_name),
89 uuid_(UUID::Random()),
90 data_writer_(OpenDataWriter()) {}
91
92 void WriteHeader(
93 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> *header,
94 const Node *node) override;
95
96 DetachedBufferWriter *MakeWriter(const Channel *channel) override;
97
98 void Rotate(const Node *node,
99 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> *header)
100 override;
101
102 DetachedBufferWriter *MakeTimestampWriter(const Channel *channel) override;
103
104 DetachedBufferWriter *MakeForwardedTimestampWriter(
105 const Channel * /*channel*/, const Node * /*node*/) override;
106
107 private:
108 // Creates a new data writer with the new part number.
109 std::unique_ptr<DetachedBufferWriter> OpenDataWriter() {
110 return std::make_unique<DetachedBufferWriter>(
111 absl::StrCat(base_name_, ".part", part_number_, ".bfbs"));
112 }
113
114 const std::string base_name_;
115 const UUID uuid_;
116 size_t part_number_ = 0;
117 std::unique_ptr<DetachedBufferWriter> data_writer_;
118};
119
120// Log namer which uses a config and a base name to name a bunch of files.
121class MultiNodeLogNamer : public LogNamer {
122 public:
123 MultiNodeLogNamer(std::string_view base_name,
124 const Configuration *configuration, const Node *node);
125
126 void WriteHeader(
127 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> *header,
128 const Node *node) override;
129
130 void Rotate(const Node *node,
131 aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> *header)
132 override;
133
134 DetachedBufferWriter *MakeWriter(const Channel *channel) override;
135
Brian Silvermand90905f2020-09-23 14:42:56 -0700136 DetachedBufferWriter *MakeForwardedTimestampWriter(const Channel *channel,
137 const Node *node) override;
Austin Schuhcb5601b2020-09-10 15:29:59 -0700138
139 DetachedBufferWriter *MakeTimestampWriter(const Channel *channel) override;
140
141 private:
142 // Files to write remote data to. We want one per channel. Maps the channel
143 // to the writer, Node, and part number.
144 struct DataWriter {
145 std::unique_ptr<DetachedBufferWriter> writer = nullptr;
146 const Node *node;
147 size_t part_number = 0;
148 UUID uuid = UUID::Random();
149 std::function<void(const Channel *, DataWriter *)> rotate;
150 };
151
152 // Opens up a writer for timestamps forwarded back.
153 void OpenForwardedTimestampWriter(const Channel *channel,
154 DataWriter *data_writer);
155
156 // Opens up a writer for remote data.
157 void OpenWriter(const Channel *channel, DataWriter *data_writer);
158
159 // Opens the main data writer file for this node responsible for data_writer_.
160 std::unique_ptr<DetachedBufferWriter> OpenDataWriter();
161
162 const std::string base_name_;
163 const Configuration *const configuration_;
164 const UUID uuid_;
165
166 size_t part_number_ = 0;
167
168 // File to write both delivery timestamps and local data to.
169 std::unique_ptr<DetachedBufferWriter> data_writer_;
170
171 std::map<const Channel *, DataWriter> data_writers_;
172};
173
174} // namespace logger
175} // namespace aos
176
177#endif // AOS_EVENTS_LOGGING_LOG_NAMER_H_