blob: c3388c75a56825fc3880a55b66e18463c4f369ae [file] [log] [blame] [edit]
/*
* Copyright (C) 2026 The Android Open Source Project
*
* 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
*
* http://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.
*/
#include "src/trace_processor/shell/metatrace.h"
#include <algorithm>
#include <cctype>
#include <cstdint>
#include <cstdlib>
#include <string>
#include <vector>
#include "perfetto/base/logging.h"
#include "perfetto/base/status.h"
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/scoped_file.h"
#include "perfetto/ext/base/status_macros.h"
#include "perfetto/ext/base/string_splitter.h"
#include "perfetto/trace_processor/metatrace_config.h"
#include "perfetto/trace_processor/trace_processor.h"
namespace perfetto::trace_processor {
metatrace::MetatraceCategories ParseMetatraceCategories(std::string s) {
using Cat = metatrace::MetatraceCategories;
std::transform(s.begin(), s.end(), s.begin(),
[](unsigned char c) { return std::tolower(c); });
base::StringSplitter splitter(s, ',');
Cat result = Cat::NONE;
for (; splitter.Next();) {
std::string cur = splitter.cur_token();
if (cur == "all" || cur == "*") {
result = Cat::ALL;
} else if (cur == "query_toplevel") {
result = static_cast<Cat>(result | Cat::QUERY_TIMELINE);
} else if (cur == "query_detailed") {
result = static_cast<Cat>(result | Cat::QUERY_DETAILED);
} else if (cur == "function_call") {
result = static_cast<Cat>(result | Cat::FUNCTION_CALL);
} else if (cur == "db") {
result = static_cast<Cat>(result | Cat::DB);
} else if (cur == "api") {
result = static_cast<Cat>(result | Cat::API_TIMELINE);
} else {
PERFETTO_ELOG("Unknown metatrace category %s", cur.data());
exit(1);
}
}
return result;
}
base::Status MaybeWriteMetatrace(TraceProcessor* trace_processor,
const std::string& metatrace_path) {
if (metatrace_path.empty()) {
return base::OkStatus();
}
std::vector<uint8_t> serialized;
RETURN_IF_ERROR(trace_processor->DisableAndReadMetatrace(&serialized));
auto file = base::OpenFile(metatrace_path, O_CREAT | O_RDWR | O_TRUNC, 0600);
if (!file)
return base::ErrStatus("Unable to open metatrace file");
auto res = base::WriteAll(*file, serialized.data(), serialized.size());
if (res < 0)
return base::ErrStatus("Error while writing metatrace file");
return base::OkStatus();
}
} // namespace perfetto::trace_processor