blob: 9b54ee572a9f61b0be9b2e01d3ca732811a89010 [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/developer/memory/metrics/bucket_match.h"
#include <lib/syslog/cpp/macros.h>
#include <lib/trace/event.h>
#include <filesystem>
#include <optional>
#include <re2/re2.h>
#include "third_party/rapidjson/include/rapidjson/document.h"
#include "third_party/rapidjson/include/rapidjson/ostreamwrapper.h"
#include "third_party/rapidjson/include/rapidjson/rapidjson.h"
#include "third_party/rapidjson/include/rapidjson/writer.h"
namespace memory {
BucketMatch::BucketMatch(const std::string& name, const std::string& process,
const std::string& vmo, std::optional<int64_t> event_code)
: name_(name),
match_all_processes_(process.empty() || process == ".*"),
process_(std::make_shared<re2::RE2>(process)),
match_all_vmos_(vmo.empty() || vmo == ".*"),
vmo_(std::make_shared<re2::RE2>(vmo)),
event_code_(event_code) {}
bool BucketMatch::ProcessMatch(const Process& process) {
if (match_all_processes_) {
return true;
}
const auto& pi = process_match_.find(process.koid);
if (pi != process_match_.end()) {
return pi->second;
}
bool match = re2::RE2::FullMatch(process.name, *process_);
process_match_.emplace(process.koid, match);
return match;
}
bool BucketMatch::VmoMatch(const std::string& vmo) {
if (match_all_vmos_) {
return true;
}
const auto& vi = vmo_match_.find(vmo);
if (vi != vmo_match_.end()) {
return vi->second;
}
bool match = re2::RE2::FullMatch(vmo, *vmo_);
vmo_match_.emplace(vmo, match);
return match;
}
std::optional<std::vector<BucketMatch>> BucketMatch::ReadBucketMatchesFromConfig(
const std::string& config_string) {
std::vector<BucketMatch> result;
rapidjson::Document doc;
doc.Parse(config_string);
if (!doc.IsArray()) {
FX_LOGS(WARNING) << "Configuration is not valid JSON";
return std::nullopt;
}
result.reserve(doc.GetArray().Size());
for (const auto& v : doc.GetArray()) {
if (!(v.HasMember("name") && v["name"].IsString() && v.HasMember("process") &&
v["process"].IsString() && v.HasMember("vmo") && v["vmo"].IsString())) {
FX_LOGS(WARNING) << "Missing member";
return std::nullopt;
}
std::string name(v["name"].GetString(), v["name"].GetStringLength());
std::string process(v["process"].GetString(), v["process"].GetStringLength());
std::string vmo(v["vmo"].GetString(), v["vmo"].GetStringLength());
std::optional<int64_t> event_code;
if (v.HasMember("event_code") && v["event_code"].IsInt64()) {
event_code = v["event_code"].GetInt64();
}
result.emplace_back(name, process, vmo, event_code);
}
return result;
}
} // namespace memory