1 // Copyright 2020 The Pigweed Authors
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
7 // https://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
17 #include "pw_bytes/span.h"
18 #include "pw_result/result.h"
19 #include "pw_ring_buffer/prefixed_entry_ring_buffer.h"
20 #include "pw_status/status.h"
21 #include "pw_status/status_with_size.h"
23 // LogQueue is a ring-buffer queue of log messages. LogQueue is backed by
24 // a caller-provided byte array and stores its messages in the format
25 // dictated by the pw_rpc_log log.proto format.
27 // Logs can be returned as a repeated proto message and the output of this
28 // class can be directly fed into an RPC stream.
31 // 0) Create LogQueue instance.
32 // 1) LogQueue::PushTokenizedMessage().
35 // 0) Use exsiting LogQueue instance.
36 // 1) For single entires, LogQueue::Pop().
37 // 2) For multiple entries, LogQueue::PopMultiple().
38 namespace pw::log_rpc {
42 LogQueue(ByteSpan log_buffer, ByteSpan encode_buffer)
43 : encode_buffer_(encode_buffer), ring_buffer_(true) {
44 ring_buffer_.SetBuffer(log_buffer);
47 LogQueue(const LogQueue&) = delete;
48 LogQueue& operator=(const LogQueue&) = delete;
49 LogQueue(LogQueue&&) = delete;
50 LogQueue& operator=(LogQueue&&) = delete;
52 // Construct a LogEntry proto message and push it into the ring buffer.
56 // FAILED_PRECONDITION - Failed when encoding the proto message.
57 // RESOURCE_EXHAUSTED - Not enough space in the buffer to write the entry.
58 pw::Status PushTokenizedMessage(ConstByteSpan message,
65 // Pop the oldest LogEntry from the queue into the provided buffer.
66 // On success, the size is the length of the entry, on failure, the size is 0.
69 // For now, don't support batching. This will always use a single absolute
70 // timestamp, and not use delta encoding.
73 // OUT_OF_RANGE - No entries in queue to read.
74 // RESOURCE_EXHAUSTED - Destination data std::span was smaller number of
75 // bytes than the data size of the data chunk being read. Available
76 // destination bytes were filled, remaining bytes of the data chunk were
78 pw::Result<ConstByteSpan> Pop(ByteSpan entry_buffer);
80 // Pop entries from the queue into the provided buffer. The provided buffer is
81 // filled until there is insufficient space for the next log entry.
84 pw::Result<ConstByteSpan> PopMultiple(ByteSpan entries_buffer);
87 size_t dropped_entries_;
88 int64_t latest_dropped_timestamp_;
90 ByteSpan encode_buffer_;
91 pw::ring_buffer::PrefixedEntryRingBuffer ring_buffer_{true};
94 // LogQueueWithEncodeBuffer is a LogQueue where the internal encode buffer is
95 // created and managed by this class.
96 template <size_t kEncodeBufferSize>
97 class LogQueueWithEncodeBuffer : public LogQueue {
99 LogQueueWithEncodeBuffer(ByteSpan log_buffer)
100 : LogQueue(log_buffer, encode_buffer_) {}
103 std::byte encode_buffer_[kEncodeBufferSize];
106 } // namespace pw::log_rpc