aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Chinchilla <cachinchilla@google.com>2022-02-23 13:30:59 -0800
committerCQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-03-24 20:39:34 +0000
commitc3fdc020654fce2b5482ff98ef9ca8214ebd239c (patch)
tree769a268991577f8d2a4a311cd9fe13d179b0095e
parenta1cd0344e259f94de128268150db4c9f88a41e2d (diff)
downloadpigweed-c3fdc020654fce2b5482ff98ef9ca8214ebd239c.tar.gz
pw_log_rpc: Send drop reason message
Independently track each log drop reason and report it in the log drop message when possible. Increase the minimum log encode buffer size to fit the largest error message. Fixes: 630 Change-Id: I18c8f73eb8e5a1ece7767a5b3309de72cfd1c3ec Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/85480 Reviewed-by: Armando Montanez <amontanez@google.com> Commit-Queue: Carlos Chinchilla <cachinchilla@google.com> Pigweed-Auto-Submit: Carlos Chinchilla <cachinchilla@google.com>
-rw-r--r--pw_log_rpc/BUILD.bazel5
-rw-r--r--pw_log_rpc/BUILD.gn1
-rw-r--r--pw_log_rpc/docs.rst52
-rw-r--r--pw_log_rpc/log_service_test.cc38
-rw-r--r--pw_log_rpc/public/pw_log_rpc/internal/config.h31
-rw-r--r--pw_log_rpc/public/pw_log_rpc/rpc_log_drain.h39
-rw-r--r--pw_log_rpc/rpc_log_drain.cc109
7 files changed, 210 insertions, 65 deletions
diff --git a/pw_log_rpc/BUILD.bazel b/pw_log_rpc/BUILD.bazel
index 52f857072..dab90830d 100644
--- a/pw_log_rpc/BUILD.bazel
+++ b/pw_log_rpc/BUILD.bazel
@@ -78,7 +78,10 @@ pw_cc_library(
pw_cc_library(
name = "rpc_log_drain",
- srcs = ["rpc_log_drain.cc"],
+ srcs = [
+ "public/pw_log_rpc/internal/config.h",
+ "rpc_log_drain.cc",
+ ],
hdrs = [
"public/pw_log_rpc/rpc_log_drain.h",
"public/pw_log_rpc/rpc_log_drain_map.h",
diff --git a/pw_log_rpc/BUILD.gn b/pw_log_rpc/BUILD.gn
index 349324807..bfe2f6adf 100644
--- a/pw_log_rpc/BUILD.gn
+++ b/pw_log_rpc/BUILD.gn
@@ -99,6 +99,7 @@ pw_source_set("rpc_log_drain") {
]
sources = [ "rpc_log_drain.cc" ]
public_deps = [
+ ":config",
":log_filter",
"$dir_pw_assert",
"$dir_pw_chrono:system_clock",
diff --git a/pw_log_rpc/docs.rst b/pw_log_rpc/docs.rst
index e2c0b24d0..cf98d85e1 100644
--- a/pw_log_rpc/docs.rst
+++ b/pw_log_rpc/docs.rst
@@ -205,21 +205,47 @@ possible. Logs can be dropped when
- They don't pass a filter. This is the expected behavior, so filtered logs will
not be tracked as dropped logs.
- The drains are too slow to keep up. In this case, the ring buffer is full of
- undrained entries; when new logs come in, old entries are dropped. [#f1]_
+ undrained entries; when new logs come in, old entries are dropped. The log
+ stream will contain a ``LogEntry`` message with the number of dropped logs.
+ E.g.
+
+ Dropped 15 logs due to slow reader
+
- There is an error creating or adding a new log entry, and the ring buffer is
- notified that the log had to be dropped. [#f1]_
-- A log entry is too large for the outbound buffer. [#f2]_
-- There are detected errors transmitting log entries. [#f2]_
+ notified that the log had to be dropped. The log stream will contain a
+ ``LogEntry`` message with the number of dropped logs.
+ E.g.
+
+ Dropped 15 logs due to slow reader
+
+- A log entry is too large for the stack buffer. The log stream will contain
+ an error message with the drop count. Provide a log buffer that fits the
+ largest entry added to the MultiSink to avoid this error.
+ E.g.
+
+ Dropped 1 log due to stack buffer too small
+
+- A log entry is too large for the outbound buffer. The log stream will contain
+ an error message with the drop count. Provide a log buffer that fits the
+ largest entry added to the MultiSink to avoid this error.
+ E.g.
+
+ Dropped 1 log due to outbound buffer too small
+
+- There are detected errors transmitting log entries. The log stream will
+ contain a ``LogEntry`` with an error message and the number of dropped logs
+ the next time the stream is flushed only if the drain's error handling is set
+ to close the stream on error.
+ E.g.
+
+ Dropped 10 logs due to writer error
+
- There are undetected errors transmitting or receiving log entries, such as an
- interface interruption. [#f3]_
-
-.. [#f1] The log stream will contain a ``LogEntry`` message with the number of
- dropped logs.
-.. [#f2] The log stream will contain a ``LogEntry`` message with the number of
- dropped logs the next time the stream is flushed only if the drain's
- error handling is set to close the stream on error.
-.. [#f3] Clients can calculate the number of logs lost in transit using the
- sequence ID and number of entries in each stream packet.
+ interface interruption. Clients can calculate the number of logs lost in
+ transit using the sequence ID and number of entries in each stream packet.
+ E.g.
+
+ Dropped 50 logs due to transmission error
The drop count is combined when possible, and reported only when an entry, that
passes any filters, is going to be sent.
diff --git a/pw_log_rpc/log_service_test.cc b/pw_log_rpc/log_service_test.cc
index 062ebdb61..1072ec55b 100644
--- a/pw_log_rpc/log_service_test.cc
+++ b/pw_log_rpc/log_service_test.cc
@@ -46,7 +46,7 @@ using log::pw_rpc::raw::Logs;
constexpr size_t kMaxMessageSize = 50;
constexpr size_t kMaxLogEntrySize =
- RpcLogDrain::kMinEntrySizeWithoutPayload + kMaxMessageSize;
+ RpcLogDrain::kMinEntryBufferSize + kMaxMessageSize;
static_assert(RpcLogDrain::kMinEntryBufferSize < kMaxLogEntrySize);
constexpr size_t kMultiSinkBufferSize = kMaxLogEntrySize * 10;
constexpr size_t kMaxDrains = 3;
@@ -57,7 +57,8 @@ constexpr char kMessage[] = "message";
constexpr char kLongMessage[] =
"This is a long log message that will be dropped.";
static_assert(sizeof(kLongMessage) < kMaxMessageSize);
-static_assert(sizeof(kLongMessage) > RpcLogDrain::kMinEntryBufferSize);
+static_assert(sizeof(kLongMessage) + RpcLogDrain::kMinEntrySizeWithoutPayload >
+ RpcLogDrain::kMinEntryBufferSize);
std::array<std::byte, 1> rpc_request_buffer;
constexpr auto kSampleMetadata =
log_tokenized::Metadata::Set<PW_LOG_LEVEL_INFO, 123, 0x03, __LINE__>();
@@ -276,7 +277,10 @@ TEST_F(LogServiceTest, HandleDropped) {
std::span(std::string_view(kMessage)))});
}
expected_messages.push_back(
- {.metadata = kDropMessageMetadata, .dropped = total_drop_count});
+ {.metadata = kDropMessageMetadata,
+ .dropped = total_drop_count,
+ .tokenized_data = std::as_bytes(
+ std::span(std::string_view(RpcLogDrain::kIngressErrorMessage)))});
for (; i < total_entries; ++i) {
expected_messages.push_back({.metadata = kSampleMetadata,
.timestamp = kSampleTimestamp,
@@ -335,7 +339,10 @@ TEST_F(LogServiceTest, HandleDroppedBetweenFilteredOutLogs) {
Vector<TestLogEntry, 2> expected_messages;
expected_messages.push_back(
- {.metadata = kDropMessageMetadata, .dropped = total_drop_count});
+ {.metadata = kDropMessageMetadata,
+ .dropped = total_drop_count,
+ .tokenized_data = std::as_bytes(
+ std::span(std::string_view(RpcLogDrain::kIngressErrorMessage)))});
expected_messages.push_back(
{.metadata = metadata,
.timestamp = kSampleTimestamp,
@@ -368,7 +375,7 @@ TEST_F(LogServiceTest, HandleSmallLogEntryBuffer) {
const size_t total_entries = 5;
const uint32_t total_drop_count = total_entries - 1;
AddLogEntries(
- total_entries - 1, kLongMessage, kSampleMetadata, kSampleTimestamp);
+ total_drop_count, kLongMessage, kSampleMetadata, kSampleTimestamp);
EXPECT_EQ(OkStatus(),
AddLogEntry(kMessage, kSampleMetadata, kSampleTimestamp).status());
@@ -379,14 +386,19 @@ TEST_F(LogServiceTest, HandleSmallLogEntryBuffer) {
ASSERT_EQ(context.status(), OkStatus());
ASSERT_EQ(context.responses().size(), 1u);
- Vector<TestLogEntry, 2> expected_messages{
- {.metadata = kDropMessageMetadata, .dropped = total_drop_count},
+ Vector<TestLogEntry, total_entries + 1> expected_messages;
+ expected_messages.push_back(
+ {.metadata = kDropMessageMetadata,
+ .dropped = total_drop_count,
+ .tokenized_data = std::as_bytes(std::span(
+ std::string_view(RpcLogDrain::kSmallStackBufferErrorMessage)))});
+ expected_messages.push_back(
{.metadata = kSampleMetadata,
.timestamp = kSampleTimestamp,
- .tokenized_data = std::as_bytes(std::span(std::string_view(kMessage)))},
- };
+ .tokenized_data = std::as_bytes(std::span(std::string_view(kMessage)))});
- // Verify data in responses.
+ // Expect one drop message with the total drop count, and the only message
+ // that fits the buffer.
size_t entries_found = 0;
uint32_t drop_count_found = 0;
for (auto& response : context.responses()) {
@@ -397,7 +409,6 @@ TEST_F(LogServiceTest, HandleSmallLogEntryBuffer) {
entries_found,
drop_count_found);
}
- // No messages fit the buffer, expect a drop message.
EXPECT_EQ(entries_found, 1u);
EXPECT_EQ(drop_count_found, total_drop_count);
}
@@ -547,7 +558,10 @@ TEST_F(LogServiceTest, InterruptedLogStreamSendsDropCount) {
const uint32_t total_drop_count = entries_found / successful_packets_sent;
Vector<TestLogEntry, max_entries> expected_messages_after_reset;
expected_messages_after_reset.push_back(
- {.metadata = kDropMessageMetadata, .dropped = total_drop_count});
+ {.metadata = kDropMessageMetadata,
+ .dropped = total_drop_count,
+ .tokenized_data = std::as_bytes(
+ std::span(std::string_view(RpcLogDrain::kWriterErrorMessage)))});
const uint32_t remaining_entries = total_entries - total_drop_count;
for (size_t i = 0; i < remaining_entries; ++i) {
diff --git a/pw_log_rpc/public/pw_log_rpc/internal/config.h b/pw_log_rpc/public/pw_log_rpc/internal/config.h
index 89a051d91..9fbcfbfc7 100644
--- a/pw_log_rpc/public/pw_log_rpc/internal/config.h
+++ b/pw_log_rpc/public/pw_log_rpc/internal/config.h
@@ -43,6 +43,37 @@
#define PW_LOG_RPC_CONFIG_LOG_MODULE_NAME "PW_LOG_RPC"
#endif // PW_LOG_RPC_CONFIG_LOG_MODULE_NAME
+// Messages to descrive the log drop reasons.
+// See https://pigweed.dev/pw_log_rpc/#log-drops
+//
+// Message for when an entry could not be added to the MultiSink.
+#ifndef PW_LOG_RPC_INGRESS_ERROR_MSG
+#define PW_LOG_RPC_INGRESS_ERROR_MSG "Ingress error"
+#endif // PW_LOG_RPC_INGRESS_ERROR_MSG
+
+// Message for when a drain drains too slow and has to be advanced, dropping
+// logs.
+#ifndef PW_LOG_RPC_SLOW_DRAIN_MSG
+#define PW_LOG_RPC_SLOW_DRAIN_MSG "Slow drain"
+#endif // PW_LOG_RPC_SLOW_DRAIN_MSG
+
+// Message for when a is too too large to fit in the outbound buffer, so it is
+// dropped.
+#ifndef PW_LOG_RPC_SMALL_OUTBOUND_BUFFER_MSG
+#define PW_LOG_RPC_SMALL_OUTBOUND_BUFFER_MSG "Outbound log buffer too small"
+#endif // PW_LOG_RPC_SMALL_OUTBOUND_BUFFER_MSG
+
+// Message for when the log entry in the MultiSink is too large to be peeked or
+// popped out, so it is dropped.
+#ifndef PW_LOG_RPC_SMALL_STACK_BUFFER_MSG
+#define PW_LOG_RPC_SMALL_STACK_BUFFER_MSG "Stack log buffer too small"
+#endif // PW_LOG_RPC_SMALL_STACK_BUFFER_MSG
+
+// Message for when a bulk of logs cannot be sent due to a writer error.
+#ifndef PW_LOG_RPC_WRITER_ERROR_MSG
+#define PW_LOG_RPC_WRITER_ERROR_MSG "Writer error"
+#endif // PW_LOG_RPC_WRITER_ERROR_MSG
+
namespace pw::log_rpc::cfg {
inline constexpr size_t kMaxModuleNameBytes =
PW_LOG_RPC_CONFIG_MAX_FILTER_RULE_MODULE_NAME_SIZE;
diff --git a/pw_log_rpc/public/pw_log_rpc/rpc_log_drain.h b/pw_log_rpc/public/pw_log_rpc/rpc_log_drain.h
index 0c7dc3922..76dd7e372 100644
--- a/pw_log_rpc/public/pw_log_rpc/rpc_log_drain.h
+++ b/pw_log_rpc/public/pw_log_rpc/rpc_log_drain.h
@@ -14,16 +14,19 @@
#pragma once
+#include <algorithm>
#include <array>
#include <cstdint>
#include <limits>
#include <optional>
+#include <string_view>
#include "pw_assert/assert.h"
#include "pw_bytes/span.h"
#include "pw_chrono/system_clock.h"
#include "pw_function/function.h"
#include "pw_log/proto/log.pwpb.h"
+#include "pw_log_rpc/internal/config.h"
#include "pw_log_rpc/log_filter.h"
#include "pw_multisink/multisink.h"
#include "pw_protobuf/serialized_size.h"
@@ -69,8 +72,28 @@ class RpcLogDrain : public multisink::MultiSink::Drain {
protobuf::SizeOfFieldBytes(log::LogEntry::Fields::FILE, 0) +
protobuf::SizeOfFieldBytes(log::LogEntry::Fields::THREAD, 0);
- // The smallest buffer size must be able to fit a typical token size: 4 bytes.
- static constexpr size_t kMinEntryBufferSize = kMinEntrySizeWithoutPayload + 4;
+ // Error messages sent when logs are dropped.
+ static constexpr std::string_view kIngressErrorMessage{
+ PW_LOG_RPC_INGRESS_ERROR_MSG};
+ static constexpr std::string_view kSlowDrainErrorMessage{
+ PW_LOG_RPC_SLOW_DRAIN_MSG};
+ static constexpr std::string_view kSmallOutboundBufferErrorMessage{
+ PW_LOG_RPC_SMALL_OUTBOUND_BUFFER_MSG};
+ static constexpr std::string_view kSmallStackBufferErrorMessage{
+ PW_LOG_RPC_SMALL_STACK_BUFFER_MSG};
+ static constexpr std::string_view kWriterErrorMessage{
+ PW_LOG_RPC_WRITER_ERROR_MSG};
+ // The smallest entry buffer must fit the largest error message, or a typical
+ // token size (4B), whichever is largest.
+ static constexpr size_t kLargestErrorMessageOrTokenSize =
+ std::max({size_t(4),
+ kIngressErrorMessage.size(),
+ kSlowDrainErrorMessage.size(),
+ kSmallOutboundBufferErrorMessage.size(),
+ kSmallStackBufferErrorMessage.size(),
+ kWriterErrorMessage.size()});
+ static constexpr size_t kMinEntryBufferSize =
+ kMinEntrySizeWithoutPayload + sizeof(kLargestErrorMessageOrTokenSize);
// When encoding LogEntry in LogEntries, there are kLogEntriesEncodeFrameSize
// bytes added to the encoded LogEntry. This constant and kMinEntryBufferSize
@@ -99,7 +122,11 @@ class RpcLogDrain : public multisink::MultiSink::Drain {
error_handling_(error_handling),
server_writer_(),
log_entry_buffer_(log_entry_buffer),
- committed_entry_drop_count_(0),
+ drop_count_ingress_error_(0),
+ drop_count_slow_drain_(0),
+ drop_count_small_outbound_buffer_(0),
+ drop_count_small_stack_buffer_(0),
+ drop_count_writer_error_(0),
mutex_(mutex),
filter_(filter),
sequence_id_(0),
@@ -191,7 +218,11 @@ class RpcLogDrain : public multisink::MultiSink::Drain {
const LogDrainErrorHandling error_handling_;
rpc::RawServerWriter server_writer_ PW_GUARDED_BY(mutex_);
const ByteSpan log_entry_buffer_ PW_GUARDED_BY(mutex_);
- uint32_t committed_entry_drop_count_ PW_GUARDED_BY(mutex_);
+ uint32_t drop_count_ingress_error_ PW_GUARDED_BY(mutex_);
+ uint32_t drop_count_slow_drain_ PW_GUARDED_BY(mutex_);
+ uint32_t drop_count_small_outbound_buffer_ PW_GUARDED_BY(mutex_);
+ uint32_t drop_count_small_stack_buffer_ PW_GUARDED_BY(mutex_);
+ uint32_t drop_count_writer_error_ PW_GUARDED_BY(mutex_);
sync::Mutex& mutex_;
Filter* filter_;
uint32_t sequence_id_;
diff --git a/pw_log_rpc/rpc_log_drain.cc b/pw_log_rpc/rpc_log_drain.cc
index 8b7957142..fe12ba0c8 100644
--- a/pw_log_rpc/rpc_log_drain.cc
+++ b/pw_log_rpc/rpc_log_drain.cc
@@ -17,6 +17,8 @@
#include <limits>
#include <mutex>
#include <optional>
+#include <span>
+#include <string_view>
#include "pw_assert/check.h"
#include "pw_chrono/system_clock.h"
@@ -29,14 +31,29 @@
namespace pw::log_rpc {
namespace {
-// Creates an encoded drop message on the provided buffer.
-Result<ConstByteSpan> CreateEncodedDropMessage(
- uint32_t drop_count, ByteSpan encoded_drop_message_buffer) {
- // Encode message in protobuf.
+// Creates an encoded drop message on the provided buffer and adds it to the
+// bulk log entries. Resets the drop count when successfull.
+void TryEncodeDropMessage(ByteSpan encoded_drop_message_buffer,
+ std::string_view reason,
+ uint32_t& drop_count,
+ log::LogEntries::MemoryEncoder& entries_encoder) {
+ // Encode drop count and reason, if any, in log proto.
log::LogEntry::MemoryEncoder encoder(encoded_drop_message_buffer);
+ if (!reason.empty()) {
+ encoder.WriteMessage(std::as_bytes(std::span(reason))).IgnoreError();
+ }
encoder.WriteDropped(drop_count).IgnoreError();
- PW_TRY(encoder.status());
- return ConstByteSpan(encoder);
+ if (!encoder.status().ok()) {
+ return;
+ }
+ // Add encoded drop messsage if fits in buffer.
+ ConstByteSpan drop_message(encoder);
+ if (drop_message.size() + RpcLogDrain::kLogEntriesEncodeFrameSize <
+ entries_encoder.ConservativeWriteLimit()) {
+ PW_CHECK_OK(entries_encoder.WriteBytes(
+ static_cast<uint32_t>(log::LogEntries::Fields::ENTRIES), drop_message));
+ drop_count = 0;
+ }
}
} // namespace
@@ -114,7 +131,7 @@ RpcLogDrain::LogDrainState RpcLogDrain::SendLogs(size_t max_num_bundles,
if (!status.ok() &&
error_handling_ == LogDrainErrorHandling::kCloseStreamOnWriterError) {
// Only update this drop count when writer errors are not ignored.
- committed_entry_drop_count_ += packed_entry_count;
+ drop_count_writer_error_ += packed_entry_count;
server_writer_.Finish().IgnoreError();
encoding_status_out = Status::Aborted();
return log_sink_state;
@@ -132,15 +149,11 @@ RpcLogDrain::LogDrainState RpcLogDrain::EncodeOutgoingPacket(
uint32_t ingress_drop_count = 0;
Result<multisink::MultiSink::Drain::PeekedEntry> possible_entry =
PeekEntry(log_entry_buffer_, drop_count, ingress_drop_count);
- // TODO(cachinchilla): remove combining these two drop types when reporting
- // drop reasons individually.
- drop_count += ingress_drop_count;
+ drop_count_ingress_error_ += ingress_drop_count;
// Check if the entry fits in the entry buffer.
if (possible_entry.status().IsResourceExhausted()) {
- // TODO(pwbug/630): track when log doesn't fit in log_entry_buffer_, as
- // this is an issue that could prevent logs from every making it off the
- // device.
+ ++drop_count_small_stack_buffer_;
continue;
}
@@ -148,7 +161,7 @@ RpcLogDrain::LogDrainState RpcLogDrain::EncodeOutgoingPacket(
if (possible_entry.status().IsOutOfRange()) {
// Stash multisink's reported drop count that will be reported later with
// any other drop counts.
- committed_entry_drop_count_ += drop_count;
+ drop_count_slow_drain_ += drop_count;
return LogDrainState::kCaughtUp; // There are no more entries.
}
@@ -161,7 +174,7 @@ RpcLogDrain::LogDrainState RpcLogDrain::EncodeOutgoingPacket(
// Add the drop count from the multisink peek, stored in `drop_count`, to
// the total drop count. Then drop the entry without counting it towards
// the total drop count. Drops will be reported later all together.
- committed_entry_drop_count_ += drop_count;
+ drop_count_slow_drain_ += drop_count;
PW_CHECK_OK(PopEntry(possible_entry.value()));
continue;
}
@@ -171,31 +184,57 @@ RpcLogDrain::LogDrainState RpcLogDrain::EncodeOutgoingPacket(
possible_entry.value().entry().size() + kLogEntriesEncodeFrameSize;
if (encoded_entry_size + kLogEntriesEncodeFrameSize > total_buffer_size) {
// Entry is larger than the entire available buffer.
- ++committed_entry_drop_count_;
+ ++drop_count_small_outbound_buffer_;
PW_CHECK_OK(PopEntry(possible_entry.value()));
continue;
}
// At this point, we have a valid entry that may fit in the encode buffer.
- // Report any drop counts combined.
- if (committed_entry_drop_count_ > 0 || drop_count > 0) {
- // Reuse the log_entry_buffer_ to send a drop message.
- const Result<ConstByteSpan> drop_message_result =
- CreateEncodedDropMessage(committed_entry_drop_count_ + drop_count,
- log_entry_buffer_);
- // Add encoded drop messsage if fits in buffer.
- if (drop_message_result.ok() &&
- drop_message_result.value().size() + kLogEntriesEncodeFrameSize <
- encoder.ConservativeWriteLimit()) {
- PW_CHECK_OK(encoder.WriteBytes(
- static_cast<uint32_t>(log::LogEntries::Fields::ENTRIES),
- drop_message_result.value()));
- committed_entry_drop_count_ = 0;
- }
- if (possible_entry.ok()) {
- PW_CHECK_OK(PeekEntry(log_entry_buffer_, drop_count, ingress_drop_count)
- .status());
- }
+ // Report any drop counts combined reusing the log_entry_buffer_ to encode a
+ // drop message.
+ drop_count_slow_drain_ += drop_count;
+ // Account for dropped entries too large for stack buffer, which PeekEntry()
+ // also reports.
+ drop_count_slow_drain_ -= drop_count_small_stack_buffer_;
+ bool log_entry_buffer_has_valid_entry = possible_entry.ok();
+ if (drop_count_slow_drain_ > 0) {
+ TryEncodeDropMessage(log_entry_buffer_,
+ std::string_view(kSlowDrainErrorMessage),
+ drop_count_slow_drain_,
+ encoder);
+ log_entry_buffer_has_valid_entry = false;
+ }
+ if (drop_count_ingress_error_ > 0) {
+ TryEncodeDropMessage(log_entry_buffer_,
+ std::string_view(kIngressErrorMessage),
+ drop_count_ingress_error_,
+ encoder);
+ log_entry_buffer_has_valid_entry = false;
+ }
+ if (drop_count_small_stack_buffer_ > 0) {
+ TryEncodeDropMessage(log_entry_buffer_,
+ std::string_view(kSmallStackBufferErrorMessage),
+ drop_count_small_stack_buffer_,
+ encoder);
+ log_entry_buffer_has_valid_entry = false;
+ }
+ if (drop_count_small_outbound_buffer_ > 0) {
+ TryEncodeDropMessage(log_entry_buffer_,
+ std::string_view(kSmallOutboundBufferErrorMessage),
+ drop_count_small_outbound_buffer_,
+ encoder);
+ log_entry_buffer_has_valid_entry = false;
+ }
+ if (drop_count_writer_error_ > 0) {
+ TryEncodeDropMessage(log_entry_buffer_,
+ std::string_view(kWriterErrorMessage),
+ drop_count_writer_error_,
+ encoder);
+ log_entry_buffer_has_valid_entry = false;
+ }
+ if (possible_entry.ok() && !log_entry_buffer_has_valid_entry) {
+ PW_CHECK_OK(PeekEntry(log_entry_buffer_, drop_count, ingress_drop_count)
+ .status());
}
// Check if the entry fits in the partially filled encoder buffer.