| // Copyright 2021 The Pigweed Authors |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| // use this file except in compliance with the License. You may obtain a copy of |
| // the License at |
| // |
| // https://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| // License for the specific language governing permissions and limitations under |
| // the License. |
| |
| #pragma once |
| |
| #include <cstddef> |
| #include <cstring> |
| |
| #include "pw_assert/assert.h" |
| #include "pw_bytes/span.h" |
| #include "pw_containers/vector.h" |
| #include "pw_log/proto/log.pwpb.h" |
| #include "pw_log_rpc/internal/config.h" |
| #include "pw_span/span.h" |
| #include "pw_status/status.h" |
| |
| namespace pw::log_rpc { |
| |
| // A Filter is a collection of rules used to check if a log entry can be kept |
| // or dropped wherever the filter is placed in the log path. |
| class Filter { |
| public: |
| struct Rule { |
| // Action to perform if the rule is met. |
| enum class Action { |
| kInactive = 0, // Ignore this rule. |
| kKeep = 1, |
| kDrop = 2, |
| }; |
| Action action = Action::kInactive; |
| |
| // Checks if the log level is greater or equal to this value when it |
| // does not equal NOT_SET. |
| log::FilterRule::Level level_greater_than_or_equal = |
| log::FilterRule::Level::ANY_LEVEL; |
| |
| // Checks if the log entry has any flag is set when it doesn't equal 0. |
| uint32_t any_flags_set = 0; |
| |
| // Checks if the log entry module equals this value when not empty. |
| Vector<std::byte, cfg::kMaxModuleNameBytes> module_equals{}; |
| |
| // Checks if the log entry thread equals this value when not empty. |
| Vector<std::byte, cfg::kMaxThreadNameBytes> thread_equals{}; |
| }; |
| |
| Filter(span<const std::byte> id, span<Rule> rules) : rules_(rules) { |
| PW_ASSERT(!id.empty()); |
| id_.assign(id.begin(), id.end()); |
| } |
| |
| // Not copyable. |
| Filter(const Filter&) = delete; |
| Filter& operator=(const Filter&) = delete; |
| |
| ConstByteSpan id() const { return ConstByteSpan(id_.data(), id_.size()); } |
| span<const Rule> rules() const { return rules_; } |
| |
| // Verifies a log entry against the filter's rules in the order they were |
| // provided, stopping at the first rule that matches. |
| // Returns true when the log should be dropped, false otherwise. Defaults to |
| // false if there are no rules, or no rules were matched. |
| bool ShouldDropLog(ConstByteSpan entry) const; |
| |
| // Decodes and updates the filter's rules given a buffer with a proto-encoded |
| // log::Filter message. If there are more rules than this filter can hold, the |
| // extra rules are discarded. |
| // |
| // Return values: |
| // OK - rules were updated successfully. |
| // FAILED_PRECONDITION - the provided buffer is empty. |
| // Forwarded errors from protobuff::decoder. |
| Status UpdateRulesFromProto(ConstByteSpan buffer); |
| |
| private: |
| Vector<std::byte, cfg::kMaxFilterIdBytes> id_; |
| span<Rule> rules_; |
| }; |
| |
| } // namespace pw::log_rpc |