blob: d9fc91c23c829ab005c0baf4f2a6747dfc07a846 [file] [log] [blame]
// 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